#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 */
struct timespec {
  int tv_sec;
  int tv_nsec;
  int /*<<< orphan*/ member_1;
  int /*<<< orphan*/ member_0;
};

/* Variables and functions */
scalar_t__ EINTR;
int /*<<< orphan*/ abort();
int /*<<< orphan*/ assert(int);
scalar_t__ errno;
int /*<<< orphan*/ fprintf(int /*<<< orphan*/, char *, char const *);
int nanosleep(struct timespec *, struct timespec *);
int /*<<< orphan*/ stderr;
char *strerror(scalar_t__);
void lgtd_sleep_monotonic_msecs(int msecs) {
  assert(msecs >= 0);
  struct timespec remainder = {.tv_sec = (msecs) / 1000,
                               .tv_nsec = ((msecs) % 1000) * 1000000},
                  request = {0, 0}, *rmtp = &remainder, *rqtp = &request;
  do {
    do {
      struct timespec *_tmp = rqtp;
      rqtp = rmtp;
      rmtp = _tmp;
    } while (0);
    int err = nanosleep(rqtp, rmtp);
    if (err && errno != EINTR) {
      const char *reason = strerror(errno);
      fprintf(stderr, "lightsd: nanosleep failed: %s.\n", reason);
      abort();
    }
  } while (remainder.tv_sec > 0 && remainder.tv_nsec > 0);
}


x86 assembly (clang, -O0):
<lgtd_sleep_monotonic_msecs>:
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
mov    %edi,-0x4(%rbp)
cmpl   $0x0,-0x4(%rbp)
setge  %al
and    $0x1,%al
movzbl %al,%edi
call   1060 <assert@plt>
mov    -0x4(%rbp),%eax
mov    $0x3e8,%ecx
cltd
idiv   %ecx
mov    %eax,-0x18(%rbp)
mov    -0x4(%rbp),%eax
mov    $0x3e8,%ecx
cltd
idiv   %ecx
imul   $0xf4240,%edx,%eax
mov    %eax,-0x14(%rbp)
movl   $0x0,-0x10(%rbp)
movl   $0x0,-0xc(%rbp)
lea    -0x28(%rbp),%rdi
xor    %esi,%esi
mov    $0x10,%edx
call   1050 <memset@plt>
lea    -0x18(%rbp),%rax
mov    %rax,-0x30(%rbp)
lea    -0x28(%rbp),%rax
mov    %rax,-0x38(%rbp)
jmp    11d1 <lgtd_sleep_monotonic_msecs+0x71>
mov    -0x38(%rbp),%rax
mov    %rax,-0x40(%rbp)
mov    -0x30(%rbp),%rax
mov    %rax,-0x38(%rbp)
mov    -0x40(%rbp),%rax
mov    %rax,-0x30(%rbp)
mov    -0x38(%rbp),%rdi
mov    -0x30(%rbp),%rsi
call   1040 <nanosleep@plt>
mov    %eax,-0x44(%rbp)
cmpl   $0x0,-0x44(%rbp)
je     1250 <lgtd_sleep_monotonic_msecs+0xf0>
mov    0x2dce(%rip),%rax
mov    (%rax),%rax
mov    0x2dbc(%rip),%rcx
cmp    (%rcx),%rax
je     1250 <lgtd_sleep_monotonic_msecs+0xf0>
mov    0x2db4(%rip),%rax
mov    (%rax),%rdi
call   1080 <strerror@plt>
mov    %rax,-0x50(%rbp)
mov    0x2da9(%rip),%rax
mov    (%rax),%edi
mov    -0x50(%rbp),%rdx
lea    0xdbc(%rip),%rsi
call   1070 <fprintf@plt>
mov    $0x0,%al
call   1030 <abort@plt>
jmp    1255 <lgtd_sleep_monotonic_msecs+0xf5>
xor    %eax,%eax
cmpl   $0x0,-0x18(%rbp)
mov    %al,-0x51(%rbp)
jle    126e <lgtd_sleep_monotonic_msecs+0x10e>
cmpl   $0x0,-0x14(%rbp)
setg   %al
mov    %al,-0x51(%rbp)
mov    -0x51(%rbp),%al
test   $0x1,%al
jne    11cc <lgtd_sleep_monotonic_msecs+0x6c>
add    $0x60,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<lgtd_sleep_monotonic_msecs>:
push   %r15
push   %r14
push   %r12
push   %rbx
sub    $0x28,%rsp
mov    %edi,%ebx
not    %edi
shr    $0x1f,%edi
call   1050 <assert@plt>
movslq %ebx,%rax
imul   $0x10624dd3,%rax,%rcx
mov    %rcx,%rdx
shr    $0x3f,%rdx
sar    $0x26,%rcx
add    %edx,%ecx
mov    %ecx,(%rsp)
imul   $0x3e8,%ecx,%ecx
sub    %ecx,%eax
imul   $0xf4240,%eax,%eax
mov    %eax,0x4(%rsp)
movq   $0x0,0x8(%rsp)
xorps  %xmm0,%xmm0
movaps %xmm0,0x10(%rsp)
mov    %rsp,%rbx
lea    0x10(%rsp),%rax
mov    0x2e25(%rip),%r15
mov    0x2e16(%rip),%r12
nopw   0x0(%rax,%rax,1)
mov    %rax,%r14
mov    %rbx,%rdi
mov    %rax,%rsi
call   1040 <nanosleep@plt>
test   %eax,%eax
je     11db <lgtd_sleep_monotonic_msecs+0x8b>
mov    (%r15),%rdi
cmp    (%r12),%rdi
jne    11fa <lgtd_sleep_monotonic_msecs+0xaa>
cmpl   $0x0,(%rsp)
jle    11ee <lgtd_sleep_monotonic_msecs+0x9e>
cmpl   $0x0,0x4(%rsp)
mov    %rbx,%rax
mov    %r14,%rbx
jg     11c0 <lgtd_sleep_monotonic_msecs+0x70>
add    $0x28,%rsp
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
ret
call   1070 <strerror@plt>
mov    0x2dda(%rip),%rcx
mov    (%rcx),%edi
lea    0xdf1(%rip),%rsi
mov    %rax,%rdx
call   1060 <fprintf@plt>
xor    %eax,%eax
call   1030 <abort@plt>

