// File: /workspace/github_c_makefile_star2_O0/google[P]multichase/multiload.c
// Function: thread_start
static void *thread_start(void *data) {
  per_thread_t *args = data;

  // ensure every thread has a different RNG
  rng_init(args->x.thread_num);

  if (set_thread_affinity) {
    // find out which cpus we can run on and move us to an appropriate cpu
    cpu_set_t cpus;
    if (sched_getaffinity(0, sizeof(cpus), &cpus)) {
      perror("sched_getaffinity");
      exit(1);
    }
    int my_cpu;
    unsigned num = args->x.thread_num;
    for (my_cpu = 0; my_cpu < CPU_SETSIZE; ++my_cpu) {
      if (!CPU_ISSET(my_cpu, &cpus)) continue;
      if (num == 0) break;
      --num;
    }
    if (my_cpu == CPU_SETSIZE) {
      fprintf(stderr, "error: more threads than cpus available\n");
      exit(1);
    }
    CPU_ZERO(&cpus);
    CPU_SET(my_cpu, &cpus);
    if (sched_setaffinity(0, sizeof(cpus), &cpus)) {
      perror("sched_setaffinity");
      exit(1);
    }
  }
  if (args->x.run_test_type == RUN_CHASE) {
    // generate chases -- using a different mixer index for every
    // thread and for every parallel chase within a thread
    unsigned parallelism = args->x.chase->parallelism;
    for (unsigned par = 0; par < parallelism; ++par) {
      if (args->x.use_longer_chase) {
        args->x.cycle[par] = generate_chase_long(
            args->x.genchase_args, parallelism * args->x.thread_num + par,
            parallelism);
      } else {
        args->x.cycle[par] = generate_chase(
            args->x.genchase_args, parallelism * args->x.thread_num + par);
      }
    }
    // handle critword2 chases
    if (strcmp(args->x.chase->name, "critword2") == 0) {
      size_t offset = strtoul(args->x.extra_args, 0, 0);
      char *p = args->x.cycle[0];
      char *q = p;
      do {
        char *next = *(char **)p;
        *(void **)(p + offset) = next + offset;
        p = next;
      } while (p != q);
    }
    // handle critword chases
    if (strcmp(args->x.chase->name, "critword") == 0) {
      size_t offset = strtoul(args->x.extra_args, 0, 0);
      char *p = args->x.cycle[0];
      char *q = p;
      do {
        char *next = *(char **)p;
        *(void **)(p + offset) = next;
        *(void **)p = p + offset;
        p = next;
      } while (p != q);
    }
    // now flush our caches
    if (args->x.cache_flush_size) {
      size_t nr_elts = args->x.cache_flush_size / sizeof(size_t);
      size_t *p = args->x.flush_arena;
      size_t sum = 0;
      while (nr_elts) {
        sum += *p;
        ++p;
        --nr_elts;
      }
      args->x.dummy += sum;
    }
  } else {
    if (verbosity > 2)
      printf("thread_start(%d) memload generate buffers\n", args->x.thread_num);
    // generate buffers
    args->x.load_arena = (char *)alloc_arena_mmap(
                             page_size, use_thp,
                             args->x.load_total_memory + args->x.load_offset,
                             -1) + args->x.load_offset;
    memset(args->x.load_arena, 1,
           args->x.load_total_memory);  // ensure pages are mapped
  }

  if (verbosity > 2)
    printf("thread_start(%d) wait and/or wake up everyone\n",
           args->x.thread_num);
  // wait and/or wake up everyone if we're all ready
  pthread_mutex_lock(&wait_mutex);
  --nr_to_startup;
  if (nr_to_startup) {
    pthread_cond_wait(&wait_cond, &wait_mutex);
  } else {
    pthread_cond_broadcast(&wait_cond);
  }
  pthread_mutex_unlock(&wait_mutex);

  if (args->x.run_test_type == RUN_CHASE) {
    if (verbosity > 2) printf("thread_start: C(%d)\n", args->x.thread_num);
    args->x.chase->fn(data);
  } else {
    if (verbosity > 2) printf("thread_start: M(%d)\n", args->x.thread_num);
    args->x.memload->fn(data);
  }
  return NULL;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x130, %rsp            # imm = 0x130
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
movl (%rax), %edi
callq 0x403ae0
cmpl $0x0, 0x111537(%rip)    # 0x515130
je 0x403de7
xorl %edi, %edi
movl $0x80, %esi
leaq -0x90(%rbp), %rdx
callq 0x470d10
cmpl $0x0, %eax
je 0x403c2d
leaq 0xd9bd1(%rip), %rdi     # 0x4dd7ef
callq 0x41e380
movl $0x1, %edi
callq 0x41d0c0
movq -0x10(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x98(%rbp)
movl $0x0, -0x94(%rbp)
cmpl $0x400, -0x94(%rbp)     # imm = 0x400
jge 0x403d03
movslq -0x94(%rbp), %rax
movq %rax, -0xa0(%rbp)
movq -0xa0(%rbp), %rax
shrq $0x3, %rax
cmpq $0x80, %rax
jae 0x403cb4
movq -0xa0(%rbp), %rax
shrq $0x6, %rax
movq -0x90(%rbp,%rax,8), %rax
movq -0xa0(%rbp), %rcx
andq $0x3f, %rcx
movl $0x1, %edx
shlq %cl, %rdx
movq %rdx, %rcx
andq %rcx, %rax
cmpq $0x0, %rax
setne %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x11c(%rbp)
jmp 0x403cbe
xorl %eax, %eax
movl %eax, -0x11c(%rbp)
jmp 0x403cbe
movl -0x11c(%rbp), %eax
movl %eax, -0xa4(%rbp)
cmpl $0x0, -0xa4(%rbp)
jne 0x403cd5
jmp 0x403cef
cmpl $0x0, -0x98(%rbp)
jne 0x403ce0
jmp 0x403d03
movl -0x98(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x98(%rbp)
movl -0x94(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x94(%rbp)
jmp 0x403c43
cmpl $0x400, -0x94(%rbp)     # imm = 0x400
jne 0x403d31
movq $0x515748, %rax         # imm = 0x515748
movq (%rax), %rdi
leaq 0xd9ae1(%rip), %rsi     # 0x4dd801
movb $0x0, %al
callq 0x41e090
movl $0x1, %edi
callq 0x41d0c0
jmp 0x403d33
leaq -0x90(%rbp), %rdi
xorl %esi, %esi
movl $0x80, %edx
callq 0x4010b0
movslq -0x94(%rbp), %rax
movq %rax, -0xb0(%rbp)
movq -0xb0(%rbp), %rax
shrq $0x3, %rax
cmpq $0x80, %rax
jae 0x403d9e
movq -0xb0(%rbp), %rcx
andq $0x3f, %rcx
movl $0x1, %eax
shlq %cl, %rax
movq -0xb0(%rbp), %rcx
shrq $0x6, %rcx
orq -0x90(%rbp,%rcx,8), %rax
movq %rax, -0x90(%rbp,%rcx,8)
movq %rax, -0x128(%rbp)
jmp 0x403da9
xorl %eax, %eax
movq %rax, -0x128(%rbp)
jmp 0x403da9
movq -0x128(%rbp), %rax
movq %rax, -0xb8(%rbp)
xorl %edi, %edi
movl $0x80, %esi
leaq -0x90(%rbp), %rdx
callq 0x470d80
cmpl $0x0, %eax
je 0x403de5
leaq 0xd9a54(%rip), %rdi     # 0x4dd82a
callq 0x41e380
movl $0x1, %edi
callq 0x41d0c0
jmp 0x403de7
movq -0x10(%rbp), %rax
cmpl $0x0, 0x9c(%rax)
jne 0x4040d1
movq -0x10(%rbp), %rax
movq 0x80(%rax), %rax
movl 0x2c(%rax), %eax
movl %eax, -0xbc(%rbp)
movl $0x0, -0xc0(%rbp)
movl -0xc0(%rbp), %eax
cmpl -0xbc(%rbp), %eax
jae 0x403ec1
movq -0x10(%rbp), %rax
testb $0x1, 0x98(%rax)
je 0x403e75
movq -0x10(%rbp), %rax
movq 0x70(%rax), %rdi
movl -0xbc(%rbp), %eax
movq -0x10(%rbp), %rcx
imull (%rcx), %eax
addl -0xc0(%rbp), %eax
movl %eax, %eax
movl %eax, %esi
movl -0xbc(%rbp), %eax
movl %eax, %edx
callq 0x411510
movq %rax, %rdx
movq -0x10(%rbp), %rax
movl -0xc0(%rbp), %ecx
movq %rdx, 0x10(%rax,%rcx,8)
jmp 0x403eab
movq -0x10(%rbp), %rax
movq 0x70(%rax), %rdi
movl -0xbc(%rbp), %eax
movq -0x10(%rbp), %rcx
imull (%rcx), %eax
addl -0xc0(%rbp), %eax
movl %eax, %eax
movl %eax, %esi
callq 0x4111d0
movq %rax, %rdx
movq -0x10(%rbp), %rax
movl -0xc0(%rbp), %ecx
movq %rdx, 0x10(%rax,%rcx,8)
jmp 0x403ead
movl -0xc0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xc0(%rbp)
jmp 0x403e16
movq -0x10(%rbp), %rax
movq 0x80(%rax), %rax
movq 0x10(%rax), %rdi
leaq 0xd9681(%rip), %rsi     # 0x4dd558
callq 0x4010c0
cmpl $0x0, %eax
jne 0x403f6d
movq -0x10(%rbp), %rax
movq 0x60(%rax), %rdi
xorl %eax, %eax
movl %eax, %esi
xorl %edx, %edx
callq 0x41d870
movq %rax, -0xc8(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0xd0(%rbp)
movq -0xd0(%rbp), %rax
movq %rax, -0xd8(%rbp)
movq -0xd0(%rbp), %rax
movq (%rax), %rax
movq %rax, -0xe0(%rbp)
movq -0xe0(%rbp), %rdx
addq -0xc8(%rbp), %rdx
movq -0xd0(%rbp), %rax
movq -0xc8(%rbp), %rcx
movq %rdx, (%rax,%rcx)
movq -0xe0(%rbp), %rax
movq %rax, -0xd0(%rbp)
movq -0xd0(%rbp), %rax
cmpq -0xd8(%rbp), %rax
jne 0x403f1c
jmp 0x403f6d
movq -0x10(%rbp), %rax
movq 0x80(%rax), %rax
movq 0x10(%rax), %rdi
leaq 0xd9619(%rip), %rsi     # 0x4dd59c
callq 0x4010c0
cmpl $0x0, %eax
jne 0x40402a
movq -0x10(%rbp), %rax
movq 0x60(%rax), %rdi
xorl %eax, %eax
movl %eax, %esi
xorl %edx, %edx
callq 0x41d870
movq %rax, -0xe8(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0xf0(%rbp)
movq -0xf0(%rbp), %rax
movq %rax, -0xf8(%rbp)
movq -0xf0(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x100(%rbp)
movq -0x100(%rbp), %rdx
movq -0xf0(%rbp), %rax
movq -0xe8(%rbp), %rcx
movq %rdx, (%rax,%rcx)
movq -0xf0(%rbp), %rcx
addq -0xe8(%rbp), %rcx
movq -0xf0(%rbp), %rax
movq %rcx, (%rax)
movq -0x100(%rbp), %rax
movq %rax, -0xf0(%rbp)
movq -0xf0(%rbp), %rax
cmpq -0xf8(%rbp), %rax
jne 0x403fc8
jmp 0x40402a
movq -0x10(%rbp), %rax
cmpq $0x0, 0x90(%rax)
je 0x4040cc
movq -0x10(%rbp), %rax
movq 0x90(%rax), %rax
shrq $0x3, %rax
movq %rax, -0x108(%rbp)
movq -0x10(%rbp), %rax
movq 0x88(%rax), %rax
movq %rax, -0x110(%rbp)
movq $0x0, -0x118(%rbp)
cmpq $0x0, -0x108(%rbp)
je 0x4040b7
movq -0x110(%rbp), %rax
movq (%rax), %rax
addq -0x118(%rbp), %rax
movq %rax, -0x118(%rbp)
movq -0x110(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x110(%rbp)
movq -0x108(%rbp), %rax
addq $-0x1, %rax
movq %rax, -0x108(%rbp)
jmp 0x40406f
movq -0x118(%rbp), %rdx
movq -0x10(%rbp), %rax
movslq 0x68(%rax), %rcx
addq %rdx, %rcx
movl %ecx, 0x68(%rax)
jmp 0x404159
cmpl $0x2, 0x113288(%rip)    # 0x517360
jle 0x4040ee
movq -0x10(%rbp), %rax
movl (%rax), %esi
leaq 0xd9755(%rip), %rdi     # 0x4dd83c
movb $0x0, %al
callq 0x41e150
movq 0x11325b(%rip), %rdi    # 0x517350
movb 0x113269(%rip), %al     # 0x517364
movq -0x10(%rbp), %rcx
movq 0xb0(%rcx), %rdx
movq -0x10(%rbp), %rcx
addq 0xb8(%rcx), %rdx
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
andb $0x1, %al
movzbl %al, %esi
callq 0x411eb0
movq %rax, %rcx
movq -0x10(%rbp), %rax
addq 0xb8(%rax), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0xa8(%rax)
movq -0x10(%rbp), %rax
movq 0xa8(%rax), %rdi
movq -0x10(%rbp), %rax
movq 0xb0(%rax), %rdx
movl $0x1, %esi
callq 0x4010b0
cmpl $0x2, 0x113200(%rip)    # 0x517360
jle 0x404176
movq -0x10(%rbp), %rax
movl (%rax), %esi
leaq 0xd96f8(%rip), %rdi     # 0x4dd867
movb $0x0, %al
callq 0x41e150
leaq 0x113283(%rip), %rdi    # 0x517400
callq 0x439b30
movq 0x11326f(%rip), %rax    # 0x5173f8
addq $-0x1, %rax
movq %rax, 0x113264(%rip)    # 0x5173f8
cmpq $0x0, 0x11325c(%rip)    # 0x5173f8
je 0x4041b3
leaq 0x113283(%rip), %rdi    # 0x517428
leaq 0x113254(%rip), %rsi    # 0x517400
callq 0x436190
jmp 0x4041bf
leaq 0x11326e(%rip), %rdi    # 0x517428
callq 0x435b40
leaq 0x11323a(%rip), %rdi    # 0x517400
callq 0x43aa10
movq -0x10(%rbp), %rax
cmpl $0x0, 0x9c(%rax)
jne 0x40420b
cmpl $0x2, 0x113181(%rip)    # 0x517360
jle 0x4041f5
movq -0x10(%rbp), %rax
movl (%rax), %esi
leaq 0xd96a8(%rip), %rdi     # 0x4dd896
movb $0x0, %al
callq 0x41e150
movq -0x10(%rbp), %rax
movq 0x80(%rax), %rax
movq (%rax), %rax
movq -0x8(%rbp), %rdi
callq *%rax
jmp 0x40423c
cmpl $0x2, 0x11314e(%rip)    # 0x517360
jle 0x404228
movq -0x10(%rbp), %rax
movl (%rax), %esi
leaq 0xd968a(%rip), %rdi     # 0x4dd8ab
movb $0x0, %al
callq 0x41e150
movq -0x10(%rbp), %rax
movq 0xa0(%rax), %rax
movq (%rax), %rax
movq -0x8(%rbp), %rdi
callq *%rax
xorl %eax, %eax
addq $0x130, %rsp            # imm = 0x130
popq %rbp
retq
nopw (%rax,%rax)