rtai-core/ipc/sem/sem.c File Reference


Detailed Description

Semaphore functions.

Author:
Paolo Mantegazza
Note:
Copyright (C) 1999-2003 Paolo Mantegazza <mantegazza@aero.polimi.it>
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

Include dependency graph for sem.c:

Include dependency graph

Functions

void rt_typed_sem_init (SEM *sem, int value, int type)
 Initialize a specifically typed (counting, binary, resource) semaphore.

void rt_sem_init (SEM *sem, int value)
 Initialize a counting semaphore.

int rt_sem_delete (SEM *sem)
 Delete a semaphore.

int rt_sem_signal (SEM *sem)
 Signaling a semaphore.

int rt_sem_broadcast (SEM *sem)
 Signaling a semaphore.

int rt_sem_wait (SEM *sem)
 Take a semaphore.

int rt_sem_wait_if (SEM *sem)
 Take a semaphore, only if the calling task is not blocked.

int rt_sem_wait_until (SEM *sem, RTIME time)
 Wait a semaphore with timeout.

int rt_sem_wait_timed (SEM *sem, RTIME delay)
 Wait a semaphore with timeout.

int rt_sem_wait_barrier (SEM *sem)
 Wait on a semaphore barrier.

int rt_cond_signal (CND *cnd)
 Wait for a signal to a conditional variable.

int rt_cond_wait (CND *cnd, SEM *mtx)
 Wait for a signal to a conditional variable.

int rt_cond_wait_until (CND *cnd, SEM *mtx, RTIME time)
 Wait a semaphore with timeout.

int rt_cond_wait_timed (CND *cnd, SEM *mtx, RTIME delay)
 Wait a semaphore with timeout.

int rt_rwl_init (RWL *rwl)
 Initialize a multi readers single writer lock.

int rt_rwl_delete (RWL *rwl)
 destroys a multi readers single writer lock.

int rt_rwl_rdlock (RWL *rwl)
 acquires a multi readers single writer lock for reading.

int rt_rwl_rdlock_if (RWL *rwl)
 try to acquire a multi readers single writer lock just for reading.

int rt_rwl_rdlock_until (RWL *rwl, RTIME time)
 try to acquire a multi readers single writer lock for reading within an absolute deadline time.

int rt_rwl_rdlock_timed (RWL *rwl, RTIME delay)
 try to acquire a multi readers single writer lock for reading within a relative deadline time.

int rt_rwl_wrlock (RWL *rwl)
 acquires a multi readers single writer lock for wrtiting.

int rt_rwl_wrlock_if (RWL *rwl)
 acquires a multi readers single writer lock for writing.

int rt_rwl_wrlock_until (RWL *rwl, RTIME time)
 try to acquire a multi readers single writer lock for writing within an absolute deadline time.

int rt_rwl_wrlock_timed (RWL *rwl, RTIME delay)
 try to acquire a multi readers single writer lock for writing within a relative deadline time.

int rt_rwl_unlock (RWL *rwl)
 unlock an acquired multi readers single writer lock.

int rt_spl_init (SPL *spl)
 Initialize a spinlock.

int rt_spl_delete (SPL *spl)
 Initialize a spinlock.

int rt_spl_lock (SPL *spl)
 Acquire a spinlock.

int rt_spl_lock_if (SPL *spl)
 Acquire a spinlock without waiting.

int rt_spl_lock_timed (SPL *spl, unsigned long ns)
 Acquire a spinlock with timeout.

int rt_spl_unlock (SPL *spl)
 Release an owned spinlock.

SEM * _rt_typed_named_sem_init (unsigned long sem_name, int value, int type)
 Initialize a specifically typed (counting, binary, resource) semaphore identified by a name.

int rt_named_sem_delete (SEM *sem)
 Delete a semaphore initialized in named mode.

RWL * _rt_named_rwl_init (unsigned long rwl_name)
 Initialize a multi readers single writer lock identified by a name.

int rt_named_rwl_delete (RWL *rwl)
 Delete a multi readers single writer lock in named mode.

SPL * _rt_named_spl_init (unsigned long spl_name)
 Initialize a spinlock identified by a name.

int rt_named_spl_delete (SPL *spl)
 Delete a spinlock in named mode.


Function Documentation

int rt_cond_signal CND *  cnd  ) 
 

Wait for a signal to a conditional variable.

rt_cond_signal resumes one of the tasks that are waiting on the condition semaphore cnd. Nothing happens if no task is waiting on cnd, while it resumed the first queued task blocked on cnd, according to the queueing method set at rt_cond_init.

Parameters:
cnd points to the structure used in the call to rt_cond_init().
Returns:
0

int rt_cond_wait CND *  cnd,
SEM *  mtx
 

Wait for a signal to a conditional variable.

rt_cond_wait atomically unlocks mtx (as for using rt_sem_signal) and waits for the condition semaphore cnd to be signaled. The task execution is suspended until the condition semaphore is signalled. Mtx must be obtained by the calling task, before calling rt_cond_wait is called. Before returning to the calling task rt_cond_wait reacquires mtx by calling rt_sem_wait.

