File: bitops.h

package info (click to toggle)
criu 4.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 11,500 kB
  • sloc: ansic: 139,280; python: 7,484; sh: 3,824; java: 2,799; makefile: 2,659; asm: 1,137; perl: 206; xml: 117; exp: 45
file content (39 lines) | stat: -rw-r--r-- 926 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#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