File: test_uatomic.c

package info (click to toggle)
liburcu 0.15.6-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 8,356 kB
  • sloc: ansic: 23,370; xml: 23,227; sh: 6,480; makefile: 1,045; cpp: 15
file content (116 lines) | stat: -rw-r--r-- 2,725 bytes parent folder | download | duplicates (2)
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// SPDX-FileCopyrightText: 2009 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
//
// SPDX-License-Identifier: GPL-2.0-or-later

#include <stdio.h>
#include <urcu/uatomic.h>

#include "tap.h"

#define NR_TESTS 17

#define BYTE_PER_LONG	(sizeof(unsigned long) / sizeof(unsigned char))
#define SHORT_PER_LONG	(sizeof(unsigned long) / sizeof(unsigned short))
#define INT_PER_LONG	(sizeof(unsigned long) / sizeof(unsigned int))

struct testvals {
#ifdef UATOMIC_HAS_ATOMIC_BYTE
	unsigned char c[BYTE_PER_LONG];
#endif
#ifdef UATOMIC_HAS_ATOMIC_SHORT
	unsigned short s[SHORT_PER_LONG];
#endif
	unsigned int i[INT_PER_LONG];
	unsigned long l;
};

static struct testvals vals;

#define do_test(ptr)				\
do {						\
	__typeof__(*(ptr)) v;			\
						\
	uatomic_add(ptr, 10);			\
	ok1(uatomic_load(ptr) == 10);	\
						\
	uatomic_add(ptr, -11UL);		\
	ok1(uatomic_load(ptr) == (__typeof__(*(ptr)))-1UL);	\
						\
	v = uatomic_cmpxchg(ptr, -1UL, 22);	\
	ok1(uatomic_load(ptr) == 22);	\
	ok1(v == (__typeof__(*(ptr)))-1UL);	\
						\
	v = uatomic_cmpxchg(ptr, 33, 44);	\
	ok1(uatomic_load(ptr) == 22);	\
	ok1(v == 22);			\
						\
	v = uatomic_xchg(ptr, 55);		\
	ok1(uatomic_load(ptr) == 55);	\
	ok1(v == 22);			\
						\
	uatomic_store(ptr, 22);			\
	uatomic_inc(ptr);			\
	ok1(uatomic_load(ptr) == 23);	\
						\
	uatomic_dec(ptr);			\
	ok1(uatomic_load(ptr) == 22);	\
						\
	v = uatomic_add_return(ptr, 74);	\
	ok1(v == 96);			\
	ok1(uatomic_load(ptr) == 96);	\
						\
	uatomic_or(ptr, 58);			\
	ok1(uatomic_load(ptr) == 122);	\
						\
	v = uatomic_sub_return(ptr, 1);		\
	ok1(v == 121);			\
						\
	uatomic_sub(ptr, (unsigned int) 2);	\
	ok1(uatomic_load(ptr) == 119);	\
						\
	uatomic_inc(ptr);			\
	uatomic_inc(ptr);			\
	ok1(uatomic_load(ptr) == 121);	\
						\
	uatomic_and(ptr, 129);			\
	ok1(uatomic_load(ptr) == 1);	\
						\
} while (0)

int main(void)
{
	int nr_run = INT_PER_LONG + 1;
	unsigned long i;

#ifdef UATOMIC_HAS_ATOMIC_BYTE
	nr_run += BYTE_PER_LONG;
#endif
#ifdef UATOMIC_HAS_ATOMIC_SHORT
	nr_run += SHORT_PER_LONG;
#endif

	plan_tests(nr_run * NR_TESTS);
#ifdef UATOMIC_HAS_ATOMIC_BYTE
	for (i = 0; i < BYTE_PER_LONG; i++) {
		diag("Test atomic ops on byte with %lu byte offset from long alignment",
			i);
		do_test(&vals.c[i]);
	}
#endif
#ifdef UATOMIC_HAS_ATOMIC_SHORT
	for (i = 0; i < SHORT_PER_LONG; i++) {
		diag("Test atomic ops on short with %lu byte offset from long alignment",
			i * sizeof(unsigned short));
		do_test(&vals.s[i]);
	}
#endif
	for (i = 0; i < INT_PER_LONG; i++) {
		diag("Test atomic ops on int with %lu byte offset from long alignment",
			i * sizeof(unsigned int));
		do_test(&vals.i[i]);
	}
	diag("Test atomic ops on long");
	do_test(&vals.l);

	return exit_status();
}