arch/parisc/include/asm/bitops.h

Source file repositories/reference/linux-study-clean/arch/parisc/include/asm/bitops.h

File Facts

System
Linux kernel
Corpus path
arch/parisc/include/asm/bitops.h
Extension
.h
Size
5511 bytes
Lines
210
Domain
Architecture Layer
Bucket
arch/parisc
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

#ifndef _PARISC_BITOPS_H
#define _PARISC_BITOPS_H

#ifndef _LINUX_BITOPS_H
#error only <linux/bitops.h> can be included directly
#endif

#include <linux/compiler.h>
#include <asm/types.h>
#include <asm/byteorder.h>
#include <asm/barrier.h>
#include <linux/atomic.h>

/* See http://marc.theaimsgroup.com/?t=108826637900003 for discussion
 * on use of volatile and __*_bit() (set/clear/change):
 *	*_bit() want use of volatile.
 *	__*_bit() are "relaxed" and don't use spinlock or volatile.
 */

static __inline__ void set_bit(int nr, volatile unsigned long * addr)
{
	unsigned long mask = BIT_MASK(nr);
	unsigned long flags;

	addr += BIT_WORD(nr);
	_atomic_spin_lock_irqsave(addr, flags);
	*addr |= mask;
	_atomic_spin_unlock_irqrestore(addr, flags);
}

static __inline__ void clear_bit(int nr, volatile unsigned long * addr)
{
	unsigned long mask = BIT_MASK(nr);
	unsigned long flags;

	addr += BIT_WORD(nr);
	_atomic_spin_lock_irqsave(addr, flags);
	*addr &= ~mask;
	_atomic_spin_unlock_irqrestore(addr, flags);
}

static __inline__ void change_bit(int nr, volatile unsigned long * addr)
{
	unsigned long mask = BIT_MASK(nr);
	unsigned long flags;

	addr += BIT_WORD(nr);
	_atomic_spin_lock_irqsave(addr, flags);
	*addr ^= mask;
	_atomic_spin_unlock_irqrestore(addr, flags);
}

static __inline__ int test_and_set_bit(int nr, volatile unsigned long * addr)
{
	unsigned long mask = BIT_MASK(nr);
	unsigned long old;
	unsigned long flags;
	int set;

	addr += BIT_WORD(nr);
	_atomic_spin_lock_irqsave(addr, flags);
	old = *addr;
	set = (old & mask) ? 1 : 0;
	if (!set)
		*addr = old | mask;
	_atomic_spin_unlock_irqrestore(addr, flags);

	return set;
}

static __inline__ int test_and_clear_bit(int nr, volatile unsigned long * addr)
{
	unsigned long mask = BIT_MASK(nr);
	unsigned long old;
	unsigned long flags;
	int set;

	addr += BIT_WORD(nr);
	_atomic_spin_lock_irqsave(addr, flags);
	old = *addr;
	set = (old & mask) ? 1 : 0;
	if (set)
		*addr = old & ~mask;
	_atomic_spin_unlock_irqrestore(addr, flags);

	return set;
}

static __inline__ int test_and_change_bit(int nr, volatile unsigned long * addr)
{

Annotation

Implementation Notes