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 
version(Posix)29 version (Posix):
30 extern (C):
31 nothrow:
32 @nogc:
33 @system:
34 
35 //
36 // Required
37 //
38 /*
39 sem_t
40 SEM_FAILED
41 
42 int sem_close(sem_t*);
43 int sem_destroy(sem_t*);
44 int sem_getvalue(sem_t*, int*);
45 int sem_init(sem_t*, int, uint);
46 sem_t* sem_open(const scope char*, int, ...);
47 int sem_post(sem_t*);
48 int sem_trywait(sem_t*);
49 int sem_unlink(const scope char*);
50 int sem_wait(sem_t*);
51 */
52 
53 version (CRuntime_Glibc)
54 {
55     private alias int __atomic_lock_t;
56 
57     private struct _pthread_fastlock
58     {
59       c_long            __status;
60       __atomic_lock_t   __spinlock;
61     }
62 
63     struct sem_t
64     {
65       _pthread_fastlock __sem_lock;
66       int               __sem_value;
67       void*             __sem_waiting;
68     }
69 
70     enum SEM_FAILED = cast(sem_t*) null;
71 }
version(Darwin)72 else version (Darwin)
73 {
74     alias int sem_t;
75 
76     enum SEM_FAILED = cast(sem_t*) null;
77 }
version(FreeBSD)78 else version (FreeBSD)
79 {
80     // FBSD-9.0 definition
81     struct sem_t
82     {
83         uint _magic;
84         struct _usem
85         {
86             shared uint _has_waiters;
87             shared uint _count;
88             uint _flags;
89         } _usem _kern;
90     }
91 
92     enum SEM_FAILED = cast(sem_t*) null;
93 }
version(NetBSD)94 else version (NetBSD)
95 {
96     alias size_t sem_t;
97 
98     enum SEM_FAILED = cast(sem_t*) null;
99 }
version(OpenBSD)100 else version (OpenBSD)
101 {
102     struct __sem { }
103     alias sem_t = __sem*;
104 
105     enum SEM_FAILED = cast(sem_t*) null;
106 }
version(DragonFlyBSD)107 else version (DragonFlyBSD)
108 {
109     struct sem_t
110     {
111         uint _magic;
112         struct _usem
113         {
114             shared uint _has_waiters;
115             shared uint _count;
116             uint _flags;
117         } _usem _kern;
118     }
119 
120     enum SEM_FAILED = cast(sem_t*) null;
121 }
version(Solaris)122 else version (Solaris)
123 {
124     struct sem_t
125     {
126         uint sem_count;
127         ushort sem_type;
128         ushort sem_magic;
129         ulong[3] sem_pad1;
130         ulong[2] sem_pad2;
131     }
132 
133     enum SEM_FAILED = cast(sem_t*)-1;
134 }
version(CRuntime_Bionic)135 else version (CRuntime_Bionic)
136 {
137     struct sem_t
138     {
139         uint count; //volatile
140     }
141 
142     enum SEM_FAILED = null;
143 }
version(CRuntime_Musl)144 else version (CRuntime_Musl)
145 {
146     struct sem_t {
147         int[4*c_long.sizeof/int.sizeof] __val;
148     }
149 
150     enum SEM_FAILED = (sem_t*).init;
151 }
version(CRuntime_UClibc)152 else version (CRuntime_UClibc)
153 {
154     enum __SIZEOF_SEM_T  = 16;
155 
156     union sem_t
157     {
158         byte[__SIZEOF_SEM_T] __size;
159         c_long __align;
160     }
161 
162     enum SEM_FAILED      = cast(sem_t*) null;
163 }
164 else
165 {
166     static assert(false, "Unsupported platform");
167 }
168 
169 int sem_close(sem_t*);
170 int sem_destroy(sem_t*);
171 int sem_getvalue(sem_t*, int*);
172 int sem_init(sem_t*, int, uint);
173 sem_t* sem_open(const scope char*, int, ...);
174 int sem_post(sem_t*);
175 int sem_trywait(sem_t*);
176 int sem_unlink(const scope char*);
177 int sem_wait(sem_t*);
178 
179 //
180 // Timeouts (TMO)
181 //
182 /*
183 int sem_timedwait(sem_t*, const scope timespec*);
184 */
185 
version(CRuntime_Glibc)186 version (CRuntime_Glibc)
187 {
188     int sem_timedwait(sem_t*, const scope timespec*);
189 }
version(Darwin)190 else version (Darwin)
191 {
192     int sem_timedwait(sem_t*, const scope timespec*);
193 }
version(FreeBSD)194 else version (FreeBSD)
195 {
196     int sem_timedwait(sem_t*, const scope timespec*);
197 }
version(NetBSD)198 else version (NetBSD)
199 {
200     int sem_timedwait(sem_t*, const scope timespec*);
201 }
version(OpenBSD)202 else version (OpenBSD)
203 {
204     int sem_timedwait(sem_t*, const scope timespec*);
205 }
version(DragonFlyBSD)206 else version (DragonFlyBSD)
207 {
208     int sem_timedwait(sem_t*, const scope timespec*);
209 }
version(Solaris)210 else version (Solaris)
211 {
212     int sem_timedwait(sem_t*, const scope timespec*);
213 }
version(CRuntime_Bionic)214 else version (CRuntime_Bionic)
215 {
216     int sem_timedwait(sem_t*, const scope timespec*);
217 }
version(CRuntime_Musl)218 else version (CRuntime_Musl)
219 {
220     int sem_timedwait(sem_t*, const scope timespec*);
221 }
version(CRuntime_UClibc)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 }
230