#include #include #include #include #include #include struct context { _Atomic long long *sum; _Atomic long long *index; }; int accumulator(void* arg) { struct context * context = (struct context *)arg; long long index; while((index = atomic_load(context->index))) { if(atomic_compare_exchange_strong(context->index, &index, index - 1)) { atomic_fetch_add(context->sum, index); } } } int main(int argc, char * argv[]) { if(argc != 3) return 1; long long nelements = atoll(argv[1]); if(nelements == 0) return 2; int nthreads = atoi(argv[2]); if(nthreads < 1) return 3; _Atomic long long sum = 0; _Atomic long long index = nelements; struct timeval start, stop; gettimeofday(&start, NULL); thrd_t threads[nthreads]; struct context context = {.sum=&sum, .index=&index}; for(int i = 0; i < nthreads; ++i) { thrd_create(&threads[i], accumulator, &context); } for(int i = 0; i < nthreads; ++i) { thrd_join(threads[i], NULL); } gettimeofday(&stop, NULL); printf("elapsed time: %lf ms\n", ((double)(stop.tv_sec - start.tv_sec)) * 1000 + ((double)((stop.tv_usec - start.tv_usec)) / 1000)); assert(index == 0 && "processed everything"); printf("result: %lld\n", sum); }