LLVM IR (-O0):
%struct.timespec = type { i32, i32, i32, i32 }
@errno = global i64 0
@EINTR = global i64 0
@stderr = global i32 0
@.str = [32 x i8] c"lightsd: nanosleep failed: %s.\0A\00"
define void @lgtd_sleep_monotonic_msecs(i32 %0) {
%2 = alloca i32
%3 = alloca %struct.timespec
%4 = alloca %struct.timespec
%5 = alloca %struct.timespec*
%6 = alloca %struct.timespec*
%7 = alloca %struct.timespec*
%8 = alloca i32
%9 = alloca i8*
store i32 %0, i32* %2
%10 = load i32, i32* %2
%11 = icmp sge i32 %10, 0
%12 = zext i1 %11 to i32
%13 = call i32 @assert(i32 %12)
%14 = getelementptr inbounds %struct.timespec, %struct.timespec* %3, i32 0, i32 0
%15 = load i32, i32* %2
%16 = sdiv i32 %15, 1000
store i32 %16, i32* %14
%17 = getelementptr inbounds %struct.timespec, %struct.timespec* %3, i32 0, i32 1
%18 = load i32, i32* %2
%19 = srem i32 %18, 1000
%20 = mul nsw i32 %19, 1000000
store i32 %20, i32* %17
%21 = getelementptr inbounds %struct.timespec, %struct.timespec* %3, i32 0, i32 2
store i32 0, i32* %21
%22 = getelementptr inbounds %struct.timespec, %struct.timespec* %3, i32 0, i32 3
store i32 0, i32* %22
%23 = bitcast %struct.timespec* %4 to i8*
store %struct.timespec* %3, %struct.timespec** %5
store %struct.timespec* %4, %struct.timespec** %6
br label %24
24: ; preds = %55, %1
br label %25
25: ; preds = %24
%26 = load %struct.timespec*, %struct.timespec** %6
store %struct.timespec* %26, %struct.timespec** %7
%27 = load %struct.timespec*, %struct.timespec** %5
store %struct.timespec* %27, %struct.timespec** %6
%28 = load %struct.timespec*, %struct.timespec** %7
store %struct.timespec* %28, %struct.timespec** %5
br label %29
29: ; preds = %25
%30 = load %struct.timespec*, %struct.timespec** %6
%31 = load %struct.timespec*, %struct.timespec** %5
%32 = call i32 @nanosleep(%struct.timespec* %30, %struct.timespec* %31)
store i32 %32, i32* %8
%33 = load i32, i32* %8
%34 = icmp ne i32 %33, 0
br i1 %34, label %35, label %46
35: ; preds = %29
%36 = load i64, i64* @errno
%37 = load i64, i64* @EINTR
%38 = icmp ne i64 %36, %37
br i1 %38, label %39, label %46
39: ; preds = %35
%40 = load i64, i64* @errno
%41 = call i8* @strerror(i64 %40)
store i8* %41, i8** %9
%42 = load i32, i32* @stderr
%43 = load i8*, i8** %9
%44 = call i32 @fprintf(i32 %42, i8* getelementptr inbounds ([32 x i8], [32 x i8]* @.str, i64 0, i64 0), i8* %43)
%45 = call i32 (...) @abort()
unreachable
46: ; preds = %35, %29
br label %47
47: ; preds = %46
%48 = getelementptr inbounds %struct.timespec, %struct.timespec* %3, i32 0, i32 0
%49 = load i32, i32* %48
%50 = icmp sgt i32 %49, 0
br i1 %50, label %51, label %55
51: ; preds = %47
%52 = getelementptr inbounds %struct.timespec, %struct.timespec* %3, i32 0, i32 1
%53 = load i32, i32* %52
%54 = icmp sgt i32 %53, 0
br label %55
55: ; preds = %51, %47
%56 = phi i1 [ false, %47 ], [ %54, %51 ]
br i1 %56, label %24, label %57
57: ; preds = %55
ret void
}

