227 lines · c
1// RUN: %libomp-compile-and-run2 3#include <stdio.h>4#include <stdbool.h>5#include <omp.h>6 7// Used to detect architecture8#include "../../src/kmp_platform.h"9 10#ifdef __cplusplus11extern "C" {12#endif13typedef void* ident_t;14extern bool15__kmpc_atomic_bool_1_cas_cpt(ident_t *loc, int gtid, char *x, char e, char d,16 char *pv);17extern bool18__kmpc_atomic_bool_2_cas_cpt(ident_t *loc, int gtid, short *x, short e, short d,19 short *pv);20extern bool21__kmpc_atomic_bool_4_cas_cpt(ident_t *loc, int gtid, int *x, int e, int d,22 int *pv);23extern bool24__kmpc_atomic_bool_8_cas_cpt(ident_t *loc, int gtid, long long *x, long long e,25 long long d, long long *pv);26extern char27__kmpc_atomic_val_1_cas_cpt(ident_t *loc, int gtid, char *x, char e, char d,28 char *pv);29extern short30__kmpc_atomic_val_2_cas_cpt(ident_t *loc, int gtid, short *x, short e, short d,31 short *pv);32extern int33__kmpc_atomic_val_4_cas_cpt(ident_t *loc, int gtid, int *x, int e, int d,34 int *pv);35extern long long36__kmpc_atomic_val_8_cas_cpt(ident_t *loc, int gtid, long long *x, long long e,37 long long d, long long *pv);38#ifdef __cplusplus39}40#endif41 42int main() {43 int ret = 0;44#if KMP_ARCH_X86 || KMP_ARCH_X86_6445 bool r;46 char c0 = 1;47 char c1 = 2;48 char c2 = 3;49 char co = 2;50 char cc = 0;51 char cv = 0;52 short s0 = 11;53 short s1 = 12;54 short s2 = 13;55 short so = 12;56 short sc = 0;57 short sv = 0;58 int i0 = 211;59 int i1 = 212;60 int i2 = 213;61 int io = 212;62 int ic = 0;63 int iv = 0;64 long long l0 = 3111;65 long long l1 = 3112;66 long long l2 = 3113;67 long long lo = 3112;68 long long lc = 0;69 long long lv = 0;70 71// initialize OpenMP runtime library72 omp_set_dynamic(0);73 74// #pragma omp atomic compare update capture75// { r = x == e; if(r) { x = d; } else { v = x; } }76// char, co == c1 initially, co == c2 finally77 r = __kmpc_atomic_bool_1_cas_cpt(NULL, 0, &co, c0, c2, &cv); // no-op78 if (co != c1) {79 ret++; printf("Error bool_1_cas_cpt no-op: %d != %d\n", co, c1); }80 if (cv != co) {81 ret++; printf("Error bool_1_cas_cpt no-op cpt: %d != %d\n", cv, co); }82 if (r) { ret++; printf("Error bool_1_cas_cpt no-op ret: %d\n", r); }83 cv = 0;84 r = __kmpc_atomic_bool_1_cas_cpt(NULL, 0, &co, c1, c2, &cv);85 if (co != c2) { ret++; printf("Error bool_1_cas_cpt: %d != %d\n", co, c2); }86 if (cv != 0) { ret++; printf("Error bool_1_cas_cpt cpt: %d != %d\n", cv, 0); }87 if (!r) { ret++; printf("Error bool_1_cas_cpt ret: %d\n", r); }88// short89 r = __kmpc_atomic_bool_2_cas_cpt(NULL, 0, &so, s0, s2, &sv); // no-op90 if (so != s1) {91 ret++; printf("Error bool_2_cas_cpt no-op: %d != %d\n", so, s1); }92 if (sv != so) {93 ret++; printf("Error bool_2_cas_cpt no-op cpt: %d != %d\n", sv, so); }94 if (r) { ret++; printf("Error bool_2_cas_cpt no-op ret: %d\n", r); }95 sv = 0;96 r = __kmpc_atomic_bool_2_cas_cpt(NULL, 0, &so, s1, s2, &sv);97 if (so != s2) { ret++; printf("Error bool_2_cas_cpt: %d != %d\n", so, s2); }98 if (sv != 0) { ret++; printf("Error bool_2_cas_cpt cpt: %d != %d\n", sv, 0); }99 if (!r) { ret++; printf("Error bool_2_cas_cpt ret: %d\n", r); }100// int101 r = __kmpc_atomic_bool_4_cas_cpt(NULL, 0, &io, i0, i2, &iv); // no-op102 if (io != i1) {103 ret++; printf("Error bool_4_cas_cpt no-op: %d != %d\n", io, i1); }104 if (iv != io) {105 ret++; printf("Error bool_4_cas_cpt no-op cpt: %d != %d\n", iv, io); }106 if (r) { ret++; printf("Error bool_4_cas_cpt no-op ret: %d\n", r); }107 iv = 0;108 r = __kmpc_atomic_bool_4_cas_cpt(NULL, 0, &io, i1, i2, &iv);109 if (io != i2) { ret++; printf("Error bool_4_cas_cpt: %d != %d\n", io, i2); }110 if (iv != 0) { ret++; printf("Error bool_4_cas_cpt cpt: %d != %d\n", iv, 0); }111 if (!r) { ret++; printf("Error bool_4_cas_cpt ret: %d\n", r); }112// long long113 r = __kmpc_atomic_bool_8_cas_cpt(NULL, 0, &lo, l0, l2, &lv); // no-op114 if (lo != l1) {115 ret++; printf("Error bool_8_cas_cpt no-op: %lld != %lld\n", lo, l1); }116 if (lv != lo) {117 ret++; printf("Error bool_8_cas_cpt no-op cpt: %lld != %lld\n", lv, lo); }118 if (r) { ret++; printf("Error bool_8_cas_cpt no-op ret: %d\n", r); }119 lv = 0;120 r = __kmpc_atomic_bool_8_cas_cpt(NULL, 0, &lo, l1, l2, &lv);121 if (lo != l2) {122 ret++; printf("Error bool_8_cas_cpt: %lld != %lld\n", lo, l2); }123 if (lv != 0) { // should not be assigned124 ret++; printf("Error bool_8_cas_cpt cpt: %lld != %d\n", lv, 0); }125 if (!r) { ret++; printf("Error bool_8_cas_cpt ret: %d\n", r); }126 127// #pragma omp atomic compare update capture128// { if (x == e) { x = d; }; v = x; }129// char, co == c2 initially, co == c1 finally130 cc = __kmpc_atomic_val_1_cas_cpt(NULL, 0, &co, c0, c1, &cv); // no-op131 if (co != c2) {132 ret++; printf("Error val_1_cas_cpt no-op: %d != %d\n", co, c2); }133 if (cv != c2) {134 ret++; printf("Error val_1_cas_cpt no-op cpt: %d != %d\n", cv, c2); }135 if (cc != c2) {136 ret++; printf("Error val_1_cas_cpt no-op ret: %d != %d\n", cc, c2); }137 cc = __kmpc_atomic_val_1_cas_cpt(NULL, 0, &co, c2, c1, &cv);138 if (co != c1) { ret++; printf("Error val_1_cas_cpt: %d != %d\n", co, c1); }139 if (cv != c1) { ret++; printf("Error val_1_cas_cpt cpt: %d != %d\n", cv, c1); }140 if (cc != c2) { ret++; printf("Error val_1_cas_cpt ret: %d != %d\n", cc, c2); }141// short142 sc = __kmpc_atomic_val_2_cas_cpt(NULL, 0, &so, s0, s1, &sv); // no-op143 if (so != s2) {144 ret++; printf("Error val_2_cas_cpt no-op: %d != %d\n", so, s2); }145 if (sv != s2) {146 ret++; printf("Error val_2_cas_cpt no-op cpt: %d != %d\n", sv, s2); }147 if (sc != s2) {148 ret++; printf("Error val_2_cas_cpt no-op ret: %d != %d\n", sc, s2); }149 sc = __kmpc_atomic_val_2_cas_cpt(NULL, 0, &so, s2, s1, &sv);150 if (so != s1) { ret++; printf("Error val_2_cas_cpt: %d != %d\n", so, s1); }151 if (sv != s1) { ret++; printf("Error val_2_cas_cpt cpt: %d != %d\n", sv, s1); }152 if (sc != s2) { ret++; printf("Error val_2_cas_cpt ret: %d != %d\n", sc, s2); }153// int154 ic = __kmpc_atomic_val_4_cas_cpt(NULL, 0, &io, i0, i1, &iv); // no-op155 if (io != i2) {156 ret++; printf("Error val_4_cas_cpt no-op: %d != %d\n", io, i2); }157 if (iv != i2) {158 ret++; printf("Error val_4_cas_cpt no-op cpt: %d != %d\n", iv, i2); }159 if (ic != i2) {160 ret++; printf("Error val_4_cas_cpt no-op ret: %d != %d\n", ic, i2); }161 ic = __kmpc_atomic_val_4_cas_cpt(NULL, 0, &io, i2, i1, &iv);162 if (io != i1) { ret++; printf("Error val_4_cas_cpt: %d != %d\n", io, i1); }163 if (iv != i1) { ret++; printf("Error val_4_cas_cpt cpt: %d != %d\n", io, i1); }164 if (ic != i2) { ret++; printf("Error val_4_cas_cpt ret: %d != %d\n", ic, i2); }165// long long166 lc = __kmpc_atomic_val_8_cas_cpt(NULL, 0, &lo, l0, l1, &lv); // no-op167 if (lo != l2) {168 ret++; printf("Error val_8_cas_cpt no-op: %lld != %lld\n", lo, l2); }169 if (lv != l2) {170 ret++; printf("Error val_8_cas_cpt no-op cpt: %lld != %lld\n", lv, l2); }171 if (lc != l2) {172 ret++; printf("Error val_8_cas_cpt no-op ret: %lld != %lld\n", lc, l2); }173 lc = __kmpc_atomic_val_8_cas_cpt(NULL, 0, &lo, l2, l1, &lv);174 if (lo != l1) { ret++; printf("Error val_8_cas_cpt: %lld != %lld\n", lo, l1); }175 if (lv != l1) {176 ret++; printf("Error val_8_cas_cpt cpt: %lld != %lld\n", lv, l1); }177 if (lc != l2) {178 ret++; printf("Error val_8_cas_cpt ret: %lld != %lld\n", lc, l2); }179 180// check in parallel181 i0 = 1;182 i1 = 0;183 for (io = 0; io < 5; ++io) {184 #pragma omp parallel num_threads(2) private(i2, ic, r, iv)185 {186 if (omp_get_thread_num() == 0) {187 // th0 waits for th1 to increment i1, then th0 increments i0188 #pragma omp atomic read189 i2 = i1;190 ic = __kmpc_atomic_val_4_cas_cpt(NULL, 0, &i0, i2, i2 + 1, &iv);191 while(ic != i2) {192 if (iv != ic) {193 ret++;194 printf("Error 1 in parallel cpt, %d != %d\n", iv, ic);195 }196 #pragma omp atomic read197 i2 = i1;198 ic = __kmpc_atomic_val_4_cas_cpt(NULL, 0, &i0, i2, i2 + 1, &iv);199 }200 if (iv != i2 + 1) {201 ret++;202 printf("Error 2 in parallel cpt, %d != %d\n", iv, i2 + 1);203 }204 } else {205 // th1 increments i1 if it is equal to i0 - 1, letting th0 to proceed206 r = 0;207 while(!r) {208 #pragma omp atomic read209 i2 = i0;210 r = __kmpc_atomic_bool_4_cas_cpt(NULL, 0, &i1, i2 - 1, i2, &iv);211 }212 }213 }214 }215 if (i0 != 6 || i1 != 5) {216 ret++;217 printf("Error in parallel, %d != %d or %d != %d\n", i0, 6, i1, 5);218 }219 220 if (ret == 0)221 printf("passed\n");222#else223 printf("Unsupported architecture, skipping test...\n");224#endif // KMP_ARCH_X86 || KMP_ARCH_X86_64225 return ret;226}227