Synchronisation Services
[Driver Development API]

Collaboration diagram for Synchronisation Services:


Spinlock with Preemption Deactivation

typedef rthal_spinlock_t rtdm_lock_t
 Lock variable.
typedef unsigned long rtdm_lockctx_t
 Variable to save the context while holding a lock.
#define RTDM_LOCK_UNLOCKED   RTHAL_SPIN_LOCK_UNLOCKED
 Static lock initialisation.
#define rtdm_lock_init(lock)   rthal_spin_lock_init(lock)
 Dynamic lock initialisation.
#define rtdm_lock_get(lock)   rthal_spin_lock(lock)
 Acquire lock from non-preemptible contexts.
#define rtdm_lock_put(lock)   rthal_spin_unlock(lock)
 Release lock without preemption restoration.
#define rtdm_lock_get_irqsave(lock, context)   rthal_spin_lock_irqsave(lock, context)
 Acquire lock and disable preemption.
#define rtdm_lock_put_irqrestore(lock, context)   rthal_spin_unlock_irqrestore(lock, context)
 Release lock and restore preemption state.
#define rtdm_lock_irqsave(context)   rthal_local_irq_save(context)
 Disable preemption locally.
#define rtdm_lock_irqrestore(context)   rthal_local_irq_restore(context)
 Restore preemption state.

Timeout Sequence Management

void rtdm_toseq_init (rtdm_toseq_t *timeout_seq, nanosecs_rel_t timeout)

Event Services

void rtdm_event_init (rtdm_event_t *event, unsigned long pending)
void rtdm_event_destroy (rtdm_event_t *event)
void rtdm_event_pulse (rtdm_event_t *event)
void rtdm_event_signal (rtdm_event_t *event)
int rtdm_event_wait (rtdm_event_t *event)
int rtdm_event_timedwait (rtdm_event_t *event, nanosecs_rel_t timeout, rtdm_toseq_t *timeout_seq)
void rtdm_event_clear (rtdm_event_t *event)

Semaphore Services

void rtdm_sem_init (rtdm_sem_t *sem, unsigned long value)
void rtdm_sem_destroy (rtdm_sem_t *sem)
int rtdm_sem_down (rtdm_sem_t *sem)
int rtdm_sem_timeddown (rtdm_sem_t *sem, nanosecs_rel_t timeout, rtdm_toseq_t *timeout_seq)
void rtdm_sem_up (rtdm_sem_t *sem)

Mutex Services

void rtdm_mutex_init (rtdm_mutex_t *mutex)
void rtdm_mutex_destroy (rtdm_mutex_t *mutex)
void rtdm_mutex_unlock (rtdm_mutex_t *mutex)
int rtdm_mutex_lock (rtdm_mutex_t *mutex)
int rtdm_mutex_timedlock (rtdm_mutex_t *mutex, nanosecs_rel_t timeout, rtdm_toseq_t *timeout_seq)

Global Lock across Scheduler Invocation

#define RTDM_EXECUTE_ATOMICALLY(code_block)


Define Documentation

#define RTDM_EXECUTE_ATOMICALLY ( code_block   ) 

Value:

{                                               \
        <ENTER_ATOMIC_SECTION>                  \
        code_block;                             \
        <LEAVE_ATOMIC_SECTION>                  \
}
Execute code block atomically Generally, it is illegal to suspend the current task by calling rtdm_task_sleep(), rtdm_event_wait(), etc. while holding a spinlock. In contrast, this macro allows to combine several operations including a potentially rescheduling call to an atomic code block with respect to other RTDM_EXECUTE_ATOMICALLY() blocks. The macro is a light-weight alternative for protecting code blocks via mutexes, and it can even be used to synchronise real-time and non-real-time contexts.

Parameters:
code_block Commands to be executed atomically
Note:
It is not allowed to leave the code block explicitly by using break, return, goto, etc. This would leave the global lock held during the code block execution in an inconsistent state. Moreover, do not embed complex operations into the code bock. Consider that they will be executed under preemption lock with interrupts switched-off. Also note that invocation of rescheduling calls may break the atomicity until the task gains the CPU again.
Environments:

This service can be called from:

Rescheduling: possible, depends on functions called within code_block.

#define rtdm_lock_get ( lock   )     rthal_spin_lock(lock)

Acquire lock from non-preemptible contexts.

Parameters:
lock Address of lock variable
Environments:

This service can be called from:

Rescheduling: never.

#define rtdm_lock_get_irqsave ( lock,
context   )     rthal_spin_lock_irqsave(lock, context)

Acquire lock and disable preemption.

Parameters:
lock Address of lock variable
context name of local variable to store the context in
Environments:

This service can be called from:

Rescheduling: never.

#define rtdm_lock_init ( lock   )     rthal_spin_lock_init(lock)

Dynamic lock initialisation.

