1219820Sjeff/* 2219820Sjeff * Copyright (c) 2004, 2005 Voltaire, Inc. All rights reserved. 3219820Sjeff * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved. 4219820Sjeff * Copyright (c) 1996-2003 Intel Corporation. All rights reserved. 5219820Sjeff * 6219820Sjeff * This software is available to you under a choice of one of two 7219820Sjeff * licenses. You may choose to be licensed under the terms of the GNU 8219820Sjeff * General Public License (GPL) Version 2, available from the file 9219820Sjeff * COPYING in the main directory of this source tree, or the 10219820Sjeff * OpenIB.org BSD license below: 11219820Sjeff * 12219820Sjeff * Redistribution and use in source and binary forms, with or 13219820Sjeff * without modification, are permitted provided that the following 14219820Sjeff * conditions are met: 15219820Sjeff * 16219820Sjeff * - Redistributions of source code must retain the above 17219820Sjeff * copyright notice, this list of conditions and the following 18219820Sjeff * disclaimer. 19219820Sjeff * 20219820Sjeff * - Redistributions in binary form must reproduce the above 21219820Sjeff * copyright notice, this list of conditions and the following 22219820Sjeff * disclaimer in the documentation and/or other materials 23219820Sjeff * provided with the distribution. 24219820Sjeff * 25219820Sjeff * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26219820Sjeff * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27219820Sjeff * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28219820Sjeff * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 29219820Sjeff * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 30219820Sjeff * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 31219820Sjeff * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 32219820Sjeff * SOFTWARE. 33219820Sjeff * 34219820Sjeff */ 35219820Sjeff 36219820Sjeff/* 37219820Sjeff * Abstract: 38219820Sjeff * This file contains the passive lock, which synchronizes passive threads. 39219820Sjeff * The passive lock allows multiple readers to access a resource 40219820Sjeff * simultaneously, exclusive from a single thread allowed writing. 41219820Sjeff * Several writer threads are allowed - but only one can write at a given time 42219820Sjeff */ 43219820Sjeff 44219820Sjeff#ifndef _CL_PASSIVE_LOCK_H_ 45219820Sjeff#define _CL_PASSIVE_LOCK_H_ 46219820Sjeff#include <complib/cl_types.h> 47219820Sjeff#include <pthread.h> 48219820Sjeff 49219820Sjeff#ifdef __cplusplus 50219820Sjeff# define BEGIN_C_DECLS extern "C" { 51219820Sjeff# define END_C_DECLS } 52219820Sjeff#else /* !__cplusplus */ 53219820Sjeff# define BEGIN_C_DECLS 54219820Sjeff# define END_C_DECLS 55219820Sjeff#endif /* __cplusplus */ 56219820Sjeff 57219820SjeffBEGIN_C_DECLS 58219820Sjeff/****h* Component Library/Passive Lock 59219820Sjeff* NAME 60219820Sjeff* Passive Lock 61219820Sjeff* 62219820Sjeff* DESCRIPTION 63219820Sjeff* The Passive Lock provides synchronization between multiple threads that 64219820Sjeff* are sharing the lock with a single thread holding the lock exclusively. 65219820Sjeff* 66219820Sjeff* Passive lock works exclusively between threads and cannot be used in 67219820Sjeff* situations where the caller cannot be put into a waiting state. 68219820Sjeff* 69219820Sjeff* The passive lock functions operate a cl_plock_t structure which should 70219820Sjeff* be treated as opaque and should be manipulated only through the provided 71219820Sjeff* functions. 72219820Sjeff* 73219820Sjeff* SEE ALSO 74219820Sjeff* Structures: 75219820Sjeff* cl_plock_t 76219820Sjeff* 77219820Sjeff* Initialization: 78219820Sjeff* cl_plock_construct, cl_plock_init, cl_plock_destroy 79219820Sjeff* 80219820Sjeff* Manipulation 81219820Sjeff* cl_plock_acquire, cl_plock_excl_acquire, cl_plock_release 82219820Sjeff*********/ 83219820Sjeff/****s* Component Library: Passive Lock/cl_plock_t 84219820Sjeff* NAME 85219820Sjeff* cl_plock_t 86219820Sjeff* 87219820Sjeff* DESCRIPTION 88219820Sjeff* Passive Lock structure. 89219820Sjeff* 90219820Sjeff* The cl_plock_t structure should be treated as opaque and should 91219820Sjeff* be manipulated only through the provided functions. 92219820Sjeff* 93219820Sjeff* SYNOPSIS 94219820Sjeff*/ 95219820Sjefftypedef struct _cl_plock { 96219820Sjeff pthread_rwlock_t lock; 97219820Sjeff cl_state_t state; 98219820Sjeff} cl_plock_t; 99219820Sjeff/* 100219820Sjeff* FIELDS 101219820Sjeff* lock 102219820Sjeff* Pthread RWLOCK object 103219820Sjeff* 104219820Sjeff* state 105219820Sjeff* Records the current state of the lock, such as initialized, 106219820Sjeff* destroying, etc. 107219820Sjeff* 108219820Sjeff* SEE ALSO 109219820Sjeff* Passive Lock 110219820Sjeff*********/ 111219820Sjeff 112219820Sjeff/****f* Component Library: Passive Lock/cl_plock_construct 113219820Sjeff* NAME 114219820Sjeff* cl_plock_construct 115219820Sjeff* 116219820Sjeff* DESCRIPTION 117219820Sjeff* The cl_plock_construct function initializes the state of a 118219820Sjeff* passive lock. 119219820Sjeff* 120219820Sjeff* SYNOPSIS 121219820Sjeff*/ 122219820Sjeffstatic inline void cl_plock_construct(IN cl_plock_t * const p_lock) 123219820Sjeff{ 124219820Sjeff CL_ASSERT(p_lock); 125219820Sjeff 126219820Sjeff p_lock->state = CL_UNINITIALIZED; 127219820Sjeff} 128219820Sjeff 129219820Sjeff/* 130219820Sjeff* PARAMETERS 131219820Sjeff* p_lock 132219820Sjeff* [in] Pointer to a cl_plock_t structure whose state to initialize. 133219820Sjeff* 134219820Sjeff* RETURN VALUE 135219820Sjeff* This function does not return a value. 136219820Sjeff* 137219820Sjeff* NOTES 138219820Sjeff* Allows calling cl_plock_destroy without first calling cl_plock_init. 139219820Sjeff* 140219820Sjeff* Calling cl_plock_construct is a prerequisite to calling any other 141219820Sjeff* passive lock function except cl_plock_init. 142219820Sjeff* 143219820Sjeff* SEE ALSO 144219820Sjeff* Passive Lock, cl_plock_init, cl_plock_destroy 145219820Sjeff*********/ 146219820Sjeff 147219820Sjeff/****f* Component Library: Passive Lock/cl_plock_destroy 148219820Sjeff* NAME 149219820Sjeff* cl_plock_destroy 150219820Sjeff* 151219820Sjeff* DESCRIPTION 152219820Sjeff* The cl_plock_destroy function performs any necessary cleanup 153219820Sjeff* of a passive lock. 154219820Sjeff* 155219820Sjeff* SYNOPSIS 156219820Sjeff*/ 157219820Sjeffstatic inline void cl_plock_destroy(IN cl_plock_t * const p_lock) 158219820Sjeff{ 159219820Sjeff CL_ASSERT(p_lock); 160219820Sjeff p_lock->state = CL_DESTROYING; 161219820Sjeff pthread_rwlock_destroy(&p_lock->lock); 162219820Sjeff p_lock->state = CL_DESTROYED; 163219820Sjeff} 164219820Sjeff 165219820Sjeff/* 166219820Sjeff* PARAMETERS 167219820Sjeff* p_lock 168219820Sjeff* [in] Pointer to a cl_plock_t structure whose state to initialize. 169219820Sjeff* 170219820Sjeff* RETURN VALUE 171219820Sjeff* This function does not return a value. 172219820Sjeff* 173219820Sjeff* NOTES 174219820Sjeff* cl_plock_destroy performs any necessary cleanup of the specified 175219820Sjeff* passive lock. 176219820Sjeff* 177219820Sjeff* This function must only be called if cl_plock_construct or 178219820Sjeff* cl_plock_init has been called. The passive lock must not be held 179219820Sjeff* when calling this function. 180219820Sjeff* 181219820Sjeff* SEE ALSO 182219820Sjeff* Passive Lock, cl_plock_construct, cl_plock_init 183219820Sjeff*********/ 184219820Sjeff 185219820Sjeff/****f* Component Library: Passive Lock/cl_plock_init 186219820Sjeff* NAME 187219820Sjeff* cl_plock_init 188219820Sjeff* 189219820Sjeff* DESCRIPTION 190219820Sjeff* The cl_plock_init function initializes a passive lock. 191219820Sjeff* 192219820Sjeff* SYNOPSIS 193219820Sjeff*/ 194219820Sjeffstatic inline cl_status_t cl_plock_init(IN cl_plock_t * const p_lock) 195219820Sjeff{ 196219820Sjeff cl_status_t status; 197219820Sjeff 198219820Sjeff CL_ASSERT(p_lock); 199219820Sjeff status = (cl_status_t) pthread_rwlock_init(&p_lock->lock, NULL); 200219820Sjeff if (status) 201219820Sjeff return CL_ERROR; 202219820Sjeff p_lock->state = CL_INITIALIZED; 203219820Sjeff return (CL_SUCCESS); 204219820Sjeff} 205219820Sjeff 206219820Sjeff/* 207219820Sjeff* PARAMETERS 208219820Sjeff* p_lock 209219820Sjeff* [in] Pointer to a cl_plock_t structure to initialize. 210219820Sjeff* 211219820Sjeff* RETURN VALUES 212219820Sjeff* CL_SUCCESS if the passive lock was initialized successfully. 213219820Sjeff* 214219820Sjeff* CL_ERROR otherwise. 215219820Sjeff* 216219820Sjeff* NOTES 217219820Sjeff* Allows calling cl_plock_acquire, cl_plock_release, 218219820Sjeff* cl_plock_excl_acquire 219219820Sjeff* 220219820Sjeff* SEE ALSO 221219820Sjeff* Passive Lock, cl_plock_construct, cl_plock_destroy, 222219820Sjeff* cl_plock_excl_acquire, cl_plock_acquire, cl_plock_release 223219820Sjeff*********/ 224219820Sjeff 225219820Sjeff/****f* Component Library: Passive Lock/cl_plock_acquire 226219820Sjeff* NAME 227219820Sjeff* cl_plock_acquire 228219820Sjeff* 229219820Sjeff* DESCRIPTION 230219820Sjeff* The cl_plock_acquire function acquires a passive lock for 231219820Sjeff* shared access. 232219820Sjeff* 233219820Sjeff* SYNOPSIS 234219820Sjeff*/ 235219820Sjeffstatic inline void cl_plock_acquire(IN cl_plock_t * const p_lock) 236219820Sjeff{ 237219820Sjeff cl_status_t status; 238219820Sjeff CL_ASSERT(p_lock); 239219820Sjeff CL_ASSERT(p_lock->state == CL_INITIALIZED); 240219820Sjeff 241219820Sjeff status = (cl_status_t) pthread_rwlock_rdlock(&p_lock->lock); 242219820Sjeff CL_ASSERT(status == 0); 243219820Sjeff} 244219820Sjeff 245219820Sjeff/* 246219820Sjeff* PARAMETERS 247219820Sjeff* p_lock 248219820Sjeff* [in] Pointer to a cl_plock_t structure to acquire. 249219820Sjeff* 250219820Sjeff* RETURN VALUE 251219820Sjeff* This function does not return a value. 252219820Sjeff* 253219820Sjeff* SEE ALSO 254219820Sjeff* Passive Lock, cl_plock_release, cl_plock_excl_acquire 255219820Sjeff*********/ 256219820Sjeff 257219820Sjeff/****f* Component Library: Passive Lock/cl_plock_excl_acquire 258219820Sjeff* NAME 259219820Sjeff* cl_plock_excl_acquire 260219820Sjeff* 261219820Sjeff* DESCRIPTION 262219820Sjeff* The cl_plock_excl_acquire function acquires exclusive access 263219820Sjeff* to a passive lock. 264219820Sjeff* 265219820Sjeff* SYNOPSIS 266219820Sjeff*/ 267219820Sjeffstatic inline void cl_plock_excl_acquire(IN cl_plock_t * const p_lock) 268219820Sjeff{ 269219820Sjeff cl_status_t status; 270219820Sjeff 271219820Sjeff CL_ASSERT(p_lock); 272219820Sjeff CL_ASSERT(p_lock->state == CL_INITIALIZED); 273219820Sjeff 274219820Sjeff status = (cl_status_t) pthread_rwlock_wrlock(&p_lock->lock); 275219820Sjeff CL_ASSERT(status == 0); 276219820Sjeff} 277219820Sjeff 278219820Sjeff/* 279219820Sjeff* PARAMETERS 280219820Sjeff* p_lock 281219820Sjeff* [in] Pointer to a cl_plock_t structure to acquire exclusively. 282219820Sjeff* 283219820Sjeff* RETURN VALUE 284219820Sjeff* This function does not return a value. 285219820Sjeff* 286219820Sjeff* SEE ALSO 287219820Sjeff* Passive Lock, cl_plock_release, cl_plock_acquire 288219820Sjeff*********/ 289219820Sjeff 290219820Sjeff/****f* Component Library: Passive Lock/cl_plock_release 291219820Sjeff* NAME 292219820Sjeff* cl_plock_release 293219820Sjeff* 294219820Sjeff* DESCRIPTION 295219820Sjeff* The cl_plock_release function releases a passive lock from 296219820Sjeff* shared or exclusive access. 297219820Sjeff* 298219820Sjeff* SYNOPSIS 299219820Sjeff*/ 300219820Sjeffstatic inline void cl_plock_release(IN cl_plock_t * const p_lock) 301219820Sjeff{ 302219820Sjeff cl_status_t status; 303219820Sjeff CL_ASSERT(p_lock); 304219820Sjeff CL_ASSERT(p_lock->state == CL_INITIALIZED); 305219820Sjeff 306219820Sjeff status = (cl_status_t) pthread_rwlock_unlock(&p_lock->lock); 307219820Sjeff CL_ASSERT(status == 0); 308219820Sjeff} 309219820Sjeff 310219820Sjeff/* 311219820Sjeff* PARAMETERS 312219820Sjeff* p_lock 313219820Sjeff* [in] Pointer to a cl_plock_t structure to release. 314219820Sjeff* 315219820Sjeff* RETURN VALUE 316219820Sjeff* This function does not return a value. 317219820Sjeff* 318219820Sjeff* SEE ALSO 319219820Sjeff* Passive Lock, cl_plock_acquire, cl_plock_excl_acquire 320219820Sjeff*********/ 321219820Sjeff 322219820SjeffEND_C_DECLS 323219820Sjeff#endif /* _CL_PASSIVE_LOCK_H_ */ 324