xref: /dragonfly/test/sysperf/mutex3.c (revision 86d7f5d305c6adaa56ff4582ece9859d73106103)
1 /*
2  * mutex3.c
3  *
4  * $DragonFly: src/test/sysperf/mutex3.c,v 1.1 2006/05/18 02:22:46 dillon Exp $
5  */
6 
7 #include "blib.h"
8 
9 #include <sys/types.h>
10 #include <machine/atomic.h>
11 #include <machine/cpufunc.h>
12 
13 int *mtx;
14 int refcnt;
15 
16 static void
spin_lock_contested(void)17 spin_lock_contested(void)
18 {
19           int i;
20           int j;
21 
22           j = 1;
23           while (atomic_swap_int(mtx, 1) != 0) {
24                     for (i = 0; i < j; ++i)
25                               __asm __volatile("pause"::);
26                     j <<= 1;
27           }
28 }
29 
30 static __inline void
spin_lock(void)31 spin_lock(void)
32 {
33           if (refcnt == 1) {
34                     if (*mtx == 0)
35                               *mtx = 1;
36                     else
37                               spin_lock_contested();
38           } else if (atomic_swap_int(mtx, 1) != 0) {
39                     spin_lock_contested();
40           }
41 }
42 
43 static __inline void
spin_unlock(void)44 spin_unlock(void)
45 {
46           cpu_sfence();
47           *mtx = 0;
48 }
49 
50 int
main(int ac,char ** av)51 main(int ac, char **av)
52 {
53     long long count = 0;
54     long long max;
55     int j;
56     int *counter;
57     pid_t pid;
58 
59     printf("Test simple locked bus cycle mutex latency\n");
60     printf("auto-forks two processes for the test with shared memory\n");
61     printf("This test is only useful on a SMP box\n");
62 
63     start_timing();
64     mtx = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANON, -1, 0);
65     counter = mtx + 64;
66     while (stop_timing(0, NULL) == 0) {
67           for (j = 0; j < 100; ++j) {
68               spin_lock();
69               spin_unlock();
70           }
71           count += 100;
72     }
73     max = count;
74     *mtx = 0;
75 
76     refcnt = 1;
77     start_timing();
78     for (count = 0; count < max; count += 100) {
79           for (j = 0; j < 100; ++j) {
80               spin_lock();
81               spin_unlock();  /* release */
82               ++counter[64];
83           }
84     }
85     stop_timing(count, "complex_mtx(uncontested/1cpu)");
86     refcnt = 2;
87 
88     if ((pid = fork()) == 0) {
89           for (;;) {
90               for (j = 0; j < 100; ++j) {
91                     spin_lock();
92                     spin_unlock();      /* release */
93                     ++counter[128];
94               }
95           }
96     } else {
97           start_timing();
98           for (count = 0; count < max; count += 100) {
99               for (j = 0; j < 100; ++j) {
100                     spin_lock();
101                     spin_unlock();      /* release */
102                     ++counter[64];
103               }
104           }
105           stop_timing(count, "complex_mtx");
106           printf("proc1=%d proc2=%d\n", counter[64], counter[128]);
107           kill(pid, 9);
108     }
109     return(0);
110 }
111 
112