C   25

pingpong c

Guest on 24th January 2023 02:02:56 PM


  1. #include <sys/syscall.h>
  2. #include <unistd.h>
  3. #include <stdio.h>
  4. #include <pthread.h>
  5.  
  6. #define ITERS   10000000
  7.  
  8. int mem;
  9.  
  10. static int
  11. sched_setaffinity(int mask)
  12. {
  13.         return (syscall(475, mask));
  14. }
  15.  
  16. static uint64_t
  17. rdtsc()
  18. {
  19.         uint32_t low, high;
  20.  
  21.         __asm __volatile("rdtsc" : "=a" (low), "=d" (high));
  22.  
  23.         return (((uint64_t)high << 32) | low);
  24. }
  25.  
  26. static int
  27. apicid()
  28. {
  29.         int eax, ebx, ecx, edx;
  30.  
  31.         __asm __volatile("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx),
  32.             "=d" (edx) : "a" (1));
  33.         return (ebx >> 24);
  34. }
  35.  
  36. void *
  37. pong(void *arg)
  38. {
  39.         int cpu, i;
  40.  
  41.         cpu = (long)arg;
  42.         sched_setaffinity(1 << cpu);
  43.  
  44.         while (1) {
  45.                 if (mem == 2)
  46.                         break;
  47.                 mem = 0;       
  48.                 __asm __volatile("" ::: "memory");
  49.                 while (mem == 0)
  50.                         __asm __volatile("" ::: "memory");
  51.         }
  52.  
  53.         return (NULL);
  54. }
  55.  
  56. void *
  57. ping(void *arg)
  58. {
  59.         uint64_t end, start, tot;
  60.         int cpu, i;
  61.  
  62.         cpu = (long)arg;
  63.         sched_setaffinity(1 << cpu);
  64.  
  65.         tot = 0;
  66.         for (i = 0; i < ITERS; i++) {
  67.                 start = rdtsc();
  68.                 mem = 1;
  69.                 __asm __volatile("" ::: "memory");
  70.  
  71.                 while (mem != 0)
  72.                         __asm __volatile("" ::: "memory");
  73.                 end = rdtsc();
  74.                 tot += end - start;
  75.         }
  76.  
  77.         mem = 2;
  78.  
  79.         printf("%lld", tot / ITERS);
  80.  
  81.         return (NULL);
  82. }
  83.  
  84. int
  85. main(void)
  86. {
  87.         pthread_t t1, t2;
  88.         long i, j;
  89.         int ncpus;
  90.  
  91.         ncpus = sysconf(_SC_NPROCESSORS_CONF);
  92.  
  93.         for (i = 0; i < ncpus; i++)
  94.                 printf("\tCPU%d", i);
  95.         printf("\n");
  96.  
  97.         for (i = 0; i < ncpus; i++) {
  98.                 printf("CPU%d\t", i);
  99.                 for (j = 0; j < ncpus; j++) {
  100.                         if (i == j) {
  101.                                 printf("\t");
  102.                                 continue;
  103.                         }
  104.                         mem = 0;
  105.                         pthread_create(&t1, NULL, ping, (void *)i);
  106.                         pthread_create(&t2, NULL, pong, (void *)j);
  107.                         pthread_join(t1, NULL);
  108.                         printf("\t");
  109.                 }
  110.                 printf("\n");
  111.         }
  112.  
  113.         return (0);
  114. }

Raw Paste


Login or Register to edit or fork this paste. It's free.

">