blob: f878bf355655054850dbd296b0d1d704f94391d9 [file] [log] [blame]
#include <utest/utest.h>
#include <pthread.h>
#include <parlib/pvcalarm.h>
TEST_SUITE("PVCALARMS");
/* <--- Begin definition of test cases ---> */
bool test_pvcalarms(void) {
const int INTERVAL = 10000;
const int ITERS = 100;
int count[max_vcores()];
void pvcalarm_callback()
{
__sync_fetch_and_add(&count[vcore_id()], 1);
}
parlib_never_yield = TRUE;
pthread_mcp_init();
vcore_request_total(max_vcores());
parlib_never_vc_request = TRUE;
for (int i = 0; i < max_vcores(); i++)
count[i] = 0;
uint64_t now, then;
now = tsc2usec(read_tsc());
enable_pvcalarms(PVCALARM_PROF, INTERVAL, pvcalarm_callback);
for (int i = 0; i < max_vcores(); i++)
while(count[i] < ITERS)
cpu_relax();
disable_pvcalarms();
then = tsc2usec(read_tsc());
UT_ASSERT_M("Alarms finished too soon", then > (now + INTERVAL*ITERS));
UT_ASSERT_M("Alarms finished too late", then < (now +
2*INTERVAL*ITERS));
return true;
}
bool test_sigperf(void)
{
const int INTERVAL = 10000;
const int ITERATIONS = 100;
const int NUM_PTHREADS = 10;
int count[NUM_PTHREADS];
pthread_t threads[NUM_PTHREADS];
static __thread int *__count;
void *thread_handler(void *arg)
{
__count = (int*)arg;
sigset_t s;
sigemptyset(&s);
sigaddset(&s, SIGPROF);
pthread_sigmask(SIG_UNBLOCK, &s, NULL);
int old_count = 0, new_count = 0;
while(1) {
while ((new_count = atomic_read((atomic_t)__count)) <=
old_count);
if (new_count >= ITERATIONS)
break;
old_count = new_count;
pthread_yield();
}
return 0;
}
void signal_handler(int signo)
{
assert(signo == SIGPROF);
__sync_fetch_and_add(__count, 1);
}
parlib_never_yield = FALSE;
parlib_never_vc_request = FALSE;
sigset_t s;
sigemptyset(&s);
sigaddset(&s, SIGPROF);
pthread_sigmask(SIG_BLOCK, &s, NULL);
struct sigaction sigact = {.sa_handler = signal_handler, 0};
sigaction(SIGPROF, &sigact, 0);
for (int i = 0; i < NUM_PTHREADS; i++)
count[i] = 0;
enable_profalarm(INTERVAL);
for (int i = 0; i < NUM_PTHREADS; i++)
pthread_create(&threads[i], NULL, thread_handler, &count[i]);
for (int i = 0; i < NUM_PTHREADS; i++)
while (count[i] < ITERATIONS)
cpu_relax();
disable_pvcalarms();
return true;
}
/* <--- End definition of test cases ---> */
struct utest utests[] = {
UTEST_REG(pvcalarms),
UTEST_REG(sigperf),
};
int num_utests = sizeof(utests) / sizeof(struct utest);
int main(int argc, char *argv[]) {
char **whitelist = &argv[1];
int whitelist_len = argc - 1;
RUN_TEST_SUITE(utests, num_utests, whitelist, whitelist_len);
}