atommutex.h File Reference

Go to the source code of this file.

Data Structures

struct  atom_mutex

Typedefs

typedef struct atom_mutex ATOM_MUTEX

Functions

uint8_t atomMutexCreate (ATOM_MUTEX *mutex)
uint8_t atomMutexDelete (ATOM_MUTEX *mutex)
uint8_t atomMutexGet (ATOM_MUTEX *mutex, int32_t timeout)
uint8_t atomMutexPut (ATOM_MUTEX *mutex)

Typedef Documentation

typedef struct atom_mutex ATOM_MUTEX

Function Documentation

uint8_t atomMutexCreate ( ATOM_MUTEX mutex  ) 

atomMutexCreate

Initialises a mutex object.

Must be called before calling any other mutex library routines on a mutex. Objects can be deleted later using atomMutexDelete().

Does not set the owner of a mutex. atomMutexGet() must be called after creation in order to actually take ownership.

Does not allocate storage, the caller provides the mutex object.

This function can be called from interrupt context.

Parameters:
[in] mutex Pointer to mutex object
Return values:
ATOM_OK Success
ATOM_ERR_PARAM Bad parameters

References ATOM_ERR_PARAM, ATOM_OK, atom_mutex::count, atom_mutex::owner, atom_mutex::suspQ, and uint8_t.

uint8_t atomMutexDelete ( ATOM_MUTEX mutex  ) 

atomMutexDelete

Deletes a mutex object.

Any threads currently suspended on the mutex will be woken up with return status ATOM_ERR_DELETED. If called at thread context then the scheduler will be called during this function which may schedule in one of the woken threads depending on relative priorities.

This function can be called from interrupt context, but loops internally waking up all threads blocking on the mutex, so the potential execution cycles cannot be determined in advance.

Parameters:
[in] mutex Pointer to mutex object
Return values:
ATOM_OK Success
ATOM_ERR_QUEUE Problem putting a woken thread on the ready queue
ATOM_ERR_TIMER Problem cancelling a timeout on a woken thread

Only call the scheduler if we are in thread context, otherwise it will be called on exiting the ISR by atomIntExit().

References ATOM_ERR_DELETED, ATOM_ERR_PARAM, ATOM_ERR_QUEUE, ATOM_ERR_TIMER, ATOM_OK, atomCurrentContext(), atomSched(), atomTimerCancel(), CRITICAL_END, CRITICAL_START, CRITICAL_STORE, FALSE, atom_tcb::suspend_timo_cb, atom_tcb::suspend_wake_status, atom_mutex::suspQ, tcbDequeueHead(), tcbEnqueuePriority(), tcbReadyQ, TRUE, and uint8_t.

uint8_t atomMutexGet ( ATOM_MUTEX mutex,
int32_t  timeout 
)

atomMutexGet

Take the lock on a mutex.

This takes ownership of a mutex if it is not currently owned. Ownership is held by this thread until a corresponding call to atomMutexPut() by the same thread.

Can be called recursively by the original locking thread (owner). Recursive calls are counted, and ownership is not relinquished until the number of unlock (atomMutexPut()) calls by the owner matches the number of lock (atomMutexGet()) calls.

No thread other than the owner can lock or unlock the mutex while it is locked by another thread.

Depending on the timeout value specified the call will do one of the following if the mutex is already locked by another thread:

timeout == 0 : Call will block until the mutex is available
timeout > 0 : Call will block until available up to the specified timeout
timeout == -1 : Return immediately if mutex is locked by another thread

If the call needs to block and timeout is zero, it will block indefinitely until the owning thread calls atomMutexPut() or atomMutexDelete() is called on the mutex.

If the call needs to block and timeout is non-zero, the call will only block for the specified number of system ticks after which time, if the thread was not already woken, the call will return with ATOM_TIMEOUT.

If the call would normally block and timeout is -1, the call will return immediately with ATOM_WOULDBLOCK.

This function can only be called from thread context. A mutex has the concept of an owner thread, so it is never valid to make a mutex call from interrupt context when there is no thread to associate with.

