zrlock.c revision 260af64db74a52d64de8c6c5f67dd0a71d228ca5
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2014, 2015 by Delphix. All rights reserved.
* Copyright 2016 The MathWorks, Inc. All rights reserved.
*/
/*
* A Zero Reference Lock (ZRL) is a reference count that can lock out new
* references only when the count is zero and only without waiting if the count
* is not already zero. It is similar to a read-write lock in that it allows
* multiple readers and only a single writer, but it does not allow a writer to
* block while waiting for readers to exit, and therefore the question of
* rw_enter(&lock, RW_WRITER) is disallowed and only tryenter() is allowed, it
* is perfectly safe for the same reader to acquire the same lock multiple
* times. The fact that a ZRL is reentrant for readers (through multiple calls
* to zrl_add()) makes it convenient for determining whether something is
* actively referenced without the fuss of flagging lock ownership across
* function calls.
*/
/*
* A ZRL can be locked only while there are zero references, so ZRL_LOCKED is
* treated as zero references.
*/
#define ZRL_LOCKED -1
#define ZRL_DESTROYED -2
void
{
zrl->zr_refcount = 0;
#ifdef ZFS_DEBUG
#endif
}
void
{
}
void
{
for (;;) {
while (n != ZRL_LOCKED) {
if (cas == n) {
#ifdef ZFS_DEBUG
}
#endif
return;
}
n = cas;
}
}
}
}
void
{
uint32_t n;
#ifdef ZFS_DEBUG
}
#endif
}
int
{
if (n == 0) {
if (cas == 0) {
#ifdef ZFS_DEBUG
#endif
return (1);
}
}
return (0);
}
void
{
#ifdef ZFS_DEBUG
membar_producer(); /* make sure the owner store happens first */
#endif
zrl->zr_refcount = 0;
}
int
{
int n = (int)zrl->zr_refcount;
return (n <= 0 ? 0 : n);
}
int
{
return (zrl->zr_refcount <= 0);
}
int
{
}
#ifdef ZFS_DEBUG
{
}
#endif