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 */
15module core.sys.posix.semaphore;
16
17import core.sys.posix.config;
18import core.sys.posix.time;
19
20version (OSX)
21    version = Darwin;
22else version (iOS)
23    version = Darwin;
24else version (TVOS)
25    version = Darwin;
26else version (WatchOS)
27    version = Darwin;
28
29version (Posix):
30extern (C):
31nothrow:
32@nogc:
33@system:
34
35//
36// Required
37//
38/*
39sem_t
40SEM_FAILED
41
42int sem_close(sem_t*);
43int sem_destroy(sem_t*);
44int sem_getvalue(sem_t*, int*);
45int sem_init(sem_t*, int, uint);
46sem_t* sem_open(const scope char*, int, ...);
47int sem_post(sem_t*);
48int sem_trywait(sem_t*);
49int sem_unlink(const scope char*);
50int sem_wait(sem_t*);
51*/
52
53version (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}
72else version (Darwin)
73{
74    alias int sem_t;
75
76    enum SEM_FAILED = cast(sem_t*) null;
77}
78else 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}
94else version (NetBSD)
95{
96    alias size_t sem_t;
97
98    enum SEM_FAILED = cast(sem_t*) null;
99}
100else version (OpenBSD)
101{
102    struct __sem;
103    alias sem_t = __sem*;
104
105    enum SEM_FAILED = cast(sem_t*) null;
106}
107else 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}
122else 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}
135else version (CRuntime_Bionic)
136{
137    struct sem_t
138    {
139        uint count; //volatile
140    }
141
142    enum SEM_FAILED = null;
143}
144else 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}
152else 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}
164else
165{
166    static assert(false, "Unsupported platform");
167}
168
169int sem_close(sem_t*);
170int sem_destroy(sem_t*);
171int sem_getvalue(sem_t*, int*);
172int sem_init(sem_t*, int, uint);
173sem_t* sem_open(const scope char*, int, ...);
174int sem_post(sem_t*);
175int sem_trywait(sem_t*);
176int sem_unlink(const scope char*);
177int sem_wait(sem_t*);
178
179//
180// Timeouts (TMO)
181//
182/*
183int sem_timedwait(sem_t*, const scope timespec*);
184*/
185
186version (CRuntime_Glibc)
187{
188    int sem_timedwait(sem_t*, const scope timespec*);
189}
190else version (Darwin)
191{
192    int sem_timedwait(sem_t*, const scope timespec*);
193}
194else version (FreeBSD)
195{
196    int sem_timedwait(sem_t*, const scope timespec*);
197}
198else version (NetBSD)
199{
200    int sem_timedwait(sem_t*, const scope timespec*);
201}
202else version (OpenBSD)
203{
204    int sem_timedwait(sem_t*, const scope timespec*);
205}
206else version (DragonFlyBSD)
207{
208    int sem_timedwait(sem_t*, const scope timespec*);
209}
210else version (Solaris)
211{
212    int sem_timedwait(sem_t*, const scope timespec*);
213}
214else version (CRuntime_Bionic)
215{
216    int sem_timedwait(sem_t*, const scope timespec*);
217}
218else version (CRuntime_Musl)
219{
220    int sem_timedwait(sem_t*, const scope timespec*);
221}
222else version (CRuntime_UClibc)
223{
224    int sem_timedwait(sem_t*, const scope timespec*);
225}
226else
227{
228    static assert(false, "Unsupported platform");
229}
230