]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/compat/posix/v2_0/src/sem.cxx
Initial revision
[karo-tx-redboot.git] / packages / compat / posix / v2_0 / src / sem.cxx
1 //==========================================================================
2 //
3 //      sem.cxx
4 //
5 //      POSIX semaphore implementation
6 //
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.
12 //
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.
16 //
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
20 // for more details.
21 //
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.
25 //
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.
32 //
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.
35 //
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####
42 //
43 // Author(s):           nickg
44 // Contributors:        nickg
45 // Date:                2000-03-27
46 // Purpose:             POSIX semaphore implementation
47 // Description:         This file contains the implementation of the POSIX semaphore
48 //                      functions.
49 //              
50 //              
51 //
52 //####DESCRIPTIONEND####
53 //
54 //==========================================================================
55
56 #include <pkgconf/hal.h>
57 #include <pkgconf/kernel.h>
58 #include <pkgconf/posix.h>
59
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
63
64 #include <semaphore.h>                  // our header
65
66 #include "pprivate.h"                   // POSIX private header
67
68 #include <cyg/kernel/thread.hxx>        // Kernel threads
69
70 #include <cyg/kernel/thread.inl>        // Cyg_ThreadQueue::empty()
71
72 #include <cyg/kernel/sema.hxx>          // Kernel semaphores
73
74 // -------------------------------------------------------------------------
75 // Internal definitions
76
77 // Handle entry to a pthread package function. 
78 #define SEMA_ENTRY() CYG_REPORT_FUNCTYPE( "returning %d" );
79
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
84 // cancellation.
85 #define SEMA_RETURN(err)                        \
86 CYG_MACRO_START                                 \
87     int __retval = 0;                           \
88     if( err != 0 ) __retval = -1, errno = err;  \
89     CYG_REPORT_RETVAL( __retval );              \
90     return __retval;                            \
91 CYG_MACRO_END
92
93 //-----------------------------------------------------------------------------
94 // new operator to allow us to invoke the Cyg_Thread constructor on the
95 // user's semaphore object.
96
97 inline void *operator new(size_t size,  void *ptr) { return (void *)ptr; };
98
99 // -------------------------------------------------------------------------
100 // Initialize semaphore to value.
101 // pshared is not supported under eCos.
102
103 externC int sem_init  (sem_t *sem, int pshared, unsigned int value)
104 {
105     SEMA_ENTRY();
106
107     if( value > SEM_VALUE_MAX )
108         SEMA_RETURN(EINVAL);
109
110     Cyg_Counting_Semaphore *sema;
111
112     sema = new((void *)sem) Cyg_Counting_Semaphore(value);
113
114     sema=sema;
115     
116     SEMA_RETURN(0);
117 }
118
119 // -------------------------------------------------------------------------
120 // Destroy the semaphore.
121
122 externC int sem_destroy  (sem_t *sem)
123 {
124     SEMA_ENTRY();
125
126     Cyg_Counting_Semaphore *sema = (Cyg_Counting_Semaphore *)sem;
127
128     // Check that the semaphore has no waiters
129     if( sema->waiting() )
130         SEMA_RETURN(EBUSY);
131
132     // Call the destructor
133     sema->~Cyg_Counting_Semaphore();
134     
135     SEMA_RETURN(0);
136 }
137
138 // -------------------------------------------------------------------------
139 // Decrement value if >0 or wait for a post.
140
141 externC int sem_wait  (sem_t *sem)
142 {
143     int retval = 0;
144     
145     SEMA_ENTRY();
146
147 #ifdef CYGPKG_POSIX_PTHREAD
148     // check for cancellation first.
149     pthread_testcancel();
150 #endif
151
152     Cyg_Counting_Semaphore *sema = (Cyg_Counting_Semaphore *)sem;
153
154     if( !sema->wait() ) retval = EINTR;
155     
156 #ifdef CYGPKG_POSIX_PTHREAD
157     // check if we were woken because we were being cancelled
158     pthread_testcancel();
159 #endif
160
161     SEMA_RETURN(retval);
162 }
163
164 // -------------------------------------------------------------------------
165 // Decrement value if >0, return -1 if not.
166
167 externC int sem_trywait  (sem_t *sem)
168 {
169     int retval = 0;
170     
171     SEMA_ENTRY();
172
173     Cyg_Counting_Semaphore *sema = (Cyg_Counting_Semaphore *)sem;
174
175     if( !sema->trywait() ) retval = EAGAIN;
176     
177     SEMA_RETURN(retval);
178 }
179
180 // -------------------------------------------------------------------------
181 // Increment value and wake a waiter if one is present.
182
183 externC int sem_post  (sem_t *sem)
184 {
185     SEMA_ENTRY();
186
187     Cyg_Counting_Semaphore *sema = (Cyg_Counting_Semaphore *)sem;
188
189     sema->post();
190     
191     SEMA_RETURN(0);
192 }
193     
194
195 // -------------------------------------------------------------------------
196 // Get current value
197
198 externC int sem_getvalue  (sem_t *sem, int *sval)
199 {
200     SEMA_ENTRY();
201
202     Cyg_Counting_Semaphore *sema = (Cyg_Counting_Semaphore *)sem;
203
204     *sval = sema->peek();
205
206     CYG_REPORT_RETVAL( 0 );
207     return 0;
208 }
209
210 // -------------------------------------------------------------------------
211 // Open an existing named semaphore, or create it.
212
213 externC sem_t *sem_open  (const char *name, int oflag, ...)
214 {
215     SEMA_ENTRY();
216
217     errno = ENOSYS;
218
219     CYG_REPORT_RETVAL( SEM_FAILED );
220     return SEM_FAILED;
221 }
222
223 // -------------------------------------------------------------------------
224 // Close descriptor for semaphore.
225
226 externC int sem_close  (sem_t *sem)
227 {
228     SEMA_ENTRY();
229
230     SEMA_RETURN(ENOSYS);
231 }   
232
233 // -------------------------------------------------------------------------
234 // Remove named semaphore
235
236 externC int sem_unlink  (const char *name)
237 {
238     SEMA_ENTRY();
239
240     SEMA_RETURN(ENOSYS);
241 }    
242
243 // -------------------------------------------------------------------------
244 // EOF sem.cxx