[BACK]Return to dec_and_lock.c CVS log [TXT][DIR] Up to [Development] / linux-2.6-xfs / arch / ia64 / lib

File: [Development] / linux-2.6-xfs / arch / ia64 / lib / Attic / dec_and_lock.c (download)

Revision 1.2, Wed Jan 5 14:17:31 2005 UTC (12 years, 9 months ago) by nathans.longdrop.melbourne.sgi.com
Branch: MAIN
Changes since 1.1: +2 -2 lines

Merge up to 2.6.10.
Merge of 2.6.x-xfs-melb:linux:21010a by kenmcd.

/*
 * Copyright (C) 2003 Jerome Marchand, Bull S.A.
 *	Cleaned up by David Mosberger-Tang <davidm@hpl.hp.com>
 *
 * This file is released under the GPLv2, or at your option any later version.
 *
 * ia64 version of "atomic_dec_and_lock()" using the atomic "cmpxchg" instruction.  This
 * code is an adaptation of the x86 version of "atomic_dec_and_lock()".
 */

#include <linux/compiler.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <asm/atomic.h>

/*
 * Decrement REFCOUNT and if the count reaches zero, acquire the spinlock.  Both of these
 * operations have to be done atomically, so that the count doesn't drop to zero without
 * acquiring the spinlock first.
 */
int
_atomic_dec_and_lock (atomic_t *refcount, spinlock_t *lock)
{
	int old, new;

	do {
		old = atomic_read(refcount);
		new = old - 1;

		if (unlikely (old == 1)) {
			/* oops, we may be decrementing to zero, do it the slow way... */
			spin_lock(lock);
			if (atomic_dec_and_test(refcount))
				return 1;
			spin_unlock(lock);
			return 0;
		}
	} while (cmpxchg(&refcount->counter, old, new) != old);
	return 0;
}

EXPORT_SYMBOL(_atomic_dec_and_lock);