Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdint.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <pthread.h>
- #define NCOUNT (100000)
- #define TCOUNT (4)
- volatile uint64_t u = 0;
- volatile uint64_t *casvar = &u;
- uint64_t
- cas(volatile uint64_t *v, uint64_t old, uint64_t new)
- {
- volatile uint64_t ret = 0;
- asm volatile (
- " add %0, zero, 1\n\t"
- " fence iorw, iorw\n\t"
- " lr.d.aq a0, (%1)\n\t"
- " bne %2, a0, done\n\t"
- " sc.d.rl %0, %3, (%1)\n\t"
- " fence iorw, iorw\n\t"
- "done:\n"
- : "+r" (ret)
- : "r" (v), "r" (old), "r" (new)
- : "a0"
- );
- return ret;
- }
- void *
- thread(void *args) {
- volatile uint64_t val = 0;
- int i;
- for (i = 0; i < NCOUNT; i++) {
- for (;;) {
- volatile uint64_t *vp = &val;
- asm volatile (
- " fence iorw, iorw\n\t"
- " lr.d.aqrl a0, (%1)\n"
- " fence iorw, iorw\n\t"
- " sd a0, (%0)\n"
- : "+r" (vp)
- : "r" (casvar)
- : "a0"
- );
- if (cas(casvar, val, val+1) == 0)
- break;
- }
- }
- return (NULL);
- }
- int
- main(int argc, char **argv)
- {
- uint64_t i;
- pthread_t tid[TCOUNT];
- volatile uint64_t result;
- for (i = 0; i < TCOUNT; i++)
- pthread_create(&tid[i], NULL, thread, (void *)i+10);
- for (i = 0; i < TCOUNT; i++) {
- if (pthread_join(tid[i], NULL))
- printf("pthread_join failed %d\n", i+10);
- }
- __atomic_load(casvar, &result, __ATOMIC_CONSUME);
- if (result != TCOUNT*NCOUNT) {
- printf("womp womp %d %d\n", result, TCOUNT*NCOUNT);
- return (1);
- }
- printf("ok %d %d\n", result, TCOUNT*NCOUNT);
- return (0);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement