1 /* 2 * Copyright (c) 2004, 2005 Voltaire, Inc. All rights reserved. 3 * Copyright (c) 2002-2010 Mellanox Technologies LTD. All rights reserved. 4 * Copyright (c) 1996-2003 Intel Corporation. All rights reserved. 5 * 6 * This software is available to you under a choice of one of two 7 * licenses. You may choose to be licensed under the terms of the GNU 8 * General Public License (GPL) Version 2, available from the file 9 * COPYING in the main directory of this source tree, or the 10 * OpenIB.org BSD license below: 11 * 12 * Redistribution and use in source and binary forms, with or 13 * without modification, are permitted provided that the following 14 * conditions are met: 15 * 16 * - Redistributions of source code must retain the above 17 * copyright notice, this list of conditions and the following 18 * disclaimer. 19 * 20 * - Redistributions in binary form must reproduce the above 21 * copyright notice, this list of conditions and the following 22 * disclaimer in the documentation and/or other materials 23 * provided with the distribution. 24 * 25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 29 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 30 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 32 * SOFTWARE. 33 * 34 */ 35 36 /* 37 * Abstract: 38 * This file contains the passive lock, which synchronizes passive threads. 39 * The passive lock allows multiple readers to access a resource 40 * simultaneously, exclusive from a single thread allowed writing. 41 * Several writer threads are allowed - but only one can write at a given time 42 */ 43 44 #ifndef _CL_PASSIVE_LOCK_H_ 45 #define _CL_PASSIVE_LOCK_H_ 46 #include <complib/cl_types.h> 47 #include <pthread.h> 48 49 #ifdef __cplusplus 50 # define BEGIN_C_DECLS extern "C" { 51 # define END_C_DECLS } 52 #else /* !__cplusplus */ 53 # define BEGIN_C_DECLS 54 # define END_C_DECLS 55 #endif /* __cplusplus */ 56 57 BEGIN_C_DECLS 58 /****h* Component Library/Passive Lock 59 * NAME 60 * Passive Lock 61 * 62 * DESCRIPTION 63 * The Passive Lock provides synchronization between multiple threads that 64 * are sharing the lock with a single thread holding the lock exclusively. 65 * 66 * Passive lock works exclusively between threads and cannot be used in 67 * situations where the caller cannot be put into a waiting state. 68 * 69 * The passive lock functions operate a cl_plock_t structure which should 70 * be treated as opaque and should be manipulated only through the provided 71 * functions. 72 * 73 * SEE ALSO 74 * Structures: 75 * cl_plock_t 76 * 77 * Initialization: 78 * cl_plock_construct, cl_plock_init, cl_plock_destroy 79 * 80 * Manipulation 81 * cl_plock_acquire, cl_plock_excl_acquire, cl_plock_release 82 *********/ 83 /****s* Component Library: Passive Lock/cl_plock_t 84 * NAME 85 * cl_plock_t 86 * 87 * DESCRIPTION 88 * Passive Lock structure. 89 * 90 * The cl_plock_t structure should be treated as opaque and should 91 * be manipulated only through the provided functions. 92 * 93 * SYNOPSIS 94 */ 95 typedef struct _cl_plock { 96 pthread_rwlock_t lock; 97 cl_state_t state; 98 } cl_plock_t; 99 /* 100 * FIELDS 101 * lock 102 * Pthread RWLOCK object 103 * 104 * state 105 * Records the current state of the lock, such as initialized, 106 * destroying, etc. 107 * 108 * SEE ALSO 109 * Passive Lock 110 *********/ 111 112 /****f* Component Library: Passive Lock/cl_plock_construct 113 * NAME 114 * cl_plock_construct 115 * 116 * DESCRIPTION 117 * The cl_plock_construct function initializes the state of a 118 * passive lock. 119 * 120 * SYNOPSIS 121 */ 122 static inline void cl_plock_construct(IN cl_plock_t * const p_lock) 123 { 124 CL_ASSERT(p_lock); 125 126 p_lock->state = CL_UNINITIALIZED; 127 } 128 129 /* 130 * PARAMETERS 131 * p_lock 132 * [in] Pointer to a cl_plock_t structure whose state to initialize. 133 * 134 * RETURN VALUE 135 * This function does not return a value. 136 * 137 * NOTES 138 * Allows calling cl_plock_destroy without first calling cl_plock_init. 139 * 140 * Calling cl_plock_construct is a prerequisite to calling any other 141 * passive lock function except cl_plock_init. 142 * 143 * SEE ALSO 144 * Passive Lock, cl_plock_init, cl_plock_destroy 145 *********/ 146 147 /****f* Component Library: Passive Lock/cl_plock_destroy 148 * NAME 149 * cl_plock_destroy 150 * 151 * DESCRIPTION 152 * The cl_plock_destroy function performs any necessary cleanup 153 * of a passive lock. 154 * 155 * SYNOPSIS 156 */ 157 static inline void cl_plock_destroy(IN cl_plock_t * const p_lock) 158 { 159 CL_ASSERT(p_lock); 160 p_lock->state = CL_DESTROYING; 161 pthread_rwlock_destroy(&p_lock->lock); 162 p_lock->state = CL_DESTROYED; 163 } 164 165 /* 166 * PARAMETERS 167 * p_lock 168 * [in] Pointer to a cl_plock_t structure whose state to initialize. 169 * 170 * RETURN VALUE 171 * This function does not return a value. 172 * 173 * NOTES 174 * cl_plock_destroy performs any necessary cleanup of the specified 175 * passive lock. 176 * 177 * This function must only be called if cl_plock_construct or 178 * cl_plock_init has been called. The passive lock must not be held 179 * when calling this function. 180 * 181 * SEE ALSO 182 * Passive Lock, cl_plock_construct, cl_plock_init 183 *********/ 184 185 /****f* Component Library: Passive Lock/cl_plock_init 186 * NAME 187 * cl_plock_init 188 * 189 * DESCRIPTION 190 * The cl_plock_init function initializes a passive lock. 191 * 192 * SYNOPSIS 193 */ 194 static inline cl_status_t cl_plock_init(IN cl_plock_t * const p_lock) 195 { 196 cl_status_t status; 197 198 CL_ASSERT(p_lock); 199 status = pthread_rwlock_init(&p_lock->lock, NULL); 200 if (status) 201 return CL_ERROR; 202 p_lock->state = CL_INITIALIZED; 203 return (CL_SUCCESS); 204 } 205 206 /* 207 * PARAMETERS 208 * p_lock 209 * [in] Pointer to a cl_plock_t structure to initialize. 210 * 211 * RETURN VALUES 212 * CL_SUCCESS if the passive lock was initialized successfully. 213 * 214 * CL_ERROR otherwise. 215 * 216 * NOTES 217 * Allows calling cl_plock_acquire, cl_plock_release, 218 * cl_plock_excl_acquire 219 * 220 * SEE ALSO 221 * Passive Lock, cl_plock_construct, cl_plock_destroy, 222 * cl_plock_excl_acquire, cl_plock_acquire, cl_plock_release 223 *********/ 224 225 /****f* Component Library: Passive Lock/cl_plock_acquire 226 * NAME 227 * cl_plock_acquire 228 * 229 * DESCRIPTION 230 * The cl_plock_acquire function acquires a passive lock for 231 * shared access. 232 * 233 * SYNOPSIS 234 */ 235 static inline void cl_plock_acquire(IN cl_plock_t * const p_lock) 236 { 237 cl_status_t __attribute__((unused)) status; 238 CL_ASSERT(p_lock); 239 CL_ASSERT(p_lock->state == CL_INITIALIZED); 240 241 status = pthread_rwlock_rdlock(&p_lock->lock); 242 CL_ASSERT(status == 0); 243 } 244 245 /* 246 * PARAMETERS 247 * p_lock 248 * [in] Pointer to a cl_plock_t structure to acquire. 249 * 250 * RETURN VALUE 251 * This function does not return a value. 252 * 253 * SEE ALSO 254 * Passive Lock, cl_plock_release, cl_plock_excl_acquire 255 *********/ 256 257 /****f* Component Library: Passive Lock/cl_plock_excl_acquire 258 * NAME 259 * cl_plock_excl_acquire 260 * 261 * DESCRIPTION 262 * The cl_plock_excl_acquire function acquires exclusive access 263 * to a passive lock. 264 * 265 * SYNOPSIS 266 */ 267 static inline void cl_plock_excl_acquire(IN cl_plock_t * const p_lock) 268 { 269 cl_status_t __attribute__((unused)) status; 270 271 CL_ASSERT(p_lock); 272 CL_ASSERT(p_lock->state == CL_INITIALIZED); 273 274 status = pthread_rwlock_wrlock(&p_lock->lock); 275 CL_ASSERT(status == 0); 276 } 277 278 /* 279 * PARAMETERS 280 * p_lock 281 * [in] Pointer to a cl_plock_t structure to acquire exclusively. 282 * 283 * RETURN VALUE 284 * This function does not return a value. 285 * 286 * SEE ALSO 287 * Passive Lock, cl_plock_release, cl_plock_acquire 288 *********/ 289 290 /****f* Component Library: Passive Lock/cl_plock_release 291 * NAME 292 * cl_plock_release 293 * 294 * DESCRIPTION 295 * The cl_plock_release function releases a passive lock from 296 * shared or exclusive access. 297 * 298 * SYNOPSIS 299 */ 300 static inline void cl_plock_release(IN cl_plock_t * const p_lock) 301 { 302 cl_status_t __attribute__((unused)) status; 303 CL_ASSERT(p_lock); 304 CL_ASSERT(p_lock->state == CL_INITIALIZED); 305 306 status = pthread_rwlock_unlock(&p_lock->lock); 307 CL_ASSERT(status == 0); 308 } 309 310 /* 311 * PARAMETERS 312 * p_lock 313 * [in] Pointer to a cl_plock_t structure to release. 314 * 315 * RETURN VALUE 316 * This function does not return a value. 317 * 318 * SEE ALSO 319 * Passive Lock, cl_plock_acquire, cl_plock_excl_acquire 320 *********/ 321 322 END_C_DECLS 323 #endif /* _CL_PASSIVE_LOCK_H_ */ 324