#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 {
  long tv_nsec;
  scalar_t__ tv_sec;
};

/* Variables and functions */
int nanosleep(struct timespec *, struct timespec *);
void busy_sleep(char *s, long ns) {
  struct timespec req;
  long i = 0;
  while (1) {
    req.tv_sec = 0;
    if (i + 50 > ns) {
      req.tv_nsec = (ns - i) * 100 + 50;
      i = ns;
    } else {
      req.tv_nsec = 5e8L;
      i += 50;
    }
    while (nanosleep(&req, &req) == -1)
      ;
    if (i == ns)
      break;
  }
}


x86 assembly (clang, -O0):
<busy_sleep>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
movq   $0x0,-0x28(%rbp)
movq   $0x0,-0x18(%rbp)
mov    -0x28(%rbp),%rax
add    $0x32,%rax
cmp    -0x10(%rbp),%rax
jle    1163 <busy_sleep+0x53>
mov    -0x10(%rbp),%rax
sub    -0x28(%rbp),%rax
imul   $0x64,%rax,%rax
add    $0x32,%rax
mov    %rax,-0x20(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x28(%rbp)
jmp    1177 <busy_sleep+0x67>
movq   $0x1dcd6500,-0x20(%rbp)
1d
mov    -0x28(%rbp),%rax
add    $0x32,%rax
mov    %rax,-0x28(%rbp)
jmp    117c <busy_sleep+0x6c>
lea    -0x20(%rbp),%rsi
mov    %rsi,%rdi
call   1030 <nanosleep@plt>
cmp    $0xffffffff,%eax
jne    1196 <busy_sleep+0x86>
jmp    117c <busy_sleep+0x6c>
mov    -0x28(%rbp),%rax
cmp    -0x10(%rbp),%rax
jne    11a9 <busy_sleep+0x99>
jmp    11ae <busy_sleep+0x9e>
jmp    1128 <busy_sleep+0x18>
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<busy_sleep>:
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x10,%rsp
mov    %rsi,%r14
xor    %r12d,%r12d
mov    $0x1dcd6500,%r15d
mov    %rsp,%rbx
nopl   0x0(%rax)
mov    %r14,%rax
sub    %r12,%rax
mov    %r12,%r13
add    $0x32,%r13
imul   $0x64,%rax,%rax
add    $0x32,%rax
cmp    %r14,%r13
cmovle %r15,%rax
movq   $0x0,0x8(%rsp)
mov    %r13,%r12
cmovg  %r14,%r12
mov    %rax,(%rsp)
mov    %rbx,%rdi
mov    %rbx,%rsi
call   1030 <nanosleep@plt>
cmp    $0xffffffff,%eax
je     1160 <busy_sleep+0x50>
cmp    %r14,%r13
jl     1130 <busy_sleep+0x20>
add    $0x10,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
%struct.timespec = type { i64, i64 }
define void @busy_sleep(i8* %0, i64 %1) {
%3 = alloca i8*
%4 = alloca i64
%5 = alloca %struct.timespec
%6 = alloca i64
store i8* %0, i8** %3
store i64 %1, i64* %4
store i64 0, i64* %6
br label %7
7: ; preds = %2, %35
%8 = getelementptr inbounds %struct.timespec, %struct.timespec* %5, i32 0, i32 1
store i64 0, i64* %8
%9 = load i64, i64* %6
%10 = add nsw i64 %9, 50
%11 = load i64, i64* %4
%12 = icmp sgt i64 %10, %11
br i1 %12, label %13, label %21
13: ; preds = %7
%14 = load i64, i64* %4
%15 = load i64, i64* %6
%16 = sub nsw i64 %14, %15
%17 = mul nsw i64 %16, 100
%18 = add nsw i64 %17, 50
%19 = getelementptr inbounds %struct.timespec, %struct.timespec* %5, i32 0, i32 0
store i64 %18, i64* %19
%20 = load i64, i64* %4
store i64 %20, i64* %6
br label %25
21: ; preds = %7
%22 = getelementptr inbounds %struct.timespec, %struct.timespec* %5, i32 0, i32 0
store i64 500000000, i64* %22
%23 = load i64, i64* %6
%24 = add nsw i64 %23, 50
store i64 %24, i64* %6
br label %25
25: ; preds = %21, %13
br label %26
26: ; preds = %29, %25
%27 = call i32 @nanosleep(%struct.timespec* %5, %struct.timespec* %5)
%28 = icmp eq i32 %27, -1
br i1 %28, label %29, label %30
29: ; preds = %26
br label %26
30: ; preds = %26
%31 = load i64, i64* %6
%32 = load i64, i64* %4
%33 = icmp eq i64 %31, %32
br i1 %33, label %34, label %35
34: ; preds = %30
br label %36
35: ; preds = %30
br label %7
36: ; preds = %34
ret void
}

LLVM IR (-O2):
%struct.timespec = type { i64, i64 }
define void @busy_sleep(i8* nocapture readnone %0, i64 %1) {
%3 = alloca %struct.timespec
%4 = bitcast %struct.timespec* %3 to i8*
%5 = getelementptr inbounds %struct.timespec, %struct.timespec* %3, i64 0, i32 1
%6 = getelementptr inbounds %struct.timespec, %struct.timespec* %3, i64 0, i32 0
br label %7
7: ; preds = %19, %2
%8 = phi i64 [ 0, %2 ], [ %15, %19 ]
store i64 0, i64* %5
%9 = add nsw i64 %8, 50
%10 = icmp sgt i64 %9, %1
%11 = sub nsw i64 %1, %8
%12 = mul nsw i64 %11, 100
%13 = add nsw i64 %12, 50
%14 = select i1 %10, i64 %13, i64 500000000
%15 = select i1 %10, i64 %1, i64 %9
store i64 %14, i64* %6
br label %16
16: ; preds = %16, %7
%17 = call i32 @nanosleep(%struct.timespec* %3, %struct.timespec* %3)
%18 = icmp eq i32 %17, -1
br i1 %18, label %16, label %19
19: ; preds = %16
%20 = icmp slt i64 %9, %1
br i1 %20, label %7, label %21
21: ; preds = %19
ret void
}