1 .\" 2 .\" The contents of this file are subject to the terms of the 3 .\" Common Development and Distribution License (the "License"). 4 .\" You may not use this file except in compliance with the License. 5 .\" 6 .\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 7 .\" or http://www.opensolaris.org/os/licensing. 8 .\" See the License for the specific language governing permissions 9 .\" and limitations under the License. 10 .\" 11 .\" When distributing Covered Code, include this CDDL HEADER in each 12 .\" file and include the License file at usr/src/OPENSOLARIS.LICENSE. 13 .\" If applicable, add the following below this CDDL HEADER, with the 14 .\" fields enclosed by brackets "[]" replaced with your own identifying 15 .\" information: Portions Copyright [yyyy] [name of copyright owner] 16 .\" 17 .\" 18 .\" Copyright (c) 2006, Sun Microsystems, Inc. All Rights Reserved 19 .\" Copyright 2018 Nexenta Systems, Inc. 20 .\" 21 .Dd July 30, 2018 22 .Dt SEMAPHORE 9F 23 .Os 24 .Sh NAME 25 .Nm semaphore , 26 .Nm sema_init , 27 .Nm sema_destroy , 28 .Nm sema_p , 29 .Nm sema_p_sig , 30 .Nm sema_v , 31 .Nm sema_tryp 32 .Nd semaphore functions 33 .Sh SYNOPSIS 34 .In sys/ksynch.h 35 .Ft void 36 .Fo sema_init 37 .Fa "ksema_t *sp" 38 .Fa "uint_t val" 39 .Fa "char *name" 40 .Fa "ksema_type_t type" 41 .Fa "void *arg" 42 .Fc 43 .Ft void 44 .Fo sema_destroy 45 .Fa "ksema_t *sp" 46 .Fc 47 .Ft void 48 .Fo sema_p 49 .Fa "ksema_t *sp" 50 .Fc 51 .Ft void 52 .Fo sema_v 53 .Fa "ksema_t *sp" 54 .Fc 55 .Ft int 56 .Fo sema_p_sig 57 .Fa "ksema_t *sp" 58 .Fc 59 .Ft int 60 .Fo sema_tryp 61 .Fa "ksema_t *sp" 62 .Fc 63 .Sh INTERFACE LEVEL 64 illumos DDI specific (illumos DDI). 65 .Sh PARAMETERS 66 .Bl -tag -width Ds 67 .It Fa sp 68 A pointer to a semaphore, type 69 .Vt ksema_t . 70 .It Fa val 71 Initial value for semaphore. 72 .It Fa name 73 Descriptive string. 74 This is obsolete and should be 75 .Dv NULL . 76 .Po Non- Ns 77 .Dv NULL 78 strings are legal, but they are a waste of kernel memory. 79 .Pc 80 .It Fa type 81 Variant type of the semaphore. 82 Currently, only 83 .Dv SEMA_DRIVER 84 is supported. 85 .It Fa arg 86 Type-specific argument; should be 87 .Dv NULL . 88 .El 89 .Sh DESCRIPTION 90 These functions implement counting semaphores as described by Dijkstra. 91 A semaphore has a value which is atomically decremented by 92 .Fn sema_p 93 and atomically incremented by 94 .Fn sema_v . 95 The value must always be greater than or equal to zero. 96 If 97 .Fn sema_p 98 is called and the value is zero, the calling thread is blocked until another 99 thread performs a 100 .Fn sema_v 101 operation on the semaphore. 102 .Pp 103 Semaphores are initialized by calling 104 .Fn sema_init . 105 The argument, 106 .Fa val , 107 gives the initial value for the semaphore. 108 The semaphore storage is provided by the caller but more may be dynamically 109 allocated, if necessary, by 110 .Fn sema_init . 111 For this reason, 112 .Fn sema_destroy 113 should be called before deallocating the storage containing the semaphore. 114 .Pp 115 The 116 .Fn sema_p_sig 117 function decrements the semaphore, as does 118 .Fn sema_p . 119 However, if the semaphore value is zero, 120 .Fn sema_p_sig 121 will return without decrementing the value if a signal 122 .Po that is, from 123 .Xr kill 2 124 .Pc 125 is pending for the thread. 126 .Pp 127 The 128 .Fn sema_tryp 129 function will decrement the semaphore value only if it is greater than zero, and 130 will not block. 131 .Sh CONTEXT 132 These functions can be called from user, interrupt, or kernel context, except 133 for 134 .Fn sema_init 135 and 136 .Fn sema_destroy , 137 which can be called from user or kernel context only. 138 None of these functions can be called from a high-level interrupt context. 139 In most cases, 140 .Fn sema_v 141 and 142 .Fn sema_p 143 should not be called from any interrupt context. 144 .Pp 145 If 146 .Fn sema_p 147 is used from interrupt context, lower-priority interrupts will not be serviced 148 during the wait. 149 This means that if the thread that will eventually perform the 150 .Fn sema_v 151 becomes blocked on anything that requires the lower-priority interrupt, the 152 system will hang. 153 .Pp 154 For example, the thread that will perform the 155 .Fn sema_v 156 may need to first allocate memory. 157 This memory allocation may require waiting for paging I/O to complete, which may 158 require a lower-priority disk or network interrupt to be serviced. 159 In general, situations like this are hard to predict, so it is advisable to 160 avoid waiting on semaphores or condition variables in an interrupt context. 161 .Pp 162 Similar to many other synchronization mechanisms, semaphores should not be used 163 in any code path that requires synchronization while handling system panic, at 164 which time many of the semaphore operations become no-ops. 165 .Sh RETURN VALUES 166 .Bl -tag -width Ds 167 .It Li 0 168 .Fn sema_tryp 169 could not decrement the semaphore value because it was zero. 170 .It Li 1 171 .Fn sema_p_sig 172 was not able to decrement the semaphore value and detected a pending signal. 173 .El 174 .Sh SEE ALSO 175 .Xr kill 2 , 176 .Xr condvar 9F , 177 .Xr mutex 9F 178 .Pp 179 .Em Writing Device Drivers