]>
Commit | Line | Data |
---|---|---|
0ab74447 A |
1 | .\" Copyright (c) 2008-2009 Apple Inc. All rights reserved. |
2 | .Dd May 1, 2009 | |
3 | .Dt dispatch_semaphore_create 3 | |
4 | .Os Darwin | |
5 | .Sh NAME | |
6 | .Nm dispatch_semaphore_create , | |
7 | .Nm dispatch_semaphore_signal , | |
8 | .Nm dispatch_semaphore_wait | |
9 | .Nd synchronized counting semaphore | |
10 | .Sh SYNOPSIS | |
11 | .Fd #include <dispatch/dispatch.h> | |
12 | .Ft dispatch_semaphore_t | |
13 | .Fo dispatch_semaphore_create | |
14 | .Fa "long count" | |
15 | .Fc | |
16 | .Ft long | |
17 | .Fo dispatch_semaphore_signal | |
18 | .Fa "dispatch_semaphore_t semaphore" | |
19 | .Fc | |
20 | .Ft long | |
21 | .Fo dispatch_semaphore_wait | |
22 | .Fa "dispatch_semaphore_t semaphore" "dispatch_time_t timeout" | |
23 | .Fc | |
24 | .Sh DESCRIPTION | |
25 | Dispatch semaphores are used to synchronize threads. | |
26 | The | |
27 | .Fa timeout | |
28 | parameter is creatable with the | |
29 | .Xr dispatch_time 3 | |
30 | or | |
31 | .Xr dispatch_walltime 3 | |
32 | functions. | |
33 | .Sh COMPLETION SYNCHRONIZATION | |
34 | If the | |
35 | .Fa count | |
36 | parameter is equal to zero, then the semaphore is useful for synchronizing completion of work. | |
37 | For example: | |
38 | .Bd -literal -offset indent | |
39 | sema = dispatch_semaphore_create(0); | |
40 | ||
41 | dispatch_async(queue, ^{ | |
42 | foo(); | |
43 | dispatch_semaphore_signal(sema); | |
44 | }); | |
45 | ||
46 | bar(); | |
47 | ||
48 | dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); | |
49 | .Ed | |
50 | .Sh FINITE RESOURCE POOL | |
51 | If the | |
52 | .Fa count | |
53 | parameter is greater than zero, then the semaphore is useful for managing a finite pool of resources. | |
54 | For example, a library that wants to limit Unix descriptor usage: | |
55 | .Bd -literal -offset indent | |
56 | sema = dispatch_semaphore_create(getdtablesize() / 4); | |
57 | .Ed | |
58 | .Pp | |
59 | At each Unix FD allocation: | |
60 | .Bd -literal -offset indent | |
61 | dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); | |
62 | fd = open("/etc/services", O_RDONLY); | |
63 | .Ed | |
64 | .Pp | |
65 | When each FD is closed: | |
66 | .Bd -literal -offset indent | |
67 | close(fd); | |
68 | dispatch_semaphore_signal(sema); | |
69 | .Ed | |
70 | .Sh RETURN VALUES | |
71 | The | |
72 | .Fn dispatch_semaphore_create | |
73 | function returns NULL if no memory is available or if the | |
74 | .Fa count | |
75 | parameter is less than zero. | |
76 | .Pp | |
77 | The | |
78 | .Fn dispatch_semaphore_signal | |
79 | function returns non-zero when a thread is woken. | |
80 | Otherwise, zero is returned. | |
81 | .Pp | |
82 | The | |
83 | .Fn dispatch_semaphore_wait | |
84 | function returns zero upon success and non-zero after the timeout expires. If the timeout is DISPATCH_TIME_FOREVER, then | |
85 | .Fn dispatch_semaphore_wait | |
86 | waits forever and always returns zero. | |
87 | .Sh MEMORY MODEL | |
88 | Dispatch semaphores are retained and released via calls to | |
89 | .Fn dispatch_retain | |
90 | and | |
91 | .Fn dispatch_release . | |
92 | .Sh CAVEATS | |
93 | Dispatch semaphores are strict counting semaphores. | |
94 | In other words, dispatch semaphores do not saturate at any particular value. | |
95 | Saturation can be achieved through atomic compare-and-swap logic. | |
96 | What follows is a saturating binary semaphore: | |
97 | .Bd -literal | |
98 | void | |
99 | saturating_semaphore_signal(dispatch_semaphore_t dsema, int *sent) | |
100 | { | |
101 | if (__sync_bool_compare_and_swap(sent, 0, 1)) { | |
102 | dispatch_semaphore_signal(dsema); | |
103 | } | |
104 | } | |
105 | ||
106 | void | |
107 | saturating_semaphore_wait(dispatch_semaphore_t dsema, int *sent) | |
108 | { | |
109 | *sent = 0; | |
110 | dispatch_semaphore_wait(dsema, DISPATCH_TIME_FOREVER); | |
111 | } | |
112 | .Ed | |
113 | .Sh SEE ALSO | |
114 | .Xr dispatch_object 3 |