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

1.1     ! root        1: //
        !             2: // nono
        !             3: // Copyright (C) 2018 [email protected]
        !             4: //
        !             5: 
        !             6: #include "config.h"
        !             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.