Merge pull request #962 from authmillenon/issue-953
core: doc: documentation improvement lifo.h lpm.h msg.h mutex.h
This commit is contained in:
commit
0f4343b5f7
@ -10,54 +10,57 @@
|
|||||||
* @addtogroup core_util
|
* @addtogroup core_util
|
||||||
* @{
|
* @{
|
||||||
*
|
*
|
||||||
* @file lifo.h
|
* @file lifo.h
|
||||||
* @brief LIFO buffer API, read long description carefully
|
* @brief LIFO buffer API, read long description carefully
|
||||||
* @author probably Kaspar Schleiser
|
* @author Heiko Will <hwill@inf.fu-berlin.de>
|
||||||
*
|
*
|
||||||
* @long This LIFO implementation very efficiently handles
|
* @detail This LIFO implementation very efficiently handles integer values.
|
||||||
* integer values. The caveat is that it can only handle
|
* The caveat is that it **can only handle values between 0 and its own
|
||||||
* values between 0 and its own size -1. Also it can only
|
* size - 1**. Also it can only handle up to one element of each value.
|
||||||
* handle up to one element of each value. If you insert
|
* If you insert a value twice the LIFO will break.
|
||||||
* a value twice the LIFO will break.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __LIFO_H
|
#ifndef __LIFO_H_
|
||||||
#define __LIFO_H
|
#define __LIFO_H_
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief: check if the given lifo is empty
|
* @brief Check if the given lifo is empty.
|
||||||
* @return: true if empty, false otherwise
|
*
|
||||||
|
* @param[in] array The lifo array to check.
|
||||||
|
*
|
||||||
|
* @return 1, if empty
|
||||||
|
* @return 0, otherwise.
|
||||||
*/
|
*/
|
||||||
int lifo_empty(int *array);
|
int lifo_empty(int *array);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief: initialize a lifo array
|
* @brief Initialize a lifo array.
|
||||||
*
|
*
|
||||||
* @param array: an array of int of size n+1
|
* @param[in,out] array An array of size *n* + 1, may not be NULL.
|
||||||
* @param n: maximum integer value the lifo is able to store
|
* @param[in] n Maximum integer value the lifo is able to store.
|
||||||
*/
|
*/
|
||||||
void lifo_init(int *array, int n);
|
void lifo_init(int *array, int n);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief: insert an element into the lifo
|
* @brief Insert an element into the lifo
|
||||||
*
|
*
|
||||||
* @param array: an integer array of least i+1 size that does not
|
* @param[in,out] array An integer array of least *i* + 1 size that **does not
|
||||||
* already contain i
|
* already contain *i***, may not be NULL.
|
||||||
* @param i: the integer value to store, between 0 and the size
|
* @param[in] i The integer value to store, between 0 and the size of
|
||||||
* of the array -1, must not be stored already
|
* the array - 1, must not be stored already.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void lifo_insert(int *array, int i);
|
void lifo_insert(int *array, int i);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief: extract the least recently inserted element from the lifo
|
* @brief Extract the least recently inserted element from the lifo.
|
||||||
*
|
*
|
||||||
* @param array: an integer array
|
* @param[in] array An integer array, may not be NULL.
|
||||||
*
|
*
|
||||||
* @return: -1 if the lifo is empty, the least recently
|
* @return -1, if the lifo is empty.
|
||||||
* inserted element otherwise
|
* @return the least recently inserted element, otherwise.
|
||||||
*/
|
*/
|
||||||
int lifo_get(int *array);
|
int lifo_get(int *array);
|
||||||
|
|
||||||
|
#endif /* __LIFO_H_ */
|
||||||
/** @} */
|
/** @} */
|
||||||
#endif /* __LIFO_H */
|
|
||||||
|
|||||||
@ -39,9 +39,19 @@ void lpm_init(void);
|
|||||||
*/
|
*/
|
||||||
enum lpm_mode lpm_set(enum lpm_mode target);
|
enum lpm_mode lpm_set(enum lpm_mode target);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Switches the MCU to active power mode LPM_ON
|
||||||
|
*/
|
||||||
void lpm_awake(void);
|
void lpm_awake(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Begin to switch MCU to active power mode.
|
||||||
|
*/
|
||||||
void lpm_begin_awake(void);
|
void lpm_begin_awake(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Finish to switch MCU to active power mode.
|
||||||
|
*/
|
||||||
void lpm_end_awake(void);
|
void lpm_end_awake(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -50,5 +60,5 @@ void lpm_end_awake(void);
|
|||||||
*/
|
*/
|
||||||
enum lpm_mode lpm_get(void);
|
enum lpm_mode lpm_get(void);
|
||||||
|
|
||||||
#endif /* LPM_H_ */
|
#endif /* __LPM_H_ */
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|||||||
@ -11,13 +11,14 @@
|
|||||||
* @ingroup core
|
* @ingroup core
|
||||||
* @brief Messaging API for inter process communication
|
* @brief Messaging API for inter process communication
|
||||||
*
|
*
|
||||||
* There are two ways to use the IPC Messaging system of RIOT. The default is synchronous
|
* There are two ways to use the IPC Messaging system of RIOT. The default is
|
||||||
* messaging. In this manner, messages are either dropped when the receiver is not waiting and the
|
* synchronous messaging. In this manner, messages are either dropped when the
|
||||||
* message was sent non-blocking, or will be delivered immediately when the receiver calls
|
* receiver is not waiting and the message was sent non-blocking, or will be
|
||||||
* msg_receive(msg_t* m). To use asynchronous messaging any thread can create its own queue by
|
* delivered immediately when the receiver calls msg_receive(msg_t* m). To use
|
||||||
* calling msg_init_queue(msg_t* array, int num). Messages sent to a thread with a non full message
|
* asynchronous messaging any thread can create its own queue by calling
|
||||||
* queue are never dropped and the sending never blocks. Threads with a full message queue behaves
|
* msg_init_queue(msg_t* array, int num). Messages sent to a thread with a non
|
||||||
* like in synchronous mode.
|
* full message queue are never dropped * and the sending never blocks. Threads
|
||||||
|
* with a full message queue behaves like in synchronous mode.
|
||||||
*
|
*
|
||||||
* @{
|
* @{
|
||||||
*
|
*
|
||||||
@ -29,16 +30,12 @@
|
|||||||
* @author Kévin Roussel <Kevin.Roussel@inria.fr>
|
* @author Kévin Roussel <Kevin.Roussel@inria.fr>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __MSG_H
|
#ifndef __MSG_H_
|
||||||
#define __MSG_H
|
#define __MSG_H_
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#define MESSAGE_SENT 1
|
|
||||||
#define MESSAGE_PROCESS_NOT_WAITING 0
|
|
||||||
#define MESSAGE_PROCESS_UNKNOWN 2
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Describes a message object which can be sent between threads.
|
* @brief Describes a message object which can be sent between threads.
|
||||||
*
|
*
|
||||||
@ -48,31 +45,35 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
typedef struct msg {
|
typedef struct msg {
|
||||||
uint16_t sender_pid; ///< PID of sending thread. Will be filled in by msg_send
|
uint16_t sender_pid; /**< PID of sending thread. Will be filled in
|
||||||
uint16_t type; ///< Type field.
|
by msg_send. */
|
||||||
|
uint16_t type; /**< Type field. */
|
||||||
union {
|
union {
|
||||||
char *ptr; ///< pointer content field
|
char *ptr; /**< Pointer content field. */
|
||||||
uint32_t value; ///< value content field
|
uint32_t value; /**< Value content field. */
|
||||||
} content;
|
} content; /**< Content of the message. */
|
||||||
} msg_t;
|
} msg_t;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Send a message.
|
* @brief Send a message.
|
||||||
*
|
*
|
||||||
* This function sends a message to another thread.
|
* This function sends a message to another thread. The ``msg_t`` structure has
|
||||||
* The msg structure has to be allocated (e.g. on the stack)
|
* to be allocated (e.g. on the stack) before calling the function and can be
|
||||||
* before calling the function and can be freed afterwards.
|
* freed afterwards. If called from an interrupt, this function will never
|
||||||
* If called from an interrupt, this function will never block.
|
* block.
|
||||||
*
|
*
|
||||||
* @param m Pointer to message structure
|
* @param[in] m Pointer to preallocated ``msg_t`` structure, must
|
||||||
* @param target_pid PID of target thread
|
* not be NULL.
|
||||||
* @param block If true and receiver is not receive-blocked, function will block. If not, function
|
* @param[in] target_pid PID of target thread
|
||||||
* returns.
|
* @param[in] block If not 0 and receiver is not receive-blocked,
|
||||||
|
* function will block. If not, function returns.
|
||||||
*
|
*
|
||||||
* @return 1 if sending was successful (message delivered directly or to a queue)
|
* @return 1, if sending was successful (message delivered directly or to a
|
||||||
* @return 0 if receiver is not waiting or has a full message queue and block == false
|
* queue)
|
||||||
* @return -1 on error (invalid PID)
|
* @return 0, if receiver is not waiting or has a full message queue and
|
||||||
|
* ``block == 0``
|
||||||
|
* @return -1, on error (invalid PID)
|
||||||
*/
|
*/
|
||||||
int msg_send(msg_t *m, unsigned int target_pid, bool block);
|
int msg_send(msg_t *m, unsigned int target_pid, bool block);
|
||||||
|
|
||||||
@ -95,13 +96,15 @@ int msg_send_to_self(msg_t *m);
|
|||||||
/**
|
/**
|
||||||
* @brief Send message from interrupt.
|
* @brief Send message from interrupt.
|
||||||
*
|
*
|
||||||
* Will be automatically chosen instead of msg_send if inISR() == true
|
* Will be automatically chosen instead of ``msg_sennd()`` if called from an
|
||||||
|
* interrupt/ISR.
|
||||||
*
|
*
|
||||||
* @param m pointer to message structure
|
* @param[in] m Pointer to preallocated ``msg_t`` structure, must
|
||||||
* @param target_pid PID of target thread
|
* not be NULL.
|
||||||
|
* @param[in] target_pid PID of target thread.
|
||||||
*
|
*
|
||||||
* @return 1 if sending was successful
|
* @return 1, if sending was successful
|
||||||
* @return 0 if receiver is not waiting and block == false
|
* @return 0, if receiver is not waiting and ``block == 0``
|
||||||
*/
|
*/
|
||||||
int msg_send_int(msg_t *m, unsigned int target_pid);
|
int msg_send_int(msg_t *m, unsigned int target_pid);
|
||||||
|
|
||||||
@ -110,9 +113,11 @@ int msg_send_int(msg_t *m, unsigned int target_pid);
|
|||||||
* @brief Receive a message.
|
* @brief Receive a message.
|
||||||
*
|
*
|
||||||
* This function blocks until a message was received.
|
* This function blocks until a message was received.
|
||||||
* @param m pointer to preallocated msg
|
|
||||||
*
|
*
|
||||||
* @return 1 Function always succeeds or blocks forever.
|
* @param[out] m Pointer to preallocated ``msg_t`` structure, must not be
|
||||||
|
* NULL.
|
||||||
|
*
|
||||||
|
* @return 1, Function always succeeds or blocks forever.
|
||||||
*/
|
*/
|
||||||
int msg_receive(msg_t *m);
|
int msg_receive(msg_t *m);
|
||||||
|
|
||||||
@ -120,21 +125,30 @@ int msg_receive(msg_t *m);
|
|||||||
* @brief Try to receive a message.
|
* @brief Try to receive a message.
|
||||||
*
|
*
|
||||||
* This function does not block if no message can be received.
|
* This function does not block if no message can be received.
|
||||||
* @param m pointer to preallocated msg
|
|
||||||
*
|
*
|
||||||
* @return 1 if a message was received, -1 otherwise.
|
* @param[out] m Pointer to preallocated ``msg_t`` structure, must not be
|
||||||
|
* NULL.
|
||||||
|
*
|
||||||
|
* @return 1, if a message was received
|
||||||
|
* @return -1, otherwise.
|
||||||
*/
|
*/
|
||||||
int msg_try_receive(msg_t *m);
|
int msg_try_receive(msg_t *m);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Send a message, block until reply received.
|
* @brief Send a message, block until reply received.
|
||||||
*
|
*
|
||||||
* This function sends a message to target_pid and then blocks until target has sent a reply.
|
* This function sends a message to *target_pid* and then blocks until target
|
||||||
* @note CAUTION!Use this function only when receiver is already waiting. If not use simple msg_send()
|
* has sent a reply which is then stored in *reply*.
|
||||||
* @param m pointer to preallocated msg
|
*
|
||||||
* @param reply pointer to preallocated msg. Reply will be written here.
|
* @note CAUTION! Use this function only when receiver is already waiting.
|
||||||
* @param target pid the pid of the target process
|
* If not use simple msg_send()
|
||||||
* @return 1 if successful
|
* @param[in] m Pointer to preallocated ``msg_t`` structure with
|
||||||
|
* the message to send, must not be NULL.
|
||||||
|
* @param[out] reply Pointer to preallocated msg. Reply will be written
|
||||||
|
* here, must not be NULL.
|
||||||
|
* @param[in] target_pid The PID of the target process
|
||||||
|
*
|
||||||
|
* @return 1, if successful.
|
||||||
*/
|
*/
|
||||||
int msg_send_receive(msg_t *m, msg_t *reply, unsigned int target_pid);
|
int msg_send_receive(msg_t *m, msg_t *reply, unsigned int target_pid);
|
||||||
|
|
||||||
@ -143,24 +157,27 @@ int msg_send_receive(msg_t *m, msg_t *reply, unsigned int target_pid);
|
|||||||
*
|
*
|
||||||
* Sender must have sent the message with msg_send_receive().
|
* Sender must have sent the message with msg_send_receive().
|
||||||
*
|
*
|
||||||
* @param m msg to reply to.
|
* @param[in] m message to reply to, must not be NULL.
|
||||||
* @param reply message that target will get as reply
|
* @param[out] reply message that target will get as reply, must not be
|
||||||
|
* NULL.
|
||||||
*
|
*
|
||||||
* @return 1 if successful
|
* @return 1, if successful
|
||||||
* @return 0 on error
|
* @return 0, on error
|
||||||
*/
|
*/
|
||||||
int msg_reply(msg_t *m, msg_t *reply);
|
int msg_reply(msg_t *m, msg_t *reply);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initialize the current thread's message queue.
|
* @brief Initialize the current thread's message queue.
|
||||||
*
|
*
|
||||||
* @param array Pointer to preallocated array of msg objects
|
* @param[in] array Pointer to preallocated array of ``msg_t`` structures, must
|
||||||
* @param num Number of msg objects in array. MUST BE POWER OF TWO!
|
* not be NULL.
|
||||||
|
* @param[in] num Number of ``msg_t`` structurs in array.
|
||||||
|
* **MUST BE POWER OF TWO!**
|
||||||
*
|
*
|
||||||
* @return 0 if successful
|
* @return 0, if successful
|
||||||
* @return -1 on error
|
* @return -1, on error
|
||||||
*/
|
*/
|
||||||
int msg_init_queue(msg_t *array, int num);
|
int msg_init_queue(msg_t *array, int num);
|
||||||
|
|
||||||
|
#endif /* __MSG_H_ */
|
||||||
/** @} */
|
/** @} */
|
||||||
#endif /* __MSG_H */
|
|
||||||
|
|||||||
@ -19,24 +19,36 @@
|
|||||||
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _MUTEX_H
|
#ifndef __MUTEX_H_
|
||||||
#define _MUTEX_H
|
#define __MUTEX_H_
|
||||||
|
|
||||||
#include "queue.h"
|
#include "queue.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Mutex structure. Should never be modified by the user.
|
* @brief Mutex structure. Must never be modified by the user.
|
||||||
*/
|
*/
|
||||||
typedef struct mutex_t {
|
typedef struct mutex_t {
|
||||||
/* fields are managed by mutex functions, don't touch */
|
/* fields are managed by mutex functions, don't touch */
|
||||||
unsigned int val; // @internal
|
/**
|
||||||
queue_node_t queue; // @internal
|
* @internal
|
||||||
|
* @brief The value of the mutex; 0 if unlocked, 1 if locked. **Must
|
||||||
|
* never be changed by the user.**
|
||||||
|
*/
|
||||||
|
unsigned int val;
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
* @brief The process waiting queue of the mutex. **Must never be changed
|
||||||
|
* by the user.**
|
||||||
|
*/
|
||||||
|
queue_node_t queue;
|
||||||
} mutex_t;
|
} mutex_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initializes a mutex object
|
* @brief Initializes a mutex object.
|
||||||
* @param mutex pre-allocated mutex structure.
|
*
|
||||||
* @return Always returns 1, always succeeds.
|
* @param[out] mutex pre-allocated mutex structure, must not be NULL.
|
||||||
|
*
|
||||||
|
* @return Always returns 1, always succeeds.
|
||||||
*/
|
*/
|
||||||
int mutex_init(struct mutex_t *mutex);
|
int mutex_init(struct mutex_t *mutex);
|
||||||
|
|
||||||
@ -44,7 +56,8 @@ int mutex_init(struct mutex_t *mutex);
|
|||||||
/**
|
/**
|
||||||
* @brief Tries to get a mutex, non-blocking.
|
* @brief Tries to get a mutex, non-blocking.
|
||||||
*
|
*
|
||||||
* @param mutex Mutex-Object to lock. Has to be initialized first.
|
* @param[in] mutex Mutex object to lock. Has to be initialized first. Must not
|
||||||
|
* be NULL.
|
||||||
*
|
*
|
||||||
* @return 1 if mutex was unlocked, now it is locked.
|
* @return 1 if mutex was unlocked, now it is locked.
|
||||||
* @return 0 if the mutex was locked.
|
* @return 0 if the mutex was locked.
|
||||||
@ -54,7 +67,8 @@ int mutex_trylock(struct mutex_t *mutex);
|
|||||||
/**
|
/**
|
||||||
* @brief Tries to get a mutex, blocking.
|
* @brief Tries to get a mutex, blocking.
|
||||||
*
|
*
|
||||||
* @param mutex Mutex-Object to lock. Has to be initialized first.
|
* @param[in] mutex Mutex object to lock. Has to be initialized first. Must not
|
||||||
|
* be NULL.
|
||||||
*
|
*
|
||||||
* @return 1 getting the mutex was successful
|
* @return 1 getting the mutex was successful
|
||||||
* @return <1 there was an error.
|
* @return <1 there was an error.
|
||||||
@ -64,28 +78,16 @@ int mutex_lock(struct mutex_t *mutex);
|
|||||||
/**
|
/**
|
||||||
* @brief Unlocks the mutex.
|
* @brief Unlocks the mutex.
|
||||||
*
|
*
|
||||||
* @param mutex Mutex-Object to unlock.
|
* @param[in] mutex Mutex object to unlock, must not be NULL.
|
||||||
*/
|
*/
|
||||||
void mutex_unlock(struct mutex_t *mutex);
|
void mutex_unlock(struct mutex_t *mutex);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Unlocks the mutex and sends the current thread to sleep
|
* @brief Unlocks the mutex and sends the current thread to sleep
|
||||||
*
|
*
|
||||||
* @param mutex Mutex-Object to unlock.
|
* @param[in] mutex Mutex object to unlock, must not be NULL.
|
||||||
*/
|
*/
|
||||||
void mutex_unlock_and_sleep(struct mutex_t *mutex);
|
void mutex_unlock_and_sleep(struct mutex_t *mutex);
|
||||||
|
|
||||||
#define MUTEX_YIELD 1
|
#endif /* __MUTEX_H_ */
|
||||||
#define MUTEX_INISR 2
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* internal functions *
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
void mutex_wake_waiters(struct mutex_t *mutex, int yield);
|
|
||||||
void mutex_wait(struct mutex_t *mutex);
|
|
||||||
|
|
||||||
/*struct mutex_entry_t * mutex_create_entry(int prio, struct tcb *proc);*/
|
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
#endif /* _MUTEX_H */
|
|
||||||
|
|||||||
13
core/mutex.c
13
core/mutex.c
@ -33,6 +33,8 @@
|
|||||||
#define ENABLE_DEBUG (0)
|
#define ENABLE_DEBUG (0)
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
|
static void mutex_wait(struct mutex_t *mutex);
|
||||||
|
|
||||||
int mutex_init(struct mutex_t *mutex)
|
int mutex_init(struct mutex_t *mutex)
|
||||||
{
|
{
|
||||||
mutex->val = 0;
|
mutex->val = 0;
|
||||||
@ -62,7 +64,7 @@ int mutex_lock(struct mutex_t *mutex)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mutex_wait(struct mutex_t *mutex)
|
static void mutex_wait(struct mutex_t *mutex)
|
||||||
{
|
{
|
||||||
int irqstate = disableIRQ();
|
int irqstate = disableIRQ();
|
||||||
DEBUG("%s: Mutex in use. %u\n", active_thread->name, mutex->val);
|
DEBUG("%s: Mutex in use. %u\n", active_thread->name, mutex->val);
|
||||||
@ -75,7 +77,7 @@ void mutex_wait(struct mutex_t *mutex)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sched_set_status((tcb_t*) active_thread, STATUS_MUTEX_BLOCKED);
|
sched_set_status((tcb_t *) active_thread, STATUS_MUTEX_BLOCKED);
|
||||||
|
|
||||||
queue_node_t n;
|
queue_node_t n;
|
||||||
n.priority = (unsigned int) active_thread->priority;
|
n.priority = (unsigned int) active_thread->priority;
|
||||||
@ -101,7 +103,7 @@ void mutex_unlock(struct mutex_t *mutex)
|
|||||||
if (mutex->val != 0) {
|
if (mutex->val != 0) {
|
||||||
if (mutex->queue.next) {
|
if (mutex->queue.next) {
|
||||||
queue_node_t *next = queue_remove_head(&(mutex->queue));
|
queue_node_t *next = queue_remove_head(&(mutex->queue));
|
||||||
tcb_t *process = (tcb_t*) next->data;
|
tcb_t *process = (tcb_t *) next->data;
|
||||||
DEBUG("%s: waking up waiter.\n", process->name);
|
DEBUG("%s: waking up waiter.\n", process->name);
|
||||||
sched_set_status(process, STATUS_PENDING);
|
sched_set_status(process, STATUS_PENDING);
|
||||||
|
|
||||||
@ -123,7 +125,7 @@ void mutex_unlock_and_sleep(struct mutex_t *mutex)
|
|||||||
if (mutex->val != 0) {
|
if (mutex->val != 0) {
|
||||||
if (mutex->queue.next) {
|
if (mutex->queue.next) {
|
||||||
queue_node_t *next = queue_remove_head(&(mutex->queue));
|
queue_node_t *next = queue_remove_head(&(mutex->queue));
|
||||||
tcb_t *process = (tcb_t*) next->data;
|
tcb_t *process = (tcb_t *) next->data;
|
||||||
DEBUG("%s: waking up waiter.\n", process->name);
|
DEBUG("%s: waking up waiter.\n", process->name);
|
||||||
sched_set_status(process, STATUS_PENDING);
|
sched_set_status(process, STATUS_PENDING);
|
||||||
}
|
}
|
||||||
@ -131,8 +133,9 @@ void mutex_unlock_and_sleep(struct mutex_t *mutex)
|
|||||||
mutex->val = 0;
|
mutex->val = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG("%s: going to sleep.\n", active_thread->name);
|
DEBUG("%s: going to sleep.\n", active_thread->name);
|
||||||
sched_set_status((tcb_t*) active_thread, STATUS_SLEEPING);
|
sched_set_status((tcb_t *) active_thread, STATUS_SLEEPING);
|
||||||
restoreIRQ(irqstate);
|
restoreIRQ(irqstate);
|
||||||
thread_yield();
|
thread_yield();
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user