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