akaros/user/utest/pvcalarm.c
<<
>>
Prefs
   1#include <utest/utest.h>
   2#include <pthread.h>
   3#include <parlib/pvcalarm.h>
   4
   5TEST_SUITE("PVCALARMS");
   6
   7/* <--- Begin definition of test cases ---> */
   8bool test_pvcalarms(void) {
   9        const int INTERVAL = 10000;
  10        const int ITERS = 100;
  11        int count[max_vcores()];
  12        void pvcalarm_callback()
  13        {
  14                __sync_fetch_and_add(&count[vcore_id()], 1);
  15        }
  16
  17        parlib_never_yield = TRUE;
  18        pthread_mcp_init();
  19        vcore_request_total(max_vcores());
  20        parlib_never_vc_request = TRUE;
  21        for (int i = 0; i < max_vcores(); i++)
  22                count[i] = 0;
  23        
  24        uint64_t now, then;
  25        now = tsc2usec(read_tsc());
  26        enable_pvcalarms(PVCALARM_PROF, INTERVAL, pvcalarm_callback);
  27        for (int i = 0; i < max_vcores(); i++)
  28                while(count[i] < ITERS)
  29                        cpu_relax();
  30        disable_pvcalarms();
  31        then = tsc2usec(read_tsc());
  32
  33        UT_ASSERT_M("Alarms finished too soon", then > (now + INTERVAL*ITERS));
  34        UT_ASSERT_M("Alarms finished too late", then < (now +
  35                                                        2*INTERVAL*ITERS));
  36        return true;
  37}
  38
  39bool test_sigperf(void)
  40{
  41        const int INTERVAL = 10000;
  42        const int ITERATIONS = 100;
  43        const int NUM_PTHREADS = 10;
  44        int count[NUM_PTHREADS];
  45        pthread_t threads[NUM_PTHREADS];
  46        static __thread int *__count;
  47
  48        void *thread_handler(void *arg)
  49        {
  50                __count = (int*)arg;
  51                sigset_t s;
  52                sigemptyset(&s);
  53                sigaddset(&s, SIGPROF);
  54                pthread_sigmask(SIG_UNBLOCK, &s, NULL);
  55                int old_count = 0, new_count = 0;
  56                while(1) {
  57                        while ((new_count = atomic_read((atomic_t)__count)) <=
  58                              old_count);
  59                        if (new_count >= ITERATIONS)
  60                                break;
  61                        old_count = new_count;
  62                        pthread_yield();
  63                }
  64                return 0;
  65        }
  66        void signal_handler(int signo)
  67        {
  68                assert(signo == SIGPROF);
  69                __sync_fetch_and_add(__count, 1);
  70        }
  71
  72        parlib_never_yield = FALSE;
  73        parlib_never_vc_request = FALSE;
  74
  75        sigset_t s;
  76        sigemptyset(&s);
  77        sigaddset(&s, SIGPROF);
  78        pthread_sigmask(SIG_BLOCK, &s, NULL);
  79        struct sigaction sigact = {.sa_handler = signal_handler, 0};
  80
  81        sigaction(SIGPROF, &sigact, 0);
  82        for (int i = 0; i < NUM_PTHREADS; i++)
  83                count[i] = 0;
  84
  85        enable_profalarm(INTERVAL);
  86        for (int i = 0; i < NUM_PTHREADS; i++)
  87                pthread_create(&threads[i], NULL, thread_handler, &count[i]);
  88
  89        for (int i = 0; i < NUM_PTHREADS; i++)
  90                while (count[i] < ITERATIONS)
  91                        cpu_relax();
  92
  93        disable_pvcalarms();
  94        return true;
  95}
  96
  97/* <--- End definition of test cases ---> */
  98
  99struct utest utests[] = {
 100        UTEST_REG(pvcalarms),
 101        UTEST_REG(sigperf),
 102};
 103int num_utests = sizeof(utests) / sizeof(struct utest);
 104
 105int main(int argc, char *argv[]) {
 106        char **whitelist = &argv[1];
 107        int whitelist_len = argc - 1;
 108
 109        RUN_TEST_SUITE(utests, num_utests, whitelist, whitelist_len);
 110}
 111