#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */
typedef int /*<<< orphan*/ sigset_t;

/* Variables and functions */
int /*<<< orphan*/ PTHREAD_CANCEL_ASYNCHRONOUS;
#define SIGALRM 129
#define SIGINT 128
int SIGTERM;
int /*<<< orphan*/ SIG_BLOCK;
int /*<<< orphan*/ alarm(int);
int /*<<< orphan*/ pthread_setcanceltype(int /*<<< orphan*/,
                                         int /*<<< orphan*/ *);
int /*<<< orphan*/ pthread_sigmask(int /*<<< orphan*/, int /*<<< orphan*/ *,
                                   int /*<<< orphan*/ *);
int /*<<< orphan*/ sigaddset(int /*<<< orphan*/ *, int);
int /*<<< orphan*/ sigalrm_handler();
int /*<<< orphan*/ sigfillset(int /*<<< orphan*/ *);
int /*<<< orphan*/ sigint_handler();
int /*<<< orphan*/ sigwait(int /*<<< orphan*/ *, int *);
void *signal_waiter(void *arg) {
  int signal;
  sigset_t set;
  arg = NULL;
  pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
  sigfillset(&set);
  pthread_sigmask(SIG_BLOCK, &set, NULL);
  sigaddset(&set, SIGINT);
  sigaddset(&set, SIGTERM);
  sigaddset(&set, SIGALRM);
  alarm(1);
  while (1) {
    sigwait(&set, &signal);
    switch (signal) {
    case SIGINT:
      sigint_handler();
      break;
    case SIGALRM:
      sigalrm_handler();
      break;
    }
  }
}


x86 assembly (clang, -O0):
<signal_waiter>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x8(%rbp)
movq   $0x0,-0x8(%rbp)
mov    0x2e4d(%rip),%rax
mov    (%rax),%edi
xor    %eax,%eax
mov    %eax,%esi
call   1080 <pthread_setcanceltype@plt>
lea    -0x10(%rbp),%rdi
call   1050 <sigfillset@plt>
mov    0x2e1a(%rip),%rax
mov    (%rax),%edi
lea    -0x10(%rbp),%rsi
xor    %eax,%eax
mov    %eax,%edx
call   1060 <pthread_sigmask@plt>
lea    -0x10(%rbp),%rdi
mov    $0x80,%esi
call   10a0 <sigaddset@plt>
mov    0x2e06(%rip),%rax
mov    (%rax),%esi
lea    -0x10(%rbp),%rdi
call   10a0 <sigaddset@plt>
lea    -0x10(%rbp),%rdi
mov    $0x81,%esi
call   10a0 <sigaddset@plt>
mov    $0x1,%edi
call   1040 <alarm@plt>
lea    -0x10(%rbp),%rdi
lea    -0xc(%rbp),%rsi
call   1090 <sigwait@plt>
mov    -0xc(%rbp),%eax
mov    %eax,-0x14(%rbp)
sub    $0x80,%eax
je     1233 <signal_waiter+0xb3>
jmp    1220 <signal_waiter+0xa0>
mov    -0x14(%rbp),%eax
sub    $0x81,%eax
je     123f <signal_waiter+0xbf>
jmp    1246 <signal_waiter+0xc6>
mov    $0x0,%al
call   1030 <sigint_handler@plt>
jmp    1246 <signal_waiter+0xc6>
mov    $0x0,%al
call   1070 <sigalrm_handler@plt>
jmp    11fd <signal_waiter+0x7d>

