mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-01-23 02:14:37 +00:00
Acked-by: Mike Rapoport <rppt@linux.ibm.com> Signed-off-by: Adrian Reber <areber@redhat.com>
39 lines
926 B
C
39 lines
926 B
C
#ifndef _LINUX_BITOPS_H
|
|
#define _LINUX_BITOPS_H
|
|
#include <asm/types.h>
|
|
#include "common/compiler.h"
|
|
#include "common/asm-generic/bitops.h"
|
|
|
|
/**
|
|
* test_and_set_bit - Set a bit and return its old value
|
|
* @nr: Bit to set
|
|
* @addr: Address to count from
|
|
*
|
|
* This operation is atomic and cannot be reordered.
|
|
* It also implies a memory barrier.
|
|
*/
|
|
|
|
static inline int test_and_set_bit(unsigned long nr, volatile unsigned long *addr)
|
|
{
|
|
unsigned long *m = ((unsigned long *)addr) + (nr >> 6);
|
|
unsigned long temp = 0;
|
|
unsigned long res;
|
|
int bit = nr & 63UL;
|
|
|
|
do {
|
|
__asm__ __volatile__(" .set mips3 \n"
|
|
" lld %0, %1 # test_and_set_bit \n"
|
|
" or %2, %0, %3 \n"
|
|
" scd %2, %1 \n"
|
|
" .set mips0 \n"
|
|
: "=&r"(temp), "+m"(*m), "=&r"(res)
|
|
: "r"(1UL << bit)
|
|
: "memory");
|
|
} while (unlikely(!res));
|
|
|
|
res = temp & (1UL << bit);
|
|
|
|
return res != 0;
|
|
}
|
|
|
|
#endif
|