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