selftests/powerpc: context_switch use private futexes with threads
This reduces overhead of mutex locking and increases context switch rate significantly (which helps to measure and profile the context switch path). Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:
parent
b802ab46ba
commit
b27ce77685
|
@ -258,9 +258,14 @@ static unsigned long xchg(unsigned long *p, unsigned long val)
|
||||||
return __atomic_exchange_n(p, val, __ATOMIC_SEQ_CST);
|
return __atomic_exchange_n(p, val, __ATOMIC_SEQ_CST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int processes;
|
||||||
|
|
||||||
static int mutex_lock(unsigned long *m)
|
static int mutex_lock(unsigned long *m)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
int flags = FUTEX_WAIT;
|
||||||
|
if (!processes)
|
||||||
|
flags |= FUTEX_PRIVATE_FLAG;
|
||||||
|
|
||||||
c = cmpxchg(m, 0, 1);
|
c = cmpxchg(m, 0, 1);
|
||||||
if (!c)
|
if (!c)
|
||||||
|
@ -270,7 +275,7 @@ static int mutex_lock(unsigned long *m)
|
||||||
c = xchg(m, 2);
|
c = xchg(m, 2);
|
||||||
|
|
||||||
while (c) {
|
while (c) {
|
||||||
sys_futex(m, FUTEX_WAIT, 2, NULL, NULL, 0);
|
sys_futex(m, flags, 2, NULL, NULL, 0);
|
||||||
c = xchg(m, 2);
|
c = xchg(m, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,12 +284,16 @@ static int mutex_lock(unsigned long *m)
|
||||||
|
|
||||||
static int mutex_unlock(unsigned long *m)
|
static int mutex_unlock(unsigned long *m)
|
||||||
{
|
{
|
||||||
|
int flags = FUTEX_WAKE;
|
||||||
|
if (!processes)
|
||||||
|
flags |= FUTEX_PRIVATE_FLAG;
|
||||||
|
|
||||||
if (*m == 2)
|
if (*m == 2)
|
||||||
*m = 0;
|
*m = 0;
|
||||||
else if (xchg(m, 0) == 1)
|
else if (xchg(m, 0) == 1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
sys_futex(m, FUTEX_WAKE, 1, NULL, NULL, 0);
|
sys_futex(m, flags, 1, NULL, NULL, 0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -293,27 +302,33 @@ static unsigned long *m1, *m2;
|
||||||
|
|
||||||
static void futex_setup(int cpu1, int cpu2)
|
static void futex_setup(int cpu1, int cpu2)
|
||||||
{
|
{
|
||||||
int shmid;
|
if (!processes) {
|
||||||
void *shmaddr;
|
static unsigned long _m1, _m2;
|
||||||
|
m1 = &_m1;
|
||||||
|
m2 = &_m2;
|
||||||
|
} else {
|
||||||
|
int shmid;
|
||||||
|
void *shmaddr;
|
||||||
|
|
||||||
shmid = shmget(IPC_PRIVATE, getpagesize(), SHM_R | SHM_W);
|
shmid = shmget(IPC_PRIVATE, getpagesize(), SHM_R | SHM_W);
|
||||||
if (shmid < 0) {
|
if (shmid < 0) {
|
||||||
perror("shmget");
|
perror("shmget");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shmaddr = shmat(shmid, NULL, 0);
|
||||||
|
if (shmaddr == (char *)-1) {
|
||||||
|
perror("shmat");
|
||||||
|
shmctl(shmid, IPC_RMID, NULL);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
shmaddr = shmat(shmid, NULL, 0);
|
|
||||||
if (shmaddr == (char *)-1) {
|
|
||||||
perror("shmat");
|
|
||||||
shmctl(shmid, IPC_RMID, NULL);
|
shmctl(shmid, IPC_RMID, NULL);
|
||||||
exit(1);
|
|
||||||
|
m1 = shmaddr;
|
||||||
|
m2 = shmaddr + sizeof(*m1);
|
||||||
}
|
}
|
||||||
|
|
||||||
shmctl(shmid, IPC_RMID, NULL);
|
|
||||||
|
|
||||||
m1 = shmaddr;
|
|
||||||
m2 = shmaddr + sizeof(*m1);
|
|
||||||
|
|
||||||
*m1 = 0;
|
*m1 = 0;
|
||||||
*m2 = 0;
|
*m2 = 0;
|
||||||
|
|
||||||
|
@ -352,8 +367,6 @@ static struct actions futex_actions = {
|
||||||
.thread2 = futex_thread2,
|
.thread2 = futex_thread2,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int processes;
|
|
||||||
|
|
||||||
static struct option options[] = {
|
static struct option options[] = {
|
||||||
{ "test", required_argument, 0, 't' },
|
{ "test", required_argument, 0, 't' },
|
||||||
{ "process", no_argument, &processes, 1 },
|
{ "process", no_argument, &processes, 1 },
|
||||||
|
|
Loading…
Reference in a new issue