#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 */
typedef struct TYPE_4__ TYPE_2__;
typedef struct TYPE_3__ TYPE_1__;

/* Type definitions */
struct timespec {
  int /*<<< orphan*/ tv_nsec;
  int /*<<< orphan*/ tv_sec;
};
struct TYPE_3__ {
  int /*<<< orphan*/ tv_nsec;
  int /*<<< orphan*/ tv_sec;
};
struct TYPE_4__ {
  int /*<<< orphan*/ tv_nsec;
  int /*<<< orphan*/ tv_sec;
};
struct itimerspec {
  TYPE_1__ it_value;
  TYPE_2__ it_interval;
};

/* Variables and functions */
int /*<<< orphan*/ CLOCK_MONOTONIC;
int /*<<< orphan*/ close(int);
int timerfd_create(int /*<<< orphan*/, int /*<<< orphan*/);
int timerfd_settime(int, int /*<<< orphan*/, struct itimerspec *,
                    int /*<<< orphan*/ *);
int event_timer(struct timespec *time) {
  int fd;
  struct itimerspec iti;
  fd = timerfd_create(CLOCK_MONOTONIC, 0);
  if (fd == -1)
    return -1;
  iti.it_interval.tv_sec = time->tv_sec;
  iti.it_interval.tv_nsec = time->tv_nsec;
  iti.it_value.tv_sec = time->tv_sec;
  iti.it_value.tv_nsec = time->tv_nsec;
  if (timerfd_settime(fd, 0, &iti, NULL) == -1) {
    close(fd);
    return -1;
  }
  return fd;
}


x86 assembly (clang, -O0):
<event_timer>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x10(%rbp)
mov    0x2ea5(%rip),%rax
mov    (%rax),%edi
xor    %esi,%esi
call   1040 <timerfd_create@plt>
mov    %eax,-0x14(%rbp)
cmpl   $0xffffffff,-0x14(%rbp)
jne    1165 <event_timer+0x35>
movl   $0xffffffff,-0x4(%rbp)
jmp    11c0 <event_timer+0x90>
mov    -0x10(%rbp),%rax
mov    0x4(%rax),%eax
mov    %eax,-0x1c(%rbp)
mov    -0x10(%rbp),%rax
mov    (%rax),%eax
mov    %eax,-0x20(%rbp)
mov    -0x10(%rbp),%rax
mov    0x4(%rax),%eax
mov    %eax,-0x24(%rbp)
mov    -0x10(%rbp),%rax
mov    (%rax),%eax
mov    %eax,-0x28(%rbp)
mov    -0x14(%rbp),%edi
xor    %esi,%esi
lea    -0x28(%rbp),%rdx
xor    %eax,%eax
mov    %eax,%ecx
call   1050 <timerfd_settime@plt>
cmp    $0xffffffff,%eax
jne    11ba <event_timer+0x8a>
mov    -0x14(%rbp),%edi
call   1030 <close@plt>
movl   $0xffffffff,-0x4(%rbp)
jmp    11c0 <event_timer+0x90>
mov    -0x14(%rbp),%eax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<event_timer>:
push   %rbp
push   %r14
push   %rbx
sub    $0x10,%rsp
mov    %rdi,%r14
mov    0x2ea6(%rip),%rax
mov    (%rax),%edi
xor    %esi,%esi
call   1040 <timerfd_create@plt>
mov    $0xffffffff,%ebx
cmp    $0xffffffff,%eax
je     1184 <event_timer+0x54>
mov    %eax,%ebp
movq   (%r14),%xmm0
pshufd $0x44,%xmm0,%xmm0
movdqa %xmm0,(%rsp)
mov    %rsp,%rdx
mov    %eax,%edi
xor    %esi,%esi
xor    %ecx,%ecx
call   1050 <timerfd_settime@plt>
cmp    $0xffffffff,%eax
je     117d <event_timer+0x4d>
mov    %ebp,%ebx
jmp    1184 <event_timer+0x54>
mov    %ebp,%edi
call   1030 <close@plt>
mov    %ebx,%eax
add    $0x10,%rsp
pop    %rbx
pop    %r14
pop    %rbp
ret

