Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.12-rc3 99 lines 2.8 kB view raw
1/* 2 * Copyright 2011 Tilera Corporation. All Rights Reserved. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation, version 2. 7 * 8 * This program is distributed in the hope that it will be useful, but 9 * WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 11 * NON INFRINGEMENT. See the GNU General Public License for 12 * more details. 13 */ 14 15#ifndef _ASM_TILE_BITOPS_64_H 16#define _ASM_TILE_BITOPS_64_H 17 18#include <linux/compiler.h> 19#include <asm/cmpxchg.h> 20 21/* See <asm/bitops.h> for API comments. */ 22 23static inline void set_bit(unsigned nr, volatile unsigned long *addr) 24{ 25 unsigned long mask = (1UL << (nr % BITS_PER_LONG)); 26 __insn_fetchor((void *)(addr + nr / BITS_PER_LONG), mask); 27} 28 29static inline void clear_bit(unsigned nr, volatile unsigned long *addr) 30{ 31 unsigned long mask = (1UL << (nr % BITS_PER_LONG)); 32 __insn_fetchand((void *)(addr + nr / BITS_PER_LONG), ~mask); 33} 34 35#define smp_mb__before_clear_bit() smp_mb() 36#define smp_mb__after_clear_bit() smp_mb() 37 38 39static inline void change_bit(unsigned nr, volatile unsigned long *addr) 40{ 41 unsigned long mask = (1UL << (nr % BITS_PER_LONG)); 42 unsigned long guess, oldval; 43 addr += nr / BITS_PER_LONG; 44 oldval = *addr; 45 do { 46 guess = oldval; 47 oldval = cmpxchg(addr, guess, guess ^ mask); 48 } while (guess != oldval); 49} 50 51 52/* 53 * The test_and_xxx_bit() routines require a memory fence before we 54 * start the operation, and after the operation completes. We use 55 * smp_mb() before, and rely on the "!= 0" comparison, plus a compiler 56 * barrier(), to block until the atomic op is complete. 57 */ 58 59static inline int test_and_set_bit(unsigned nr, volatile unsigned long *addr) 60{ 61 int val; 62 unsigned long mask = (1UL << (nr % BITS_PER_LONG)); 63 smp_mb(); /* barrier for proper semantics */ 64 val = (__insn_fetchor((void *)(addr + nr / BITS_PER_LONG), mask) 65 & mask) != 0; 66 barrier(); 67 return val; 68} 69 70 71static inline int test_and_clear_bit(unsigned nr, volatile unsigned long *addr) 72{ 73 int val; 74 unsigned long mask = (1UL << (nr % BITS_PER_LONG)); 75 smp_mb(); /* barrier for proper semantics */ 76 val = (__insn_fetchand((void *)(addr + nr / BITS_PER_LONG), ~mask) 77 & mask) != 0; 78 barrier(); 79 return val; 80} 81 82 83static inline int test_and_change_bit(unsigned nr, 84 volatile unsigned long *addr) 85{ 86 unsigned long mask = (1UL << (nr % BITS_PER_LONG)); 87 unsigned long guess, oldval; 88 addr += nr / BITS_PER_LONG; 89 oldval = *addr; 90 do { 91 guess = oldval; 92 oldval = cmpxchg(addr, guess, guess ^ mask); 93 } while (guess != oldval); 94 return (oldval & mask) != 0; 95} 96 97#include <asm-generic/bitops/ext2-atomic-setbit.h> 98 99#endif /* _ASM_TILE_BITOPS_64_H */