1 /**
2  * D header file for POSIX.
3  *
4  * Copyright: Copyright Sean Kelly 2005 - 2009.
5  * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6  * Authors:   Sean Kelly, Alex Rønne Petersen
7  * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition
8  */
9 
10 /*          Copyright Sean Kelly 2005 - 2009.
11  * Distributed under the Boost Software License, Version 1.0.
12  *    (See accompanying file LICENSE or copy at
13  *          http://www.boost.org/LICENSE_1_0.txt)
14  */
15 module core.sys.posix.semaphore;
16 
17 import core.sys.posix.config;
18 import core.sys.posix.time;
19 
20 version (OSX)
21     version = Darwin;
22 else version (iOS)
23     version = Darwin;
24 else version (TVOS)
25     version = Darwin;
26 else version (WatchOS)
27     version = Darwin;
28 
29 version (Posix):
30 extern (C):
31 nothrow:
32 @nogc:
33 
34 //
35 // Required
36 //
37 /*
38 sem_t
39 SEM_FAILED
40 
41 int sem_close(sem_t*);
42 int sem_destroy(sem_t*);
43 int sem_getvalue(sem_t*, int*);
44 int sem_init(sem_t*, int, uint);
45 sem_t* sem_open(const scope char*, int, ...);
46 int sem_post(sem_t*);
47 int sem_trywait(sem_t*);
48 int sem_unlink(const scope char*);
49 int sem_wait(sem_t*);
50 */
51 
52 version (CRuntime_Glibc)
53 {
54     private alias int __atomic_lock_t;
55 
56     private struct _pthread_fastlock
57     {
58       c_long            __status;
59       __atomic_lock_t   __spinlock;
60     }
61 
62     struct sem_t
63     {
64       _pthread_fastlock __sem_lock;
65       int               __sem_value;
66       void*             __sem_waiting;
67     }
68 
69     enum SEM_FAILED = cast(sem_t*) null;
70 }
71 else version (Darwin)
72 {
73     alias int sem_t;
74 
75     enum SEM_FAILED = cast(sem_t*) null;
76 }
77 else version (FreeBSD)
78 {
79     // FBSD-9.0 definition
80     struct sem_t
81     {
82         uint _magic;
83         struct _usem
84         {
85             shared uint _has_waiters;
86             shared uint _count;
87             uint _flags;
88         } _usem _kern;
89     }
90 
91     enum SEM_FAILED = cast(sem_t*) null;
92 }
93 else version (NetBSD)
94 {
95     alias size_t sem_t;
96 
97     enum SEM_FAILED = cast(sem_t*) null;
98 }
99 else version (OpenBSD)
100 {
101     struct __sem;
102     alias sem_t = __sem*;
103 
104     enum SEM_FAILED = cast(sem_t*) null;
105 }
106 else version (DragonFlyBSD)
107 {
108     struct sem_t
109     {
110         uint _magic;
111         struct _usem
112         {
113             shared uint _has_waiters;
114             shared uint _count;
115             uint _flags;
116         } _usem _kern;
117     }
118 
119     enum SEM_FAILED = cast(sem_t*) null;
120 }
121 else version (Solaris)
122 {
123     struct sem_t
124     {
125         uint sem_count;
126         ushort sem_type;
127         ushort sem_magic;
128         ulong[3] sem_pad1;
129         ulong[2] sem_pad2;
130     }
131 
132     enum SEM_FAILED = cast(sem_t*)-1;
133 }
134 else version (CRuntime_Bionic)
135 {
136     struct sem_t
137     {
138         uint count; //volatile
139     }
140 
141     enum SEM_FAILED = null;
142 }
143 else version (CRuntime_Musl)
144 {
145     struct sem_t {
146         int[4*c_long.sizeof/int.sizeof] __val;
147     }
148 
149     enum SEM_FAILED = (sem_t*).init;
150 }
151 else version (CRuntime_UClibc)
152 {
153     enum __SIZEOF_SEM_T  = 16;
154 
155     union sem_t
156     {
157         byte[__SIZEOF_SEM_T] __size;
158         c_long __align;
159     }
160 
161     enum SEM_FAILED      = cast(sem_t*) null;
162 }
163 else
164 {
165     static assert(false, "Unsupported platform");
166 }
167 
168 int sem_close(sem_t*);
169 int sem_destroy(sem_t*);
170 int sem_getvalue(sem_t*, int*);
171 int sem_init(sem_t*, int, uint);
172 sem_t* sem_open(const scope char*, int, ...);
173 int sem_post(sem_t*);
174 int sem_trywait(sem_t*);
175 int sem_unlink(const scope char*);
176 int sem_wait(sem_t*);
177 
178 //
179 // Timeouts (TMO)
180 //
181 /*
182 int sem_timedwait(sem_t*, const scope timespec*);
183 */
184 
185 version (CRuntime_Glibc)
186 {
187     int sem_timedwait(sem_t*, const scope timespec*);
188 }
189 else version (Darwin)
190 {
191     int sem_timedwait(sem_t*, const scope timespec*);
192 }
193 else version (FreeBSD)
194 {
195     int sem_timedwait(sem_t*, const scope timespec*);
196 }
197 else version (NetBSD)
198 {
199     int sem_timedwait(sem_t*, const scope timespec*);
200 }
201 else version (OpenBSD)
202 {
203     int sem_timedwait(sem_t*, const scope timespec*);
204 }
205 else version (DragonFlyBSD)
206 {
207     int sem_timedwait(sem_t*, const scope timespec*);
208 }
209 else version (Solaris)
210 {
211     int sem_timedwait(sem_t*, const scope timespec*);
212 }
213 else version (CRuntime_Bionic)
214 {
215     int sem_timedwait(sem_t*, const scope timespec*);
216 }
217 else version (CRuntime_Musl)
218 {
219     pragma(mangle, muslRedirTime64Mangle!("sem_timedwait", "__sem_timedwait_time64"))
220     int sem_timedwait(sem_t*, const scope timespec*);
221 }
222 else version (CRuntime_UClibc)
223 {
224     int sem_timedwait(sem_t*, const scope timespec*);
225 }
226 else
227 {
228     static assert(false, "Unsupported platform");
229 }