Parameters:
lock Address of lock variable
Environments:

This service can be called from:

Rescheduling: never.

#define rtdm_lock_irqrestore ( context   )     rthal_local_irq_restore(context)

Restore preemption state.

Parameters:
context name of local variable which stored the context
Environments:

This service can be called from:

Rescheduling: possible.

#define rtdm_lock_irqsave ( context   )     rthal_local_irq_save(context)

Disable preemption locally.

Parameters:
context name of local variable to store the context in
Environments:

This service can be called from:

Rescheduling: never.

#define rtdm_lock_put ( lock   )     rthal_spin_unlock(lock)

Release lock without preemption restoration.

Parameters:
lock Address of lock variable
Environments:

This service can be called from:

Rescheduling: never.

#define rtdm_lock_put_irqrestore ( lock,
context   )     rthal_spin_unlock_irqrestore(lock, context)

Release lock and restore preemption state.

Parameters:
lock Address of lock variable
context name of local variable which stored the context
Environments:

This service can be called from:

Rescheduling: possible.


Function Documentation

void rtdm_event_clear ( rtdm_event_t *  event  ) 

Clear event state

Parameters:
[in,out] event Event handle as returned by rtdm_event_init() Environments: This service can be called from: - Kernel module initialization/cleanup code
  • Interrupt service routine
  • Kernel-based task
  • User-space task (RT, non-RT) Rescheduling: never.

void rtdm_event_destroy ( rtdm_event_t *  event  ) 

Destroy an event

Parameters:
[in,out] event Event handle as returned by rtdm_event_init() Environments: This service can be called from: - Kernel module initialization/cleanup code
  • Kernel-based task
  • User-space task (RT, non-RT) Rescheduling: possible.

void rtdm_event_init ( rtdm_event_t *  event,
unsigned long  pending 
)

Initialise an event

Parameters:
[in,out] event Event handle
[in] pending Non-zero if event shall be initialised as set, 0 otherwise Environments: This service can be called from: - Kernel module initialization/cleanup code
  • Kernel-based task
  • User-space task (RT, non-RT) Rescheduling: never.

void rtdm_event_pulse ( rtdm_event_t *  event  ) 

Signal an event occurrence to currently listening waiters This function wakes up all current waiters of the given event, but it does not change the event state. Subsequently callers of rtdm_event_wait() or rtdm_event_timedwait() will therefore be blocked first.

Parameters:
[in,out] event Event handle as returned by rtdm_event_init()
Environments:

This service can be called from:

Rescheduling: possible.

void rtdm_event_signal ( rtdm_event_t *  event  ) 

Signal an event occurrence This function sets the given event and wakes up all current waiters. If no waiter is presently registered, the next call to rtdm_event_wait() or rtdm_event_timedwait() will return immediately.

Parameters:
[in,out] event Event handle as returned by rtdm_event_init()
Environments:

This service can be called from:

Rescheduling: possible.

int rtdm_event_timedwait ( rtdm_event_t *  event,
nanosecs_rel_t  timeout,
rtdm_toseq_t *  timeout_seq 
)

Wait on event occurrence with timeout This function waits or tests for the occurence of the given event, taking the provided timeout into account. On successful return, the event is reset.

Parameters:
[in,out] event Event handle as returned by rtdm_event_init()
[in] timeout Relative timeout in nanoseconds, see RTDM_TIMEOUT_xxx for special values
[in,out] timeout_seq Handle of a timeout sequence as returned by rtdm_toseq_init() or NULL
Returns:
0 on success, otherwise:

Environments:

This service can be called from:

Rescheduling: possible.

int rtdm_event_wait ( rtdm_event_t *  event  ) 

Wait on event occurrence This is the light-weight version of rtdm_event_timedwait(), implying an infinite timeout.

Parameters:
[in,out] event Event handle as returned by rtdm_event_init()
Returns:
0 on success, otherwise:

Environments:

This service can be called from:

Rescheduling: possible.

void rtdm_mutex_destroy ( rtdm_mutex_t *  mutex  ) 

Destroy a mutex

Parameters:
[in,out] mutex Mutex handle as returned by rtdm_mutex_init() Environments: This service can be called from: - Kernel module initialization/cleanup code
  • Kernel-based task
  • User-space task (RT, non-RT) Rescheduling: possible.

void rtdm_mutex_init ( rtdm_mutex_t *  mutex  ) 

Initialise a mutex This function initalises a basic mutex with priority inversion protection. "Basic", as it does not allow a mutex owner to recursively lock the same mutex again.

Parameters:
[in,out] mutex Mutex handle
Environments:

This service can be called from:

Rescheduling: never.

int rtdm_mutex_lock ( rtdm_mutex_t *  mutex  ) 

Request a mutex This is the light-weight version of rtdm_mutex_timedlock(), implying an infinite timeout.

