URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
[/] [or1k/] [trunk/] [ecos-2.0/] [doc/] [html/] [ref/] [kernel-semaphores.html] - Rev 1765
Compare with Previous | Blame | View Log
<!-- Copyright (C) 2003 Red Hat, Inc. --> <!-- This material may be distributed only subject to the terms --> <!-- and conditions set forth in the Open Publication License, v1.0 --> <!-- or later (the latest version is presently available at --> <!-- http://www.opencontent.org/openpub/). --> <!-- Distribution of the work or derivative of the work in any --> <!-- standard (paper) book form is prohibited unless prior --> <!-- permission is obtained from the copyright holder. --> <HTML ><HEAD ><TITLE >Semaphores</TITLE ><meta name="MSSmartTagsPreventParsing" content="TRUE"> <META NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+ "><LINK REL="HOME" TITLE="eCos Reference Manual" HREF="ecos-ref.html"><LINK REL="UP" TITLE="The eCos Kernel" HREF="kernel.html"><LINK REL="PREVIOUS" TITLE="Condition Variables" HREF="kernel-condition-variables.html"><LINK REL="NEXT" TITLE="Mail boxes" HREF="kernel-mail-boxes.html"></HEAD ><BODY CLASS="REFENTRY" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#840084" ALINK="#0000FF" ><DIV CLASS="NAVHEADER" ><TABLE SUMMARY="Header navigation table" WIDTH="100%" BORDER="0" CELLPADDING="0" CELLSPACING="0" ><TR ><TH COLSPAN="3" ALIGN="center" >eCos Reference Manual</TH ></TR ><TR ><TD WIDTH="10%" ALIGN="left" VALIGN="bottom" ><A HREF="kernel-condition-variables.html" ACCESSKEY="P" >Prev</A ></TD ><TD WIDTH="80%" ALIGN="center" VALIGN="bottom" ></TD ><TD WIDTH="10%" ALIGN="right" VALIGN="bottom" ><A HREF="kernel-mail-boxes.html" ACCESSKEY="N" >Next</A ></TD ></TR ></TABLE ><HR ALIGN="LEFT" WIDTH="100%"></DIV ><H1 ><A NAME="KERNEL-SEMAPHORES">Semaphores</H1 ><DIV CLASS="REFNAMEDIV" ><A NAME="AEN1330" ></A ><H2 >Name</H2 >cyg_semaphore_init, cyg_semaphore_destroy, cyg_semaphore_wait, cyg_semaphore_timed_wait, cyg_semaphore_post, cyg_semaphore_peek -- Synchronization primitive</DIV ><DIV CLASS="REFSYNOPSISDIV" ><A NAME="AEN1338"><H2 >Synopsis</H2 ><DIV CLASS="FUNCSYNOPSIS" ><A NAME="AEN1339"><P ></P ><TABLE BORDER="5" BGCOLOR="#E0E0F0" WIDTH="70%" ><TR ><TD ><PRE CLASS="FUNCSYNOPSISINFO" >#include <cyg/kernel/kapi.h> </PRE ></TD ></TR ></TABLE ><P ><CODE ><CODE CLASS="FUNCDEF" >void cyg_semaphore_init</CODE >(cyg_sem_t* sem, cyg_count32 val);</CODE ></P ><P ><CODE ><CODE CLASS="FUNCDEF" >void cyg_semaphore_destroy</CODE >(cyg_sem_t* sem);</CODE ></P ><P ><CODE ><CODE CLASS="FUNCDEF" >cyg_bool_t cyg_semaphore_wait</CODE >(cyg_sem_t* sem);</CODE ></P ><P ><CODE ><CODE CLASS="FUNCDEF" >cyg_bool_t cyg_semaphore_timed_wait</CODE >(cyg_sem_t* sem, cyg_tick_count_t abstime);</CODE ></P ><P ><CODE ><CODE CLASS="FUNCDEF" >cyg_bool_t cyg_semaphore_trywait</CODE >(cyg_sem_t* sem);</CODE ></P ><P ><CODE ><CODE CLASS="FUNCDEF" >void cyg_semaphore_post</CODE >(cyg_sem_t* sem);</CODE ></P ><P ><CODE ><CODE CLASS="FUNCDEF" >void cyg_semaphore_peek</CODE >(cyg_sem_t* sem, cyg_count32* val);</CODE ></P ><P ></P ></DIV ></DIV ><DIV CLASS="REFSECT1" ><A NAME="KERNEL-SEMAPHORES-DESCRIPTION" ></A ><H2 >Description</H2 ><P >Counting semaphores are a <A HREF="kernel-overview.html#KERNEL-OVERVIEW-SYNCH-PRIMITIVES" >synchronization primitive</A > that allow threads to wait until an event has occurred. The event may be generated by a producer thread, or by a DSR in response to a hardware interrupt. Associated with each semaphore is an integer counter that keeps track of the number of events that have not yet been processed. If this counter is zero, an attempt by a consumer thread to wait on the semaphore will block until some other thread or a DSR posts a new event to the semaphore. If the counter is greater than zero then an attempt to wait on the semaphore will consume one event, in other words decrement the counter, and return immediately. Posting to a semaphore will wake up the first thread that is currently waiting, which will then resume inside the semaphore wait operation and decrement the counter again. </P ><P >Another use of semaphores is for certain forms of resource management. The counter would correspond to how many of a certain type of resource are currently available, with threads waiting on the semaphore to claim a resource and posting to release the resource again. In practice <A HREF="kernel-condition-variables.html" >condition variables</A > are usually much better suited for operations like this. </P ><P ><TT CLASS="FUNCTION" >cyg_semaphore_init</TT > is used to initialize a semaphore. It takes two arguments, a pointer to a <SPAN CLASS="STRUCTNAME" >cyg_sem_t</SPAN > structure and an initial value for the counter. Note that semaphore operations, unlike some other parts of the kernel API, use pointers to data structures rather than handles. This makes it easier to embed semaphores in a larger data structure. The initial counter value can be any number, zero, positive or negative, but typically a value of zero is used to indicate that no events have occurred yet. </P ><P ><TT CLASS="FUNCTION" >cyg_semaphore_wait</TT > is used by a consumer thread to wait for an event. If the current counter is greater than 0, in other words if the event has already occurred in the past, then the counter will be decremented and the call will return immediately. Otherwise the current thread will be blocked until there is a <TT CLASS="FUNCTION" >cyg_semaphore_post</TT > call. </P ><P ><TT CLASS="FUNCTION" >cyg_semaphore_post</TT > is called when an event has occurs. This increments the counter and wakes up the first thread waiting on the semaphore (if any). Usually that thread will then continue running inside <TT CLASS="FUNCTION" >cyg_semaphore_wait</TT > and decrement the counter again. However other scenarioes are possible. For example the thread calling <TT CLASS="FUNCTION" >cyg_semaphore_post</TT > may be running at high priority, some other thread running at medium priority may be about to call <TT CLASS="FUNCTION" >cyg_semaphore_wait</TT > when it next gets a chance to run, and a low priority thread may be waiting on the semaphore. What will happen is that the current high priority thread continues running until it is descheduled for some reason, then the medium priority thread runs and its call to <TT CLASS="FUNCTION" >cyg_semaphore_wait</TT > succeeds immediately, and later on the low priority thread runs again, discovers a counter value of 0, and blocks until another event is posted. If there are multiple threads blocked on a semaphore then the configuration option <TT CLASS="VARNAME" >CYGIMP_KERNEL_SCHED_SORTED_QUEUES</TT > determines which one will be woken up by a post operation. </P ><P ><TT CLASS="FUNCTION" >cyg_semaphore_wait</TT > returns a boolean. Normally it will block until it has successfully decremented the counter, retrying as necessary, and return success. However the wait operation may be aborted by a call to <A HREF="kernel-thread-control.html" ><TT CLASS="FUNCTION" >cyg_thread_release</TT ></A >, and <TT CLASS="FUNCTION" >cyg_semaphore_wait</TT > will then return false. </P ><P ><TT CLASS="FUNCTION" >cyg_semaphore_timed_wait</TT > is a variant of <TT CLASS="FUNCTION" >cyg_semaphore_wait</TT >. It can be used to wait until either an event has occurred or a number of clock ticks have happened. The function returns success if the semaphore wait operation succeeded, or false if the operation timed out or was aborted by <TT CLASS="FUNCTION" >cyg_thread_release</TT >. If support for the real-time clock has been removed from the current configuration then this function will not be available. <TT CLASS="FUNCTION" >cyg_semaphore_trywait</TT > is another variant which will always return immediately rather than block, again returning success or failure. </P ><P ><TT CLASS="FUNCTION" >cyg_semaphore_peek</TT > can be used to get hold of the current counter value. This function is rarely useful except for debugging purposes since the counter value may change at any time if some other thread or a DSR performs a semaphore operation. </P ></DIV ><DIV CLASS="REFSECT1" ><A NAME="KERNEL-SEMAPHORES-CONTEXT" ></A ><H2 >Valid contexts</H2 ><P ><TT CLASS="FUNCTION" >cyg_semaphore_init</TT > is normally called during initialization but may also be called from thread context. <TT CLASS="FUNCTION" >cyg_semaphore_wait</TT > and <TT CLASS="FUNCTION" >cyg_semaphore_timed_wait</TT > may only be called from thread context because these operations may block. <TT CLASS="FUNCTION" >cyg_semaphore_trywait</TT >, <TT CLASS="FUNCTION" >cyg_semaphore_post</TT > and <TT CLASS="FUNCTION" >cyg_semaphore_peek</TT > may be called from thread or DSR context. </P ></DIV ><DIV CLASS="NAVFOOTER" ><HR ALIGN="LEFT" WIDTH="100%"><TABLE SUMMARY="Footer navigation table" WIDTH="100%" BORDER="0" CELLPADDING="0" CELLSPACING="0" ><TR ><TD WIDTH="33%" ALIGN="left" VALIGN="top" ><A HREF="kernel-condition-variables.html" ACCESSKEY="P" >Prev</A ></TD ><TD WIDTH="34%" ALIGN="center" VALIGN="top" ><A HREF="ecos-ref.html" ACCESSKEY="H" >Home</A ></TD ><TD WIDTH="33%" ALIGN="right" VALIGN="top" ><A HREF="kernel-mail-boxes.html" ACCESSKEY="N" >Next</A ></TD ></TR ><TR ><TD WIDTH="33%" ALIGN="left" VALIGN="top" >Condition Variables</TD ><TD WIDTH="34%" ALIGN="center" VALIGN="top" ><A HREF="kernel.html" ACCESSKEY="U" >Up</A ></TD ><TD WIDTH="33%" ALIGN="right" VALIGN="top" >Mail boxes</TD ></TR ></TABLE ></DIV ></BODY ></HTML >