#include "blib.h"
#include <sys/types.h>
#include <machine/atomic.h>
#include <machine/cpufunc.h>
int *mtx;
int refcnt;
static void
spin_lock_contested(void)
{
int i;
int j;
j = 1;
while (atomic_swap_int(mtx, 1) != 0) {
for (i = 0; i < j; ++i)
__asm __volatile("pause"::);
j <<= 1;
}
}
static __inline void
spin_lock(void)
{
if (refcnt == 1) {
if (*mtx == 0)
*mtx = 1;
else
spin_lock_contested();
} else if (atomic_swap_int(mtx, 1) != 0) {
spin_lock_contested();
}
}
static __inline void
spin_unlock(void)
{
cpu_sfence();
*mtx = 0;
}
int
main(int ac, char **av)
{
long long count = 0;
long long max;
int j;
int *counter;
pid_t pid;
printf("Test simple locked bus cycle mutex latency\n");
printf("auto-forks two processes for the test with shared memory\n");
printf("This test is only useful on a SMP box\n");
start_timing();
mtx = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANON, -1, 0);
counter = mtx + 64;
while (stop_timing(0, NULL) == 0) {
for (j = 0; j < 100; ++j) {
spin_lock();
spin_unlock();
}
count += 100;
}
max = count;
*mtx = 0;
refcnt = 1;
start_timing();
for (count = 0; count < max; count += 100) {
for (j = 0; j < 100; ++j) {
spin_lock();
spin_unlock();
++counter[64];
}
}
stop_timing(count, "complex_mtx(uncontested/1cpu)");
refcnt = 2;
if ((pid = fork()) == 0) {
for (;;) {
for (j = 0; j < 100; ++j) {
spin_lock();
spin_unlock();
++counter[128];
}
}
} else {
start_timing();
for (count = 0; count < max; count += 100) {
for (j = 0; j < 100; ++j) {
spin_lock();
spin_unlock();
++counter[64];
}
}
stop_timing(count, "complex_mtx");
printf("proc1=%d proc2=%d\n", counter[64], counter[128]);
kill(pid, 9);
}
return(0);
}