akaros/tests/signal_futex.c
<<
>>
Prefs
   1/* Copyright (c) 2014 The Regents of the University of California
   2 * Kevin Klues <klueska@cs.berkeley.edu>
   3 * See LICENSE for details.
   4 */
   5
   6#include <stdio.h>
   7#include <stdlib.h>
   8#include <unistd.h>
   9#include <parlib/parlib.h>
  10#include <pthread.h>
  11#include <futex.h>
  12#include <signal.h>
  13
  14// Signal handler run in vcore context which redirects signals to userspace by
  15// waking a thread waiting on a futex. Note, this does not guarantee that every
  16// signal that comes through this handler will be noticed or processed by the
  17// thread.
  18int __sigpending = 0;
  19void sig_handler(int signr)
  20{
  21        __sigpending = 1;
  22        futex(&__sigpending, FUTEX_WAKE, INT_MAX, NULL, NULL, 0);
  23}
  24
  25// User level thread waiting on a futex to count signals
  26int count = 0;
  27void *count_signals(void *arg)
  28{
  29        while(1) {
  30                futex(&__sigpending, FUTEX_WAIT, 0, NULL, NULL, 0);
  31                __sync_fetch_and_add(&count, 1);
  32                __sigpending = 0;
  33        }
  34}
  35
  36// Thread spamming us with signals
  37void *sig_thread(void *arg)
  38{
  39        int *done = (int*)arg;
  40        struct sigaction sigact = {.sa_handler = sig_handler, 0};
  41
  42        sigaction(SIGUSR1, &sigact, 0);
  43        while(1) {
  44                kill(getpid(), SIGUSR1);
  45                cmb();
  46                if (*done) return NULL;
  47        }
  48}
  49
  50int main(int argc, char **argv)
  51{
  52        int done = false;
  53
  54        pthread_t pth_handle, pth_handle2;
  55        // Spawn off a thread to spam us with signals
  56        pthread_create(&pth_handle, NULL, &sig_thread, &done);
  57        // Spawn off a thread to process those signals
  58        pthread_create(&pth_handle2, NULL, &count_signals, NULL);
  59
  60        // Sleep for 3 seconds by timing out on a futex
  61        int dummy = 0;
  62        struct timespec timeout = {.tv_sec = 3, 0};
  63
  64        futex(&dummy, FUTEX_WAIT, 0, &timeout, NULL, 0);
  65        // Force the signal tread to exit
  66        cmb();
  67        done = true;
  68        pthread_join(pth_handle, NULL);
  69        printf("count: %d\n", count);
  70        return 0;
  71}
  72