Parameters:
[in] mutex Pointer to mutex object
[in] timeout Max system ticks to block (0 = forever)
Return values:
ATOM_OK Success
ATOM_TIMEOUT Mutex timed out before being woken
ATOM_WOULDBLOCK Called with timeout == -1 but count is zero
ATOM_ERR_DELETED Mutex was deleted while suspended
ATOM_ERR_CONTEXT Not called in thread context and attempted to block
ATOM_ERR_PARAM Bad parameter
ATOM_ERR_QUEUE Problem putting the thread on the suspend queue
ATOM_ERR_TIMER Problem registering the timeout
ATOM_ERR_OVF The recursive lock count would have overflowed (>255)

Check we are at thread context. Because mutexes have the concept of owner threads, it is never valid to call here from an ISR, regardless of whether we will block.

Store the timer details in the TCB so that we can cancel the timer callback if the mutex is put before the timeout occurs.

Current thread now blocking, schedule in a new one. We already know we are in thread context so can call the scheduler from here.

Normal atomMutexPut() wakeups will set ATOM_OK status, while timeouts will set ATOM_TIMEOUT and mutex deletions will set ATOM_ERR_DELETED.

If we were woken up by another thread relinquishing the mutex and handing this thread ownership, then the relinquishing thread will set status to ATOM_OK and will make this thread the owner. Setting the owner before waking the thread ensures that no other thread can preempt and take ownership of the mutex between this thread being made ready to run, and actually being scheduled back in here.

Since this thread has just gained ownership, the lock count is zero and should be incremented once for this call.

References ATOM_ERR_CONTEXT, ATOM_ERR_OVF, ATOM_ERR_PARAM, ATOM_ERR_QUEUE, ATOM_ERR_TIMER, ATOM_OK, ATOM_WOULDBLOCK, atomCurrentContext(), atomSched(), atomTimerRegister(), atom_timer::cb_data, atom_timer::cb_func, atom_timer::cb_ticks, atom_mutex::count, CRITICAL_END, CRITICAL_START, CRITICAL_STORE, FALSE, mutex_timer::mutex_ptr, atom_mutex::owner, POINTER, atom_tcb::suspend_timo_cb, atom_tcb::suspend_wake_status, atom_tcb::suspended, atom_mutex::suspQ, mutex_timer::tcb_ptr, tcbDequeueEntry(), tcbEnqueuePriority(), TRUE, and uint8_t.

uint8_t atomMutexPut ( ATOM_MUTEX mutex  ) 

atomMutexPut

Give back the lock on a mutex.

This checks that the mutex is owned by the calling thread, and decrements the recursive lock count. Once the lock count reaches zero, the lock is considered relinquished and no longer owned by this thread.

If the lock is relinquished and there are threads blocking on the mutex, the call will wake up the highest priority thread suspended. Only one thread is woken per call to atomMutexPut(). If multiple threads of the same priority are suspended, they are woken in order of suspension (FIFO).

This function can only be called from thread context. A mutex has the concept of an owner thread, so it is never valid to make a mutex call from interrupt context when there is no thread to associate with.

Parameters:
[in] mutex Pointer to mutex object
Return values:
ATOM_OK Success
ATOM_ERR_PARAM Bad parameter
ATOM_ERR_QUEUE Problem putting a woken thread on the ready queue
ATOM_ERR_TIMER Problem cancelling a timeout for a woken thread
ATOM_ERR_OWNERSHIP Attempt to unlock mutex not owned by this thread

Threads are woken up in priority order, with a FIFO system used on same priority threads. We always take the head, ordering is taken care of by an ordered list enqueue.

The scheduler may now make a policy decision to thread switch. We already know we are in thread context so can call the scheduler from here.

Relinquished ownership and no threads waiting. Nothing to do.

Decremented lock but still retain ownership due to recursion. Nothing to do.

References ATOM_ERR_OWNERSHIP, ATOM_ERR_PARAM, ATOM_ERR_QUEUE, ATOM_ERR_TIMER, ATOM_OK, atomCurrentContext(), atomSched(), atomTimerCancel(), atom_mutex::count, CRITICAL_END, CRITICAL_START, CRITICAL_STORE, FALSE, atom_mutex::owner, atom_tcb::suspend_timo_cb, atom_tcb::suspend_wake_status, atom_mutex::suspQ, tcbDequeueHead(), tcbEnqueuePriority(), tcbReadyQ, and uint8_t.


Generated on Fri Jun 4 01:00:01 2010 for atomthreads by  doxygen 1.6.1