LLVM IR (-O2):
%struct.timespec = type { i32, i32, i32, i32 }
@errno = global i64 0
@EINTR = global i64 0
@stderr = global i32 0
@.str = [32 x i8] c"lightsd: nanosleep failed: %s.\0A\00"
define void @lgtd_sleep_monotonic_msecs(i32 %0) {
%2 = alloca %struct.timespec
%3 = alloca %struct.timespec
%4 = xor i32 %0, -1
%5 = lshr i32 %4, 31
%6 = tail call i32 @assert(i32 %5)
%7 = bitcast %struct.timespec* %2 to i8*
%8 = getelementptr inbounds %struct.timespec, %struct.timespec* %2, i64 0, i32 0
%9 = sdiv i32 %0, 1000
store i32 %9, i32* %8
%10 = getelementptr inbounds %struct.timespec, %struct.timespec* %2, i64 0, i32 1
%11 = srem i32 %0, 1000
%12 = mul nsw i32 %11, 1000000
store i32 %12, i32* %10
%13 = getelementptr inbounds %struct.timespec, %struct.timespec* %2, i64 0, i32 2
store i32 0, i32* %13
%14 = getelementptr inbounds %struct.timespec, %struct.timespec* %2, i64 0, i32 3
store i32 0, i32* %14
%15 = bitcast %struct.timespec* %3 to i8*
br label %16
16: ; preds = %30, %1
%17 = phi %struct.timespec* [ %3, %1 ], [ %18, %30 ]
%18 = phi %struct.timespec* [ %2, %1 ], [ %17, %30 ]
%19 = call i32 @nanosleep(%struct.timespec* %18, %struct.timespec* %17)
%20 = icmp eq i32 %19, 0
br i1 %20, label %30, label %21
21: ; preds = %16
%22 = load i64, i64* @errno
%23 = load i64, i64* @EINTR
%24 = icmp eq i64 %22, %23
br i1 %24, label %30, label %25
25: ; preds = %21
%26 = call i8* @strerror(i64 %22)
%27 = load i32, i32* @stderr
%28 = call i32 @fprintf(i32 %27, i8* getelementptr inbounds ([32 x i8], [32 x i8]* @.str, i64 0, i64 0), i8* %26)
%29 = call i32 (...) @abort()
unreachable
30: ; preds = %21, %16
%31 = load i32, i32* %8
%32 = icmp sgt i32 %31, 0
%33 = load i32, i32* %10
%34 = icmp sgt i32 %33, 0
%35 = select i1 %32, i1 %34, i1 false
br i1 %35, label %16, label %36
36: ; preds = %30
ret void
}