Annotation of nono/lib/testatomic.cpp, revision 1.1.1.2

1.1       root        1: //
                      2: // nono
                      3: // Copyright (C) 2018 [email protected]
                      4: //
                      5: 
1.1.1.2 ! root        6: #include "config-nono.h"
1.1       root        7: #include <atomic>
                      8: #include <cstdio>
                      9: #include <inttypes.h>
                     10: #include <pthread.h>
                     11: #include <sys/time.h>
                     12: #if defined(__NetBSD__)
                     13: #include <atomic.h>
                     14: #endif
                     15: 
                     16: volatile uint64_t shared;
                     17: volatile uint32_t terminate;
                     18: uint64_t result;
                     19: const uint64_t loopcnt = 10000000;
                     20: 
                     21: pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
                     22: 
                     23: std::atomic<uint64_t> shared5(0);
                     24: std::atomic<uint32_t> terminate5(0);
                     25: 
                     26: // test1: なにもしない
                     27: void
                     28: test1_init()
                     29: {
                     30: }
                     31: 
                     32: void *
                     33: test1_prod(void *arg)
                     34: {
                     35:        for (uint64_t i = 0; i < loopcnt; i++) {
                     36:                shared++;
                     37:        }
                     38:        terminate = 1;
                     39:        return NULL;
                     40: }
                     41: 
                     42: void *
                     43: test1_cons(void *arg)
                     44: {
                     45:        do {
                     46:                result += shared;
                     47:                shared = 0;
                     48:        } while (terminate == 0);
                     49:        return NULL;
                     50: }
                     51: 
                     52: // test2: pthread_mutex
                     53: void
                     54: test2_init()
                     55: {
                     56: }
                     57: 
                     58: void *
                     59: test2_prod(void *arg)
                     60: {
                     61:        for (uint64_t i = 0; i < loopcnt; i++) {
                     62:                pthread_mutex_lock(&mutex);
                     63:                shared++;
                     64:                pthread_mutex_unlock(&mutex);
                     65:        }
                     66:        terminate = 1;
                     67:        return NULL;
                     68: }
                     69: 
                     70: void *
                     71: test2_cons(void *arg)
                     72: {
                     73:        uint32_t t;
                     74:        do {
                     75:                pthread_mutex_lock(&mutex);
                     76:                result += shared;
                     77:                shared = 0;
                     78:                t = terminate;
                     79:                pthread_mutex_unlock(&mutex);
                     80:        } while (t == 0);
                     81:        result += shared;
                     82:        return NULL;
                     83: }
                     84: 
                     85: #if defined(__NetBSD__)
                     86: // test3: atomic.h
                     87: void
                     88: test3_init()
                     89: {
                     90: }
                     91: 
                     92: void *
                     93: test3_prod(void *arg)
                     94: {
                     95:        for (uint64_t i = 0; i < loopcnt; i++) {
                     96:                atomic_add_64(&shared, 1);
                     97:        }
                     98:        terminate = 1;
                     99:        return NULL;
                    100: }
                    101: 
                    102: void *
                    103: test3_cons(void *arg)
                    104: {
                    105:        do {
                    106:                result += atomic_swap_64(&shared, 0);
                    107:        } while (terminate == 0);
                    108:        // 見落とした分
                    109:        result += atomic_swap_64(&shared, 0);
                    110:        return NULL;
                    111: }
                    112: #endif
                    113: 
                    114: #if defined(__clang_version__)
                    115: // test4: clang's builtin
                    116: 
                    117: #else
                    118: 
                    119: // test4: GCC's builtin atomic
                    120: void
                    121: test4_init()
                    122: {
                    123: }
                    124: 
                    125: #define ATOMIC_TYPE __ATOMIC_SEQ_CST
                    126: 
                    127: void *
                    128: test4_prod(void *arg)
                    129: {
                    130:        for (uint64_t i = 0; i < loopcnt; i++) {
                    131:                __atomic_add_fetch(&shared, 1, ATOMIC_TYPE);
                    132:        }
                    133:        terminate = 1;
                    134:        return NULL;
                    135: }
                    136: 
                    137: void *
                    138: test4_cons(void *arg)
                    139: {
                    140:        do {
                    141:                result += __atomic_exchange_8(&shared, 0, ATOMIC_TYPE);
                    142:        } while (terminate == 0);
                    143:        // 
                    144:        result += __atomic_exchange_8(&shared, 0, ATOMIC_TYPE);
                    145:        return NULL;
                    146: }
                    147: #endif // __GNUC__
                    148: 
                    149: // test5: std::atomic
                    150: void
                    151: test5_init()
                    152: {
                    153: }
                    154: 
                    155: void *
                    156: test5_prod(void *arg)
                    157: {
                    158:        for (uint64_t i = 0; i < loopcnt; i++) {
                    159:                shared5.fetch_add(1);
                    160:        }
                    161:        terminate = 1;
                    162:        return NULL;
                    163: }
                    164: 
                    165: void *
                    166: test5_cons(void *arg)
                    167: {
                    168:        do {
                    169:                result += shared5.exchange(0);
                    170:        } while (terminate == 0);
                    171:        //
                    172:        result += shared5.exchange(0);
                    173:        return NULL;
                    174: }
                    175: 
                    176: // メインルーチン
                    177: int
                    178: test(const char *name,
                    179:        void (*init)(), void *(*prod)(void *), void *(*cons)(void *))
                    180: {
                    181:        pthread_t t1;
                    182:        pthread_t t2;
                    183:        struct timeval start, end, tv;
                    184: 
                    185:        printf("%-20s: ", name); fflush(stdout);
                    186:        result = 0;
                    187:        shared = 0;
                    188:        terminate = false;
                    189:        init();
                    190: 
                    191:        gettimeofday(&start, NULL);
                    192:        pthread_create(&t1, NULL, prod, NULL);
                    193:        pthread_create(&t2, NULL, cons, NULL);
                    194:        pthread_join(t1, NULL);
                    195:        pthread_join(t2, NULL);
                    196:        gettimeofday(&end, NULL);
                    197: 
                    198:        timersub(&end, &start, &tv);
                    199:        printf("time=%d.%06d, ", (int)tv.tv_sec, (int)tv.tv_usec);
                    200:        printf("result=%" PRIu64 "\n", result);
                    201:        return 0;
                    202: }
                    203: 
                    204: int
                    205: main(int ac, char *av[])
                    206: {
                    207:        printf("compiled by ");
                    208: #if defined(__clang_version__)
                    209:        printf("clang %s", __clang_version__);
                    210: #elif defined(__GNUC__) && defined(__VERSION__)
                    211:        printf("gcc %s", __VERSION__);
                    212: #else
                    213:        printf("unknown compiler");
                    214: #endif
                    215:        printf("\n");
                    216: 
                    217:        test("test1(no atomics)",       test1_init, test1_prod, test1_cons);
                    218: #if defined(__NetBSD__)
                    219:        test("test3(atomic.h)",         test3_init, test3_prod, test3_cons);
                    220: #endif
                    221: #if defined(__clang_version__)
                    222: #else
                    223:        test("test4(gcc builtin)",      test4_init, test4_prod, test4_cons);
                    224: #endif
                    225:        test("test5(std::atomic)",      test5_init, test5_prod, test5_cons);
                    226:        test("test2(pthread_mutex)",test2_init, test2_prod, test2_cons);
                    227:        return 0;
                    228: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.