/* $Id: fast_sigblock.c,v 1.2 2013/01/09 07:32:04 kostik Exp $ */ #include #include #include #include #include #include #include #include #include #include #ifndef FAST_SIGBLOCK_PEND #define FAST_SIGBLOCK_SETPTR 1 #define FAST_SIGBLOCK_UNBLOCK 2 #define FAST_SIGBLOCK_UNSETPTR 3 #define FAST_SIGBLOCK_PEND 0x1 #define FAST_SIGBLOCK_INC 0x10 #define SYS_fast_sigblock 533 #endif static uint32_t fsigblock; static int cnt; static int killer(void *arg) { static const char a[] = "."; pid_t worker_pid; int error, oldcnt, mcnt; worker_pid = *(pid_t *)arg; oldcnt = cnt; for (;;) { error = kill(worker_pid, SIGHUP); if (error != 0) errc(1, error, "kill"); /* usleep(300); */ mcnt = cnt; if (mcnt != oldcnt) { oldcnt = mcnt; if (mcnt % 100 != 0) write(2, a, 1); } } return (0); } static void fast_sigblock_loc(int cmd, uint32_t *ptr) { int error; error = syscall(SYS_fast_sigblock, cmd, ptr); if (error == -1) err(1, "SYS_fast_sigblock"); } static void handler(int signo) { static const char a[1] = "!"; uint32_t fs; fs = fsigblock; if (fs != 0) { printf("sig %d fsigblock %x\n", signo, fs); exit(1); } if (++cnt % 100 == 0) write(2, a, 1); } static void worker(void) { uint32_t oldval; fast_sigblock_loc(FAST_SIGBLOCK_SETPTR, &fsigblock); for (;;) { atomic_add_int(&fsigblock, FAST_SIGBLOCK_INC); /* usleep(700); */ oldval = atomic_fetchadd_int(&fsigblock, -FAST_SIGBLOCK_INC); if (oldval == (FAST_SIGBLOCK_PEND | FAST_SIGBLOCK_INC)) fast_sigblock_loc(FAST_SIGBLOCK_UNBLOCK, NULL); } } int main(void) { struct sigaction sa; char *stack; pid_t my_pid, killer_pid; bzero(&sa, sizeof(sa)); sa.sa_handler = handler; if (sigaction(SIGHUP, &sa, NULL) == -1) err(1, "sigaction"); stack = malloc(100 * getpagesize()); my_pid = getpid(); killer_pid = rfork_thread(RFPROC | RFMEM, stack, killer, &my_pid); if (killer_pid == -1) err(1, "rfork_thread"); worker(); return (0); }