Parameters:
[in,out] mutex Mutex handle as returned by rtdm_mutex_init()
Returns:
0 on success, otherwise:

Environments:

This service can be called from:

Rescheduling: possible.

int rtdm_mutex_timedlock ( rtdm_mutex_t *  mutex,
nanosecs_rel_t  timeout,
rtdm_toseq_t *  timeout_seq 
)

Request a mutex with timeout This function tries to acquire the given mutex. If it is not available, the caller is blocked unless non-blocking operation was selected.

Parameters:
[in,out] mutex Mutex handle as returned by rtdm_mutex_init()
[in] timeout Relative timeout in nanoseconds, see RTDM_TIMEOUT_xxx for special values
[in,out] timeout_seq Handle of a timeout sequence as returned by rtdm_toseq_init() or NULL
Returns:
0 on success, otherwise:

Environments:

This service can be called from:

Rescheduling: possible.

void rtdm_mutex_unlock ( rtdm_mutex_t *  mutex  ) 

Release a mutex This function releases the given mutex, waking up a potential waiter which was blocked upon rtdm_mutex_lock() or rtdm_mutex_timedlock().

Parameters:
[in,out] mutex Mutex handle as returned by rtdm_mutex_init()
Environments:

This service can be called from:

Rescheduling: possible.

void rtdm_sem_destroy ( rtdm_sem_t *  sem  ) 

Destroy a semaphore

Parameters:
[in,out] sem Semaphore handle as returned by rtdm_sem_init() Environments: This service can be called from: - Kernel module initialization/cleanup code
  • Kernel-based task
  • User-space task (RT, non-RT) Rescheduling: possible.

int rtdm_sem_down ( rtdm_sem_t *  sem  ) 

Decrement a semaphore This is the light-weight version of rtdm_sem_timeddown(), implying an infinite timeout.

Parameters:
[in,out] sem Semaphore handle as returned by rtdm_sem_init()
Returns:
0 on success, otherwise:

Environments:

This service can be called from:

Rescheduling: possible.

void rtdm_sem_init ( rtdm_sem_t *  sem,
unsigned long  value 
)

Initialise a semaphore

Parameters:
[in,out] sem Semaphore handle
[in] value Initial value of the semaphore Environments: This service can be called from: - Kernel module initialization/cleanup code
  • Kernel-based task
  • User-space task (RT, non-RT) Rescheduling: never.

int rtdm_sem_timeddown ( rtdm_sem_t *  sem,
nanosecs_rel_t  timeout,
rtdm_toseq_t *  timeout_seq 
)

Decrement a semaphore with timeout This function tries to decrement the given semphore's value if it is positive on entry. If not, the caller is blocked unless non-blocking operation was selected.

Parameters:
[in,out] sem Semaphore handle as returned by rtdm_sem_init()
[in] timeout Relative timeout in nanoseconds, see RTDM_TIMEOUT_xxx for special values
[in,out] timeout_seq Handle of a timeout sequence as returned by rtdm_toseq_init() or NULL
Returns:
0 on success, otherwise:

Environments:

This service can be called from:

Rescheduling: possible.

void rtdm_sem_up ( rtdm_sem_t *  sem  ) 

Increment a semaphore This function increments the given semphore's value, waking up a potential waiter which was blocked upon rtdm_sem_down().

Parameters:
[in,out] sem Semaphore handle as returned by rtdm_sem_init()
Environments:

This service can be called from:

Rescheduling: possible.

void rtdm_toseq_init ( rtdm_toseq_t *  timeout_seq,
nanosecs_rel_t  timeout 
)

Initialise a timeout sequence This service initialises a timeout sequence handle according to the given timeout value. Timeout sequences allow to maintain a continuous timeout across multiple calls of blocking synchronisation services. A typical application scenario is given below.

Parameters:
[in,out] timeout_seq Timeout sequence handle
[in] timeout Relative timeout in nanoseconds, see RTDM_TIMEOUT_xxx for special values
Application Scenario:
int device_service_routine(...)
{
        rtdm_toseq_t timeout_seq;
        ...

        rtdm_toseq_init(&timeout_seq, timeout);
        ...
        while (received < requested) {
                ret = rtdm_event_timedwait(&data_available, timeout, &timeout_seq);
                if (ret < 0) // including -ETIMEDOUT
                        break;

                // receive some data
                ...
        }
        ...
}
Using a timeout sequence in such a scenario avoids that the user-provided relative timeout is restarted on every call to rtdm_event_timedwait(), potentially causing an overall delay that is larger than specified by timeout. Moreover, all functions supporting timeout sequences also interpret special timeout values (infinite and non-blocking), disburdening the driver developer from handling them separately.

Environments:

This service can be called from:

Rescheduling: never.


Generated on Mon Mar 24 18:02:43 2008 for Xenomai API by  doxygen 1.5.3