/* $Id: fast_sigblock2.c,v 1.2 2013/01/09 07:31:56 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 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); raise(SIGHUP); /* 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); else if (oldval != FAST_SIGBLOCK_INC) errx(1, "oldval %x", oldval); } } int main(void) { struct sigaction sa; bzero(&sa, sizeof(sa)); sa.sa_handler = handler; if (sigaction(SIGHUP, &sa, NULL) == -1) err(1, "sigaction"); worker(); return (0); }