Parameters:
cnd points to the structure used in the call to rt_cond_init().
mtx points to the structure used in the call to rt_sem_init().
Returns:
0 on succes, SEM_ERR in case of error.

int rt_cond_wait_timed CND *  cnd,
SEM *  mtx,
RTIME  delay
 

Wait a semaphore with timeout.

rt_cond_wait_timed atomically unlocks mtx (as for using rt_sem_signal) and waits for the condition semaphore cnd to be signalled. The task execution is suspended until the condition semaphore is either signaled or a timeout expires. Mtx must be obtained by the calling task, before calling rt_cond_wait is called. Before returning to the calling task rt_cond_wait_until reacquires mtx by calling rt_sem_wait and returns a value to indicate if it has been signalled pr timedout.

Parameters:
cnd points to the structure used in the call to rt_cond_init().
mtx points to the structure used in the call to rt_sem_init().
delay is a realtive time values with respect to the current time, in timer count unit.
Returns:
0 if it was signaled, SEM_TIMOUT if a timeout occured, SEM_ERR if the task has been resumed because of any other action (likely cnd was deleted).

int rt_cond_wait_until CND *  cnd,
SEM *  mtx,
RTIME  time
 

Wait a semaphore with timeout.

rt_cond_wait_until atomically unlocks mtx (as for using rt_sem_signal) and waits for the condition semaphore cnd to be signalled. The task execution is suspended until the condition semaphore is either signaled or a timeout expires. Mtx must be obtained by the calling task, before calling rt_cond_wait is called. Before returning to the calling task rt_cond_wait_until reacquires mtx by calling rt_sem_wait and returns a value to indicate if it has been signalled pr timedout.

Parameters:
cnd points to the structure used in the call to rt_cond_init().
mtx points to the structure used in the call to rt_sem_init().
time is an absolute value to the current time, in timer count unit.
Returns:
0 if it was signaled, SEM_TIMOUT if a timeout occured, SEM_ERR if the task has been resumed because of any other action (likely cnd was deleted).

int rt_named_sem_delete SEM *  sem  ) 
 

Delete a semaphore initialized in named mode.

rt_named_sem_delete deletes a semaphore previously created with _rt_typed_named_sem_init().

Parameters:
sem points to the structure pointer returned by a corresponding call to _rt_typed_named_sem_init.
Any tasks blocked on this semaphore is returned in error and allowed to run when semaphore is destroyed. As it is done by all the named allocation functions delete calls have just the effect of decrementing a usage count till the last is done, as that is the one the really frees the object.

Returns:
an int >=0 is returned upon success, SEM_ERR if it failed to delete the semafore, -EFAULT if the semaphore does not exist anymore.

int rt_sem_broadcast SEM *  sem  ) 
 

Signaling a semaphore.

rt_sem_broadcast signals an event to a semaphore that unblocks all tasks waiting on it. It is used as a support for RTAI proper conditional variables but can be of help in many other instances. After the broadcast the semaphore counts is set to zero, thus all tasks waiting on it will blocked.

Parameters:
sem points to the structure used in the call to rt_sem_init().
Returns:
0 always.

int rt_sem_delete SEM *  sem  ) 
 

Delete a semaphore.

rt_sem_delete deletes a semaphore previously created with rt_sem_init().

Parameters:
sem points to the structure used in the corresponding call to rt_sem_init.
Any tasks blocked on this semaphore is returned in error and allowed to run when semaphore is destroyed.

Returns:
0 is returned upon success. A negative value is returned on failure as described below:
  • 0xFFFF: sem does not refer to a valid semaphore.
Note:
In principle 0xFFFF could theoretically be a usable semaphores events count, so it could be returned also under normal circumstances. It is unlikely you are going to count up to such number of events, in any case avoid counting up to 0xFFFF.

int rt_sem_signal SEM *  sem  ) 
 

Signaling a semaphore.

rt_sem_signal signals an event to a semaphore. It is typically called when the task leaves a critical region. The semaphore value is incremented and tested. If the value is not positive, the first task in semaphore's waiting queue is allowed to run. rt_sem_signal never blocks the caller task.

Parameters:
sem points to the structure used in the call to rt_sem_init().
Returns:
0 is returned upon success. A negative value is returned on failure as described below:
  • 0xFFFF: sem does not refer to a valid semaphore.
Note:
In principle 0xFFFF could theoretically be a usable semaphores events count, so it could be returned also under normal circumstances. It is unlikely you are going to count up to such number of events, in any case avoid counting up to 0xFFFF. See rt_sem_wait() notes for some curiosities.

int rt_sem_wait SEM *  sem  ) 
 

Take a semaphore.