LLVM IR (-O0):
%struct.timespec = type { i32, i32 }
%struct.itimerspec = type { %struct.TYPE_3__, %struct.TYPE_4__ }
%struct.TYPE_3__ = type { i32, i32 }
%struct.TYPE_4__ = type { i32, i32 }
@CLOCK_MONOTONIC = global i32 0
define i32 @event_timer(%struct.timespec* %0) {
%2 = alloca i32
%3 = alloca %struct.timespec*
%4 = alloca i32
%5 = alloca %struct.itimerspec
store %struct.timespec* %0, %struct.timespec** %3
%6 = load i32, i32* @CLOCK_MONOTONIC
%7 = call i32 @timerfd_create(i32 %6, i32 0)
store i32 %7, i32* %4
%8 = load i32, i32* %4
%9 = icmp eq i32 %8, -1
br i1 %9, label %10, label %11
10: ; preds = %1
store i32 -1, i32* %2
br label %40
11: ; preds = %1
%12 = load %struct.timespec*, %struct.timespec** %3
%13 = getelementptr inbounds %struct.timespec, %struct.timespec* %12, i32 0, i32 1
%14 = load i32, i32* %13
%15 = getelementptr inbounds %struct.itimerspec, %struct.itimerspec* %5, i32 0, i32 1
%16 = getelementptr inbounds %struct.TYPE_4__, %struct.TYPE_4__* %15, i32 0, i32 1
store i32 %14, i32* %16
%17 = load %struct.timespec*, %struct.timespec** %3
%18 = getelementptr inbounds %struct.timespec, %struct.timespec* %17, i32 0, i32 0
%19 = load i32, i32* %18
%20 = getelementptr inbounds %struct.itimerspec, %struct.itimerspec* %5, i32 0, i32 1
%21 = getelementptr inbounds %struct.TYPE_4__, %struct.TYPE_4__* %20, i32 0, i32 0
store i32 %19, i32* %21
%22 = load %struct.timespec*, %struct.timespec** %3
%23 = getelementptr inbounds %struct.timespec, %struct.timespec* %22, i32 0, i32 1
%24 = load i32, i32* %23
%25 = getelementptr inbounds %struct.itimerspec, %struct.itimerspec* %5, i32 0, i32 0
%26 = getelementptr inbounds %struct.TYPE_3__, %struct.TYPE_3__* %25, i32 0, i32 1
store i32 %24, i32* %26
%27 = load %struct.timespec*, %struct.timespec** %3
%28 = getelementptr inbounds %struct.timespec, %struct.timespec* %27, i32 0, i32 0
%29 = load i32, i32* %28
%30 = getelementptr inbounds %struct.itimerspec, %struct.itimerspec* %5, i32 0, i32 0
%31 = getelementptr inbounds %struct.TYPE_3__, %struct.TYPE_3__* %30, i32 0, i32 0
store i32 %29, i32* %31
%32 = load i32, i32* %4
%33 = call i32 @timerfd_settime(i32 %32, i32 0, %struct.itimerspec* %5, i32* null)
%34 = icmp eq i32 %33, -1
br i1 %34, label %35, label %38
35: ; preds = %11
%36 = load i32, i32* %4
%37 = call i32 @close(i32 %36)
store i32 -1, i32* %2
br label %40
38: ; preds = %11
%39 = load i32, i32* %4
store i32 %39, i32* %2
br label %40
40: ; preds = %38, %35, %10
%41 = load i32, i32* %2
ret i32 %41
}

LLVM IR (-O2):
%struct.timespec = type { i32, i32 }
%struct.itimerspec = type { %struct.TYPE_3__, %struct.TYPE_4__ }
%struct.TYPE_3__ = type { i32, i32 }
%struct.TYPE_4__ = type { i32, i32 }
@CLOCK_MONOTONIC = global i32 0
define i32 @event_timer(%struct.timespec* nocapture %0) {
%2 = alloca <4 x i32>
%3 = bitcast <4 x i32>* %2 to i8*
%4 = load i32, i32* @CLOCK_MONOTONIC
%5 = tail call i32 @timerfd_create(i32 %4, i32 0)
%6 = icmp eq i32 %5, -1
br i1 %6, label %16, label %7
7: ; preds = %1
%8 = bitcast <4 x i32>* %2 to %struct.itimerspec*
%9 = bitcast %struct.timespec* %0 to <2 x i32>*
%10 = load <2 x i32>, <2 x i32>* %9
%11 = shufflevector <2 x i32> %10, <2 x i32> poison, <4 x i32> <i32 0, i32 1, i32 0, i32 1>
store <4 x i32> %11, <4 x i32>* %2
%12 = call i32 @timerfd_settime(i32 %5, i32 0, %struct.itimerspec* %8, i32* null)
%13 = icmp eq i32 %12, -1
br i1 %13, label %14, label %16
14: ; preds = %7
%15 = call i32 @close(i32 %5)
br label %16
16: ; preds = %7, %1, %14
%17 = phi i32 [ -1, %14 ], [ -1, %1 ], [ %5, %7 ]
ret i32 %17
}