1 //==========================================================================
5 // POSIX semaphore implementation
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //==========================================================================
41 //#####DESCRIPTIONBEGIN####
44 // Contributors: nickg
46 // Purpose: POSIX semaphore implementation
47 // Description: This file contains the implementation of the POSIX semaphore
52 //####DESCRIPTIONEND####
54 //==========================================================================
56 #include <pkgconf/hal.h>
57 #include <pkgconf/kernel.h>
58 #include <pkgconf/posix.h>
60 #include <cyg/kernel/ktypes.h> // base kernel types
61 #include <cyg/infra/cyg_trac.h> // tracing macros
62 #include <cyg/infra/cyg_ass.h> // assertion macros
64 #include <semaphore.h> // our header
66 #include "pprivate.h" // POSIX private header
68 #include <cyg/kernel/thread.hxx> // Kernel threads
70 #include <cyg/kernel/thread.inl> // Cyg_ThreadQueue::empty()
72 #include <cyg/kernel/sema.hxx> // Kernel semaphores
74 // -------------------------------------------------------------------------
75 // Internal definitions
77 // Handle entry to a pthread package function.
78 #define SEMA_ENTRY() CYG_REPORT_FUNCTYPE( "returning %d" );
80 // Do a semaphore package defined return. This requires the error code
81 // to be placed in errno, and if it is non-zero, -1 returned as the
82 // result of the function. This also gives us a place to put any
83 // generic tidyup handling needed for things like signal delivery and
85 #define SEMA_RETURN(err) \
88 if( err != 0 ) __retval = -1, errno = err; \
89 CYG_REPORT_RETVAL( __retval ); \
93 //-----------------------------------------------------------------------------
94 // new operator to allow us to invoke the Cyg_Thread constructor on the
95 // user's semaphore object.
97 inline void *operator new(size_t size, void *ptr) { return (void *)ptr; };
99 // -------------------------------------------------------------------------
100 // Initialize semaphore to value.
101 // pshared is not supported under eCos.
103 externC int sem_init (sem_t *sem, int pshared, unsigned int value)
107 if( value > SEM_VALUE_MAX )
110 Cyg_Counting_Semaphore *sema;
112 sema = new((void *)sem) Cyg_Counting_Semaphore(value);
119 // -------------------------------------------------------------------------
120 // Destroy the semaphore.
122 externC int sem_destroy (sem_t *sem)
126 Cyg_Counting_Semaphore *sema = (Cyg_Counting_Semaphore *)sem;
128 // Check that the semaphore has no waiters
129 if( sema->waiting() )
132 // Call the destructor
133 sema->~Cyg_Counting_Semaphore();
138 // -------------------------------------------------------------------------
139 // Decrement value if >0 or wait for a post.
141 externC int sem_wait (sem_t *sem)
147 #ifdef CYGPKG_POSIX_PTHREAD
148 // check for cancellation first.
149 pthread_testcancel();
152 Cyg_Counting_Semaphore *sema = (Cyg_Counting_Semaphore *)sem;
154 if( !sema->wait() ) retval = EINTR;
156 #ifdef CYGPKG_POSIX_PTHREAD
157 // check if we were woken because we were being cancelled
158 pthread_testcancel();
164 // -------------------------------------------------------------------------
165 // Decrement value if >0, return -1 if not.
167 externC int sem_trywait (sem_t *sem)
173 Cyg_Counting_Semaphore *sema = (Cyg_Counting_Semaphore *)sem;
175 if( !sema->trywait() ) retval = EAGAIN;
180 // -------------------------------------------------------------------------
181 // Increment value and wake a waiter if one is present.
183 externC int sem_post (sem_t *sem)
187 Cyg_Counting_Semaphore *sema = (Cyg_Counting_Semaphore *)sem;
195 // -------------------------------------------------------------------------
198 externC int sem_getvalue (sem_t *sem, int *sval)
202 Cyg_Counting_Semaphore *sema = (Cyg_Counting_Semaphore *)sem;
204 *sval = sema->peek();
206 CYG_REPORT_RETVAL( 0 );
210 // -------------------------------------------------------------------------
211 // Open an existing named semaphore, or create it.
213 externC sem_t *sem_open (const char *name, int oflag, ...)
219 CYG_REPORT_RETVAL( SEM_FAILED );
223 // -------------------------------------------------------------------------
224 // Close descriptor for semaphore.
226 externC int sem_close (sem_t *sem)
233 // -------------------------------------------------------------------------
234 // Remove named semaphore
236 externC int sem_unlink (const char *name)
243 // -------------------------------------------------------------------------