rt_sem_wait waits for a event to be signaled to a semaphore. It is typically called when a task enters a critical region. The semaphore value is decremented and tested. If it is still non-negative rt_sem_wait returns immediately. Otherwise the caller task is blocked and queued up. Queuing may happen in priority order or on FIFO base. This is determined by the compile time option SEM_PRIORD. In this case rt_sem_wait returns if:

  • The caller task is in the first place of the waiting queue and another task issues a rt_sem_signal() call;
  • An error occurs (e.g. the semaphore is destroyed);

Parameters:
sem points to the structure used in the call to rt_sem_init().
Returns:
the number of events already signaled upon success. A special value" as described below in case of a failure :
  • 0xFFFF: sem does not refer to a valid semaphore.
Note:
In principle 0xFFFF could theoretically be a usable semaphores events count, so it could be returned also under normal circumstances. It is unlikely you are going to count up to such number of events, in any case avoid counting up to 0xFFFF.
Just for curiosity: the original Dijkstra notation for rt_sem_wait was a "P" operation, and rt_sem_signal was a "V" operation. The name for P comes from the Dutch "prolagen", a combination of "proberen" (to probe) and "verlagen" (to decrement). Also from the word "passeren" (to pass).
The name for V comes from the Dutch "verhogen" (to increase) or "vrygeven" (to release). (Source: Daniel Tabak - Multiprocessors, Prentice Hall, 1990).
It should be also remarked that real time programming practitioners were using semaphores a long time before Dijkstra formalized P and V. "In Italian semaforo" means a traffic light, so that semaphores have an intuitive appeal and their use and meaning is easily understood.

int rt_sem_wait_barrier SEM *  sem  ) 
 

Wait on a semaphore barrier.

rt_sem_wait_barrier is a gang waiting in that a task issuing such a request will be blocked till a number of tasks equal to the semaphore count set at rt_sem_init is reached.

Returns:
0 always.

int rt_sem_wait_if SEM *  sem  ) 
 

Take a semaphore, only if the calling task is not blocked.

rt_sem_wait_if is a version of the semaphore wait operation is similar to rt_sem_wait() but it is never blocks the caller. If the semaphore is not free, rt_sem_wait_if returns immediately and the semaphore value remains unchanged.

Parameters:
sem points to the structure used in the call to rt_sem_init().
Returns:
the number of events already signaled upon success. A special value as described below in case of a failure:
  • 0xFFFF: sem does not refer to a valid semaphore.
Note:
In principle 0xFFFF could theoretically be a usable semaphores events count so it could be returned also under normal circumstances. It is unlikely you are going to count up to such number of events, in any case avoid counting up to 0xFFFF.

int rt_sem_wait_timed SEM *  sem,
RTIME  delay
 

Wait a semaphore with timeout.

rt_sem_wait_timed, like rt_sem_wait_until(), is a timed version of the standard semaphore wait call. The semaphore value is decremented and tested. If it is still non-negative these functions return immediately. Otherwise the caller task is blocked and queued up. Queuing may happen in priority order or on FIFO base. This is determined by the compile time option SEM_PRIORD. In this case the function returns if:

  • The caller task is in the first place of the waiting queue and an other task issues a rt_sem_signal() call;
  • a timeout occurs;
  • an error occurs (e.g. the semaphore is destroyed);

In case of a timeout, the semaphore value is incremented before return.

Parameters:
sem points to the structure used in the call to rt_sem_init().
delay is an absolute value to the current time.
Returns:
the number of events already signaled upon success. A special value as described below in case of a failure:
  • 0xFFFF: sem does not refer to a valid semaphore.
Note:
In principle 0xFFFF could theoretically be a usable semaphores events count so it could be returned also under normal circumstances. It is unlikely you are going to count up to such number of events, in any case avoid counting up to 0xFFFF.

int rt_sem_wait_until SEM *  sem,
RTIME  time
 

Wait a semaphore with timeout.

rt_sem_wait_until, like rt_sem_wait_timed() is a timed version of the standard semaphore wait call. The semaphore value is decremented and tested. If it is still non-negative these functions return immediately. Otherwise the caller task is blocked and queued up. Queuing may happen in priority order or on FIFO base. This is determined by the compile time option SEM_PRIORD. In this case the function returns if:

  • The caller task is in the first place of the waiting queue and an other task issues a rt_sem_signal call();
  • a timeout occurs;
  • an error occurs (e.g. the semaphore is destroyed);

In case of a timeout, the semaphore value is incremented before return.

Parameters:
sem points to the structure used in the call to rt_sem_init().
time is an absolute value to the current time.
Returns:
the number of events already signaled upon success. Aa special value" as described below in case of a failure:
  • 0xFFFF: sem does not refer to a valid semaphore.
Note:
In principle 0xFFFF could theoretically be a usable semaphores events count so it could be returned also under normal circumstances. It is unlikely you are going to count up to such number of events, in any case avoid counting up to 0xFFFF.


Generated on Sat Jul 24 19:36:14 2004 for RTAI API by doxygen 1.3.4