cl_passivelock.h revision 329564
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
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 = 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 __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*/
267static 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*/
300static 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
322END_C_DECLS
323#endif				/* _CL_PASSIVE_LOCK_H_ */
324