Home | History | Annotate | Line # | Download | only in unit
      1 // SPDX-FileCopyrightText: 2009 Mathieu Desnoyers <mathieu.desnoyers (at) efficios.com>
      2 //
      3 // SPDX-License-Identifier: GPL-2.0-or-later
      4 
      5 #include <stdio.h>
      6 #include <urcu/uatomic.h>
      7 
      8 #include "tap.h"
      9 
     10 #define NR_TESTS 17
     11 
     12 #define BYTE_PER_LONG	(sizeof(unsigned long) / sizeof(unsigned char))
     13 #define SHORT_PER_LONG	(sizeof(unsigned long) / sizeof(unsigned short))
     14 #define INT_PER_LONG	(sizeof(unsigned long) / sizeof(unsigned int))
     15 
     16 struct testvals {
     17 #ifdef UATOMIC_HAS_ATOMIC_BYTE
     18 	unsigned char c[BYTE_PER_LONG];
     19 #endif
     20 #ifdef UATOMIC_HAS_ATOMIC_SHORT
     21 	unsigned short s[SHORT_PER_LONG];
     22 #endif
     23 	unsigned int i[INT_PER_LONG];
     24 	unsigned long l;
     25 };
     26 
     27 static struct testvals vals;
     28 
     29 #define do_test(ptr)				\
     30 do {						\
     31 	__typeof__(*(ptr)) v;			\
     32 						\
     33 	uatomic_add(ptr, 10);			\
     34 	ok1(uatomic_read(ptr) == 10);	\
     35 						\
     36 	uatomic_add(ptr, -11UL);		\
     37 	ok1(uatomic_read(ptr) == (__typeof__(*(ptr)))-1UL);	\
     38 						\
     39 	v = uatomic_cmpxchg(ptr, -1UL, 22);	\
     40 	ok1(uatomic_read(ptr) == 22);	\
     41 	ok1(v == (__typeof__(*(ptr)))-1UL);	\
     42 						\
     43 	v = uatomic_cmpxchg(ptr, 33, 44);	\
     44 	ok1(uatomic_read(ptr) == 22);	\
     45 	ok1(v == 22);			\
     46 						\
     47 	v = uatomic_xchg(ptr, 55);		\
     48 	ok1(uatomic_read(ptr) == 55);	\
     49 	ok1(v == 22);			\
     50 						\
     51 	uatomic_set(ptr, 22);			\
     52 	uatomic_inc(ptr);			\
     53 	ok1(uatomic_read(ptr) == 23);	\
     54 						\
     55 	uatomic_dec(ptr);			\
     56 	ok1(uatomic_read(ptr) == 22);	\
     57 						\
     58 	v = uatomic_add_return(ptr, 74);	\
     59 	ok1(v == 96);			\
     60 	ok1(uatomic_read(ptr) == 96);	\
     61 						\
     62 	uatomic_or(ptr, 58);			\
     63 	ok1(uatomic_read(ptr) == 122);	\
     64 						\
     65 	v = uatomic_sub_return(ptr, 1);		\
     66 	ok1(v == 121);			\
     67 						\
     68 	uatomic_sub(ptr, (unsigned int) 2);	\
     69 	ok1(uatomic_read(ptr) == 119);	\
     70 						\
     71 	uatomic_inc(ptr);			\
     72 	uatomic_inc(ptr);			\
     73 	ok1(uatomic_read(ptr) == 121);	\
     74 						\
     75 	uatomic_and(ptr, 129);			\
     76 	ok1(uatomic_read(ptr) == 1);	\
     77 						\
     78 } while (0)
     79 
     80 int main(void)
     81 {
     82 	int nr_run = INT_PER_LONG + 1;
     83 	unsigned long i;
     84 
     85 #ifdef UATOMIC_HAS_ATOMIC_BYTE
     86 	nr_run += BYTE_PER_LONG;
     87 #endif
     88 #ifdef UATOMIC_HAS_ATOMIC_SHORT
     89 	nr_run += SHORT_PER_LONG;
     90 #endif
     91 
     92 	plan_tests(nr_run * NR_TESTS);
     93 #ifdef UATOMIC_HAS_ATOMIC_BYTE
     94 	for (i = 0; i < BYTE_PER_LONG; i++) {
     95 		diag("Test atomic ops on byte with %lu byte offset from long alignment",
     96 			i);
     97 		do_test(&vals.c[i]);
     98 	}
     99 #endif
    100 #ifdef UATOMIC_HAS_ATOMIC_SHORT
    101 	for (i = 0; i < SHORT_PER_LONG; i++) {
    102 		diag("Test atomic ops on short with %lu byte offset from long alignment",
    103 			i * sizeof(unsigned short));
    104 		do_test(&vals.s[i]);
    105 	}
    106 #endif
    107 	for (i = 0; i < INT_PER_LONG; i++) {
    108 		diag("Test atomic ops on int with %lu byte offset from long alignment",
    109 			i * sizeof(unsigned int));
    110 		do_test(&vals.i[i]);
    111 	}
    112 	diag("Test atomic ops on long");
    113 	do_test(&vals.l);
    114 
    115 	return exit_status();
    116 }
    117