1/* 2 * Copyright (c) 2004, 2005 Voltaire, Inc. All rights reserved. 3 * Copyright (c) 2002-2005 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 57BEGIN_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*/ 95typedef 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*/ 122static 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*/ 157static 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*/ 194static 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 = (cl_status_t) 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*/ 235static inline void cl_plock_acquire(IN cl_plock_t * const p_lock) 236{ 237 cl_status_t status; 238 CL_ASSERT(p_lock); 239 CL_ASSERT(p_lock->state == CL_INITIALIZED); 240 241 status = (cl_status_t) 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*/ 267static inline void cl_plock_excl_acquire(IN cl_plock_t * const p_lock) 268{ 269 cl_status_t status; 270 271 CL_ASSERT(p_lock); 272 CL_ASSERT(p_lock->state == CL_INITIALIZED); 273 274 status = (cl_status_t) 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*/ 300static inline void cl_plock_release(IN cl_plock_t * const p_lock) 301{ 302 cl_status_t status; 303 CL_ASSERT(p_lock); 304 CL_ASSERT(p_lock->state == CL_INITIALIZED); 305 306 status = (cl_status_t) 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 322END_C_DECLS 323#endif /* _CL_PASSIVE_LOCK_H_ */ 324