x86 assembly (clang, -O2):
<signal_waiter>:
push   %r14
push   %rbx
push   %rax
mov    0x2e5d(%rip),%rax
mov    (%rax),%edi
xor    %esi,%esi
call   1080 <pthread_setcanceltype@plt>
lea    0x4(%rsp),%r14
mov    %r14,%rdi
call   1050 <sigfillset@plt>
mov    0x2e28(%rip),%rax
mov    (%rax),%edi
mov    %r14,%rsi
xor    %edx,%edx
call   1060 <pthread_sigmask@plt>
mov    %r14,%rdi
mov    $0x80,%esi
call   10a0 <sigaddset@plt>
mov    0x2e18(%rip),%rax
mov    (%rax),%esi
mov    %r14,%rdi
call   10a0 <sigaddset@plt>
mov    %r14,%rdi
mov    $0x81,%esi
call   10a0 <sigaddset@plt>
mov    $0x1,%edi
call   1040 <alarm@plt>
mov    %rsp,%rbx
jmp    11f7 <signal_waiter+0x77>
xchg   %ax,%ax
xor    %eax,%eax
call   1070 <sigalrm_handler@plt>
mov    %r14,%rdi
mov    %rbx,%rsi
call   1090 <sigwait@plt>
mov    (%rsp),%eax
cmp    $0x81,%eax
je     11f0 <signal_waiter+0x70>
cmp    $0x80,%eax
jne    11f7 <signal_waiter+0x77>
xor    %eax,%eax
call   1030 <sigint_handler@plt>
jmp    11f7 <signal_waiter+0x77>

LLVM IR (-O0):
@PTHREAD_CANCEL_ASYNCHRONOUS = global i32 0
@SIG_BLOCK = global i32 0
@SIGTERM = global i32 0
define i8* @signal_waiter(i8* %0) {
%2 = alloca i8*
%3 = alloca i32
%4 = alloca i32
store i8* %0, i8** %2
store i8* null, i8** %2
%5 = load i32, i32* @PTHREAD_CANCEL_ASYNCHRONOUS
%6 = call i32 @pthread_setcanceltype(i32 %5, i32* null)
%7 = call i32 @sigfillset(i32* %4)
%8 = load i32, i32* @SIG_BLOCK
%9 = call i32 @pthread_sigmask(i32 %8, i32* %4, i32* null)
%10 = call i32 @sigaddset(i32* %4, i32 128)
%11 = load i32, i32* @SIGTERM
%12 = call i32 @sigaddset(i32* %4, i32 %11)
%13 = call i32 @sigaddset(i32* %4, i32 129)
%14 = call i32 @alarm(i32 1)
br label %15
15: ; preds = %1, %22
%16 = call i32 @sigwait(i32* %4, i32* %3)
%17 = load i32, i32* %3
switch i32 %17, label %22 [
i32 128, label %18
i32 129, label %20
]
18: ; preds = %15
%19 = call i32 (...) @sigint_handler()
br label %22
20: ; preds = %15
%21 = call i32 (...) @sigalrm_handler()
br label %22
22: ; preds = %15, %20, %18
br label %15
}

LLVM IR (-O2):
@PTHREAD_CANCEL_ASYNCHRONOUS = global i32 0
@SIG_BLOCK = global i32 0
@SIGTERM = global i32 0
define noalias i8* @signal_waiter(i8* nocapture readnone %0) {
%2 = alloca i32
%3 = alloca i32
%4 = bitcast i32* %2 to i8*
%5 = bitcast i32* %3 to i8*
%6 = load i32, i32* @PTHREAD_CANCEL_ASYNCHRONOUS
%7 = tail call i32 @pthread_setcanceltype(i32 %6, i32* null)
%8 = call i32 @sigfillset(i32* %3)
%9 = load i32, i32* @SIG_BLOCK
%10 = call i32 @pthread_sigmask(i32 %9, i32* %3, i32* null)
%11 = call i32 @sigaddset(i32* %3, i32 128)
%12 = load i32, i32* @SIGTERM
%13 = call i32 @sigaddset(i32* %3, i32 %12)
%14 = call i32 @sigaddset(i32* %3, i32 129)
%15 = call i32 @alarm(i32 1)
br label %16
16: ; preds = %19, %1
%17 = call i32 @sigwait(i32* %3, i32* %2)
%18 = load i32, i32* %2
switch i32 %18, label %19 [
i32 128, label %20
i32 129, label %22
]
19: ; preds = %16, %22, %20
br label %16
20: ; preds = %16
%21 = call i32 (...) @sigint_handler()
br label %19
22: ; preds = %16
%23 = call i32 (...) @sigalrm_handler()
br label %19
}