⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rcuref.h

📁 Axis 221 camera embedded programing interface
💻 H
字号:
/* * rcuref.h * * Reference counting for elements of lists/arrays protected by * RCU. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Copyright (C) IBM Corporation, 2005 * * Author: Dipankar Sarma <dipankar@in.ibm.com> *	   Ravikiran Thirumalai <kiran_th@gmail.com> * * See Documentation/RCU/rcuref.txt for detailed user guide. * */#ifndef _RCUREF_H_#define _RCUREF_H_#ifdef __KERNEL__#include <linux/types.h>#include <linux/interrupt.h>#include <linux/spinlock.h>#include <asm/atomic.h>/* * These APIs work on traditional atomic_t counters used in the * kernel for reference counting. Under special circumstances * where a lock-free get() operation races with a put() operation * these APIs can be used. See Documentation/RCU/rcuref.txt. */#ifdef __HAVE_ARCH_CMPXCHG/** * rcuref_inc - increment refcount for object. * @rcuref: reference counter in the object in question. * * This should be used only for objects where we use RCU and * use the rcuref_inc_lf() api to acquire a reference * in a lock-free reader-side critical section. */static inline void rcuref_inc(atomic_t *rcuref){	atomic_inc(rcuref);}/** * rcuref_dec - decrement refcount for object. * @rcuref: reference counter in the object in question. * * This should be used only for objects where we use RCU and * use the rcuref_inc_lf() api to acquire a reference * in a lock-free reader-side critical section. */static inline void rcuref_dec(atomic_t *rcuref){	atomic_dec(rcuref);}/** * rcuref_dec_and_test - decrement refcount for object and test * @rcuref: reference counter in the object. * @release: pointer to the function that will clean up the object *	     when the last reference to the object is released. *	     This pointer is required. * * Decrement the refcount, and if 0, return 1. Else return 0. * * This should be used only for objects where we use RCU and * use the rcuref_inc_lf() api to acquire a reference * in a lock-free reader-side critical section. */static inline int rcuref_dec_and_test(atomic_t *rcuref){	return atomic_dec_and_test(rcuref);}/* * cmpxchg is needed on UP too, if deletions to the list/array can happen * in interrupt context. *//** * rcuref_inc_lf - Take reference to an object in a read-side * critical section protected by RCU. * @rcuref: reference counter in the object in question. * * Try and increment the refcount by 1.  The increment might fail if * the reference counter has been through a 1 to 0 transition and * is no longer part of the lock-free list. * Returns non-zero on successful increment and zero otherwise. */static inline int rcuref_inc_lf(atomic_t *rcuref){	int c, old;	c = atomic_read(rcuref);	while (c && (old = cmpxchg(&rcuref->counter, c, c + 1)) != c)		c = old;	return c;}#else				/* !__HAVE_ARCH_CMPXCHG */extern spinlock_t __rcuref_hash[];/* * Use a hash table of locks to protect the reference count * since cmpxchg is not available in this arch. */#ifdef	CONFIG_SMP#define RCUREF_HASH_SIZE	4#define RCUREF_HASH(k) \	(&__rcuref_hash[(((unsigned long)k)>>8) & (RCUREF_HASH_SIZE-1)])#else#define	RCUREF_HASH_SIZE	1#define RCUREF_HASH(k) 	&__rcuref_hash[0]#endif				/* CONFIG_SMP *//** * rcuref_inc - increment refcount for object. * @rcuref: reference counter in the object in question. * * This should be used only for objects where we use RCU and * use the rcuref_inc_lf() api to acquire a reference in a lock-free * reader-side critical section. */static inline void rcuref_inc(atomic_t *rcuref){	unsigned long flags;	spin_lock_irqsave(RCUREF_HASH(rcuref), flags);	rcuref->counter += 1;	spin_unlock_irqrestore(RCUREF_HASH(rcuref), flags);}/** * rcuref_dec - decrement refcount for object. * @rcuref: reference counter in the object in question. * * This should be used only for objects where we use RCU and * use the rcuref_inc_lf() api to acquire a reference in a lock-free * reader-side critical section. */static inline void rcuref_dec(atomic_t *rcuref){	unsigned long flags;	spin_lock_irqsave(RCUREF_HASH(rcuref), flags);	rcuref->counter -= 1;	spin_unlock_irqrestore(RCUREF_HASH(rcuref), flags);}/** * rcuref_dec_and_test - decrement refcount for object and test * @rcuref: reference counter in the object. * @release: pointer to the function that will clean up the object *	     when the last reference to the object is released. *	     This pointer is required. * * Decrement the refcount, and if 0, return 1. Else return 0. * * This should be used only for objects where we use RCU and * use the rcuref_inc_lf() api to acquire a reference in a lock-free * reader-side critical section. */static inline int rcuref_dec_and_test(atomic_t *rcuref){	unsigned long flags;	spin_lock_irqsave(RCUREF_HASH(rcuref), flags);	rcuref->counter--;	if (!rcuref->counter) {		spin_unlock_irqrestore(RCUREF_HASH(rcuref), flags);		return 1;	} else {		spin_unlock_irqrestore(RCUREF_HASH(rcuref), flags);		return 0;	}}/** * rcuref_inc_lf - Take reference to an object of a lock-free collection * by traversing a lock-free list/array. * @rcuref: reference counter in the object in question. * * Try and increment the refcount by 1.  The increment might fail if * the reference counter has been through a 1 to 0 transition and * object is no longer part of the lock-free list. * Returns non-zero on successful increment and zero otherwise. */static inline int rcuref_inc_lf(atomic_t *rcuref){	int ret;	unsigned long flags;	spin_lock_irqsave(RCUREF_HASH(rcuref), flags);	if (rcuref->counter)		ret = rcuref->counter++;	else		ret = 0;	spin_unlock_irqrestore(RCUREF_HASH(rcuref), flags);	return ret;}#endif /* !__HAVE_ARCH_CMPXCHG */#endif /* __KERNEL__ */#endif /* _RCUREF_H_ */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -