% % Copyright (c) 1997-1999 University of Utah and the Flux Group. % All rights reserved. % % The University of Utah grants you the right to copy and reproduce this % document or portions thereof for academic, research, evaluation, and % personal use only, provided that (1) the title page appears prominently, % and (2) these copyright and permission notices are retained in all copies. % To arrange for alternate terms, contact the University of Utah at % csl-dist@cs.utah.edu or +1-801-585-3271. % \label{synch} \apiintf{oskit_lock}{Thread-safe lock interface} The {\tt oskit_lock} COM interface allows components to protect data structures from concurrent access by multiple threads. The interface is intended to be generic so that components do not need to know the specifics of any particular thread system. The user of a lock should be prepared for the possibility that the thread will be put to sleep if the lock cannot be granted. There are two variants supported; a regular lock and a critical lock. A critical lock differs only in that interrupts are blocked while the lock is held. The {\tt oskit_lock} COM interface inherits from {\tt oskit_iunknown}, and has the following additional methods: \begin{icsymlist} \item[lock] Lock a lock. \item[unlock] Unlock a lock. \end{icsymlist} \api{lock}{Lock a lock} \begin{apisyn} \cinclude{oskit/com/lock.h} \funcproto OSKIT_COMDECL oskit_lock_lock(oskit_lock_t *lock); \end{apisyn} \begin{apidesc} This method attempts to lock {\tt lock}. If the lock cannot be immediately granted, the current thread is put to sleep until the lock can be granted. \end{apidesc} \begin{apiparm} \item[lock] The {\tt oskit_lock} COM interface for the lock. \end{apiparm} \begin{apiret} Returns 0 on success, or an error code specified in {\tt }, on error. \end{apiret} \api{lock}{Unlock a lock} \begin{apisyn} \cinclude{oskit/com/lock.h} \funcproto OSKIT_COMDECL oskit_lock_unlock(oskit_lock_t *lock); \end{apisyn} \begin{apidesc} This method unlocks {\tt lock}. If there are any threads waiting for the lock, one will be woken up and granted the lock. \end{apidesc} \begin{apiparm} \item[lock] The {\tt oskit_lock} COM interface for the lock. \end{apiparm} \begin{apiret} Returns 0 on success, or an error code specified in {\tt }, on error. \end{apiret} \apiintf{oskit_condvar}{Condition variable interface} The {\tt oskit_condvar} COM interface allows components to wait for conditions. The interface is intended to be generic so that components do not need to know the specifics of any particular thread system. A condition is typically combined with an {\tt oskit_lock} object to facilitate building monitor type objects. Attempting to wait on a condition without supplying a locked {\tt oskit_lock} object results in undefined behavior. The {\tt oskit_lock} COM interface inherits from {\tt oskit_iunknown}, and has the following additional methods: \begin{icsymlist} \item[wait] Wait on a condition variable. \item[signal] Signal a condition variable. \item[broadcast] Broadcast a condition variable. \end{icsymlist} \api{wait}{Wait on a condition variable} \begin{apisyn} \cinclude{oskit/com/condvar.h} \funcproto OSKIT_COMDECL oskit_condvar_wait(oskit_condvar_t *condvar, oskit_lock_t *lock); \end{apisyn} \begin{apidesc} This method causes the current thread is to wait until the condition variable is signaled or broadcast. The {\tt oskit_lock} object must be locked when called. The lock is released prior to waiting, and reacquired before returning. \end{apidesc} \begin{apiparm} \item[condvar] The {\tt oskit_condvar} COM interface for the condition variable. \item[lock] The {\tt oskit_lock} COM interface for the lock. \end{apiparm} \begin{apiret} Returns 0 on success, or an error code specified in {\tt }, on error. \end{apiret} \api{signal}{Signal a condition variable} \begin{apisyn} \cinclude{oskit/com/condvar.h} \funcproto OSKIT_COMDECL oskit_condvar_signal(oskit_condvar_t *condvar); \end{apisyn} \begin{apidesc} Wake up exactly one thread waiting on the condition variable object {\tt condvar}. \end{apidesc} \begin{apiparm} \item[condvar] The {\tt oskit_condvar} COM interface for the condition variable. \end{apiparm} \begin{apiret} Returns 0 on success, or an error code specified in {\tt }, on error. \end{apiret} \api{broadcast}{Broadcast a condition variable} \begin{apisyn} \cinclude{oskit/com/condvar.h} \funcproto OSKIT_COMDECL oskit_condvar_broadcast(oskit_condvar_t *condvar); \end{apisyn} \begin{apidesc} Wake up all threads waiting on the condition variable object {\tt condvar}. \end{apidesc} \begin{apiparm} \item[condvar] The {\tt oskit_condvar} COM interface for the condition variable. \end{apiparm} \begin{apiret} Returns 0 on success, or an error code specified in {\tt }, on error. \end{apiret} \apiintf{oskit_lock_mgr}{Lock manager: Interface for creating locks and condition variables} \label{lock-mgr} The lock manager is registered in the services registry (See Section~\ref{oskit-services}) when the threading system (if it is included) is initialized. Components that need to protect data structures can query the services registry for the lock manager. Since the lock manager will only be registered by the threading system, the client can assume that the absence of a lock manager implies a single threaded system (locks are unnecessary). The {\tt oskit_lock_mgr} COM interface inherits from {\tt oskit_iunknown}, and has the following additional methods: \begin{csymlist} \item[allocate_lock] Allocate a lock object. \item[allocate_critical_lock] Allocate a critical lock object. \end{csymlist} \api{allocate_lock}{Allocate a thread-safe lock} \begin{apisyn} \cinclude{oskit/com/lock_mgr.h} \funcproto OSKIT_COMDECL oskit_lock_mgr_allocate_lock(oskit_lock_mgr_t *lmgr, \outparam oskit_lock_t *out_lock); \end{apisyn} \begin{apidesc} This method returns an {\tt oskit_lock_t} COM interface in {\tt out_lock}. \end{apidesc} \begin{apiparm} \item[lmgr] The lock manager COM interface. \item[out_lock] The {\tt oskit_lock} COM interface for the new lock. \end{apiparm} \begin{apiret} Returns 0 on success, or an error code specified in {\tt }, on error. \end{apiret} \api{allocate_critical_lock}{Allocate a critical thread-safe lock} \begin{apisyn} \cinclude{oskit/com/lock_mgr.h} \funcproto OSKIT_COMDECL oskit_lock_mgr_allocate_critical_lock(oskit_lock_mgr_t *lmgr, \outparam oskit_lock_t *out_lock); \end{apisyn} \begin{apidesc} This method returns an {\tt oskit_lock_t} COM interface in {\tt out_lock}. The lock is flagged as critical so that interrupts are blocked while the lock is held. \end{apidesc} \begin{apiparm} \item[lmgr] The lock manager COM interface. \item[out_lock] The {\tt oskit_lock} COM interface for the new lock. \end{apiparm} \begin{apiret} Returns 0 on success, or an error code specified in {\tt }, on error. \end{apiret} \api{allocate_condvar}{Allocate a condition variable} \begin{apisyn} \cinclude{oskit/com/lock_mgr.h} \funcproto OSKIT_COMDECL oskit_lock_mgr_allocate_condvar(oskit_lock_mgr_t *lmgr, \outparam oskit_condvar_t *out_condvar); \end{apisyn} \begin{apidesc} This method returns an {\tt oskit_condvar_t} COM interface in {\tt out_condvar}. Condition variables may be used in conjunction with locks to form monitors. \end{apidesc} \begin{apiparm} \item[lmgr] The lock manager COM interface. \item[out_condvar] The {\tt oskit_condvar} COM interface for the new condition variable. \end{apiparm} \begin{apiret} Returns 0 on success, or an error code specified in {\tt }, on error. \end{apiret}