decompiled_code:
int uthread_yield()
{
ucontext_t *v0; // rdi
greg_t v1; // rax

v0 = current_thread;
v1 = current_thread[1].uc_mcontext.gregs[1];
if ( current_thread != (ucontext_t *)v1 )
{
if ( SLODWORD(current_thread[1].uc_mcontext.gregs[0]) >= *(_DWORD *)(v1 + 976) )
{
current_thread = (ucontext_t *)current_thread[1].uc_mcontext.gregs[1];
goto LABEL_6;
}
LODWORD(v1) = head_thread;
if ( current_thread != (ucontext_t *)head_thread )
{
current_thread = (ucontext_t *)head_thread;
LABEL_6:
LODWORD(v1) = swapcontext(v0, current_thread);
return v1;
}
}
return v1;
}

canonical_decompiled_code:
int func5()
{
ucontext_t *v0; // rdi
greg_t v1; // rax

v0 = current_thread;
v1 = current_thread[1].uc_mcontext.gregs[1];
if ( current_thread != (ucontext_t *)v1 )
{
if ( SLODWORD(current_thread[1].uc_mcontext.gregs[0]) >= *(_DWORD *)(v1 + 976) )
{
current_thread = (ucontext_t *)current_thread[1].uc_mcontext.gregs[1];
goto LABEL_6;
}
LODWORD(v1) = head_thread;
if ( current_thread != (ucontext_t *)head_thread )
{
current_thread = (ucontext_t *)head_thread;
LABEL_6:
LODWORD(v1) = swapcontext(v0, current_thread);
return v1;
}
}
return v1;
}

original_code:
void
uthread_yield (void)
{
  if (current_thread == current_thread->next)
      return;
  uthread_t *old_thread = current_thread;
  if( old_thread->pri < old_thread->next->pri )
    {
      if( current_thread == head_thread )
          return;
      else
          current_thread = head_thread;
    }
  else
      current_thread = old_thread->next;
  swapcontext (&old_thread->context, &current_thread->context);
}

canonical_original_code:
void uthread_yield()
{
  if (current_thread == current_thread->next)
      return;
  struct uthread *old_thread = current_thread;
  if( old_thread->pri < old_thread->next->pri )
    {
      if( current_thread == head_thread )
          return;
      else
          current_thread = head_thread;
    }
  else
      current_thread = old_thread->next;
  swapcontext (&old_thread->context, &current_thread->context);
}


decompiled_code:
int uthread_exit()
{
ucontext_t *v0; // rdx
ucontext_t *v1; // rsi
ucontext_t *v2; // rax
__int64 v3; // rcx
greg_t v4; // rax
ucontext_t *v6; // rax

v0 = current_thread;
v1 = (ucontext_t *)head_thread;
v2 = (ucontext_t *)head_thread;
if ( (ucontext_t *)head_thread == current_thread )
{
v6 = (ucontext_t *)current_thread[1].uc_mcontext.gregs[1];
current_thread = v6;
*(_QWORD *)(tail_thread + 984) = v6;
head_thread = (__int64)v6;
}
else
{
do
{
v3 = (__int64)v2;
v2 = (ucontext_t *)v2[1].uc_mcontext.gregs[1];
}
while ( v2 != current_thread );
v4 = current_thread[1].uc_mcontext.gregs[1];
if ( SLODWORD(current_thread[1].uc_mcontext.gregs[0]) >= *(_DWORD *)(v4 + 976) )
{
if ( (ucontext_t *)tail_thread == current_thread )
{
tail_thread = v3;
*(_QWORD *)(v3 + 984) = head_thread;
current_thread = v1;
}
else
{
current_thread = (ucontext_t *)current_thread[1].uc_mcontext.gregs[1];
*(_QWORD *)(v3 + 984) = v4;
}
}
else
{
*(_QWORD *)(v3 + 984) = v4;
current_thread = v1;
}
}
retired_thread = v0;
return setcontext(&cleanup_context);
}

canonical_decompiled_code:
int func7()
{
ucontext_t *v0; // rdx
ucontext_t *v1; // rsi
ucontext_t *v2; // rax
__int64 v3; // rcx
greg_t v4; // rax
ucontext_t *v6; // rax

v0 = current_thread;
v1 = (ucontext_t *)head_thread;
v2 = (ucontext_t *)head_thread;
if ( (ucontext_t *)head_thread == current_thread )
{
v6 = (ucontext_t *)current_thread[1].uc_mcontext.gregs[1];
current_thread = v6;
*(_QWORD *)(tail_thread + 984) = v6;
head_thread = (__int64)v6;
}
else
{
do
{
v3 = (__int64)v2;
v2 = (ucontext_t *)v2[1].uc_mcontext.gregs[1];
}
while ( v2 != current_thread );
v4 = current_thread[1].uc_mcontext.gregs[1];
if ( SLODWORD(current_thread[1].uc_mcontext.gregs[0]) >= *(_DWORD *)(v4 + 976) )
{
if ( (ucontext_t *)tail_thread == current_thread )
{
tail_thread = v3;
*(_QWORD *)(v3 + 984) = head_thread;
current_thread = v1;
}
else
{
current_thread = (ucontext_t *)current_thread[1].uc_mcontext.gregs[1];
*(_QWORD *)(v3 + 984) = v4;
}
}
else
{
*(_QWORD *)(v3 + 984) = v4;
current_thread = v1;
}
}
retired_thread = v0;
return setcontext(&cleanup_context);
}

original_code:
void
uthread_exit (void)
{
  uthread_t *old_thread = current_thread;
  if( old_thread == head_thread )
    {
      current_thread = current_thread->next;
      tail_thread->next = current_thread;
      head_thread = current_thread;
    }
  else
    {
      uthread_t *prev_thread = head_thread;
      while( prev_thread->next != old_thread )
        prev_thread = prev_thread->next;
      if( old_thread->pri < old_thread->next->pri )
        {
          prev_thread->next = old_thread->next;
          current_thread = head_thread;
        }
      else
        {
          if( old_thread == tail_thread )
            {
              tail_thread = prev_thread;
              prev_thread->next = head_thread;
              current_thread = head_thread;
            }
          else
            {
              current_thread = current_thread->next;
              prev_thread->next = current_thread;
            }
        }
    }
  retired_thread = old_thread;
  setcontext (&cleanup_context);
}

canonical_original_code:
void uthread_exit()
{
  struct uthread *old_thread = current_thread;
  if( old_thread == head_thread )
    {
      current_thread = current_thread->next;
      tail_thread->next = current_thread;
      head_thread = current_thread;
    }
  else
    {
      struct uthread *prev_thread = head_thread;
      while( prev_thread->next != old_thread )
        prev_thread = prev_thread->next;
      if( old_thread->pri < old_thread->next->pri )
        {
          prev_thread->next = old_thread->next;
          current_thread = head_thread;
        }
      else
        {
          if( old_thread == tail_thread )
            {
              tail_thread = prev_thread;
              prev_thread->next = head_thread;
              current_thread = head_thread;
            }
          else
            {
              current_thread = current_thread->next;
              prev_thread->next = current_thread;
            }
        }
    }
  retired_thread = old_thread;
  setcontext (&cleanup_context);
}

variable_types: struct uthread { struct ucontext_t { unsigned long uc_flags; struct ucontext_t *uc_link; struct stack_t { void *ss_sp; int ss_flags; unsigned long ss_size; } uc_stack; struct mcontext_t { long long gregs[23]; struct _libc_fpstate { unsigned short cwd; unsigned short swd; unsigned short ftw; unsigned short fop; unsigned long rip; unsigned long rdp; unsigned int mxcsr; unsigned int mxcr_mask; struct _libc_fpxreg { unsigned short significand[4]; unsigned short exponent; unsigned short __glibc_reserved1[3]; } _st[8]; struct _libc_xmmreg { unsigned int element[4]; } _xmm[16]; unsigned int __glibc_reserved1[24]; } *fpregs; unsigned long long __reserved1[8]; } uc_mcontext; struct __sigset_t { unsigned long __val[-1]; } uc_sigmask; struct _libc_fpstate __fpregs_mem; unsigned long long __ssp[4]; } context; void *stack; int pri; struct uthread *next; } *

return_type: void

user_defined_types: struct uthread { struct ucontext_t context; void *stack; int pri; struct uthread *next; }

user_defined_types: struct ucontext_t { unsigned long uc_flags; struct ucontext_t *uc_link; struct stack_t uc_stack; struct mcontext_t uc_mcontext; struct __sigset_t uc_sigmask; struct _libc_fpstate __fpregs_mem; unsigned long long __ssp[4]; }

user_defined_types: struct mcontext_t { long long gregs[23]; struct _libc_fpstate *fpregs; unsigned long long __reserved1[8]; }

user_defined_types: struct _libc_fpstate { unsigned short cwd; unsigned short swd; unsigned short ftw; unsigned short fop; unsigned long rip; unsigned long rdp; unsigned int mxcsr; unsigned int mxcr_mask; struct _libc_fpxreg _st[8]; struct _libc_xmmreg _xmm[16]; unsigned int __glibc_reserved1[24]; }


decompiled_code:
__int64 __fastcall thread_start(unsigned int a1)
{
printf("In thread_start %d , control transfered\n", a1);
return uthread_yield();
}

canonical_decompiled_code:
__int64 __fastcall func7(unsigned int a1)
{
printf("In thread_start %d , control transfered\n", a1);
return func20();
}

original_code:
void thread_start(int val) {
  printf("In thread_start %d , control transfered\n", val);
  uthread_yield();
}

variable_types: val int


original_code:
void list_init(list_t *l,
        int (*compare)(const void *key, const void *with),
        void (*data_delete)(void *data)){
  l->head = ((void *)0);
  l->tail = ((void *)0);
  l->length = 0;
  l->compare = compare;
  l->data_delete = data_delete;
}

canonical_original_code:
void list_init(struct list *l, int (*compare)(void *key, void *with), void (*data_delete)(void *data)){
  l->head = ((void *)0);
  l->tail = ((void *)0);
  l->length = 0;
  l->compare = compare;
  l->data_delete = data_delete;
}

variable_types: struct list { struct list_item { struct list_item *prev; void *data; } *head; unsigned int length; int (*compare)(void *key, void *with); void (*data_delete)(void *data); } *

variable_types:
compare
int (*)(void *key, void *with)

user_defined_types: struct list { struct list_item *head; unsigned int length; int (*compare)(void *key, void *with); void (*data_delete)(void *data); }


decompiled_code:
__int64 __fastcall list_visit_items(__int64 *a1, __int64 (__fastcall *a2)(__int64))
{
__int64 i; // rbx
__int64 result; // rax

for ( i = *a1; i; i = *(_QWORD *)(i + 8) )
result = a2(i);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func10(__int64 *a1, __int64 (__fastcall *a2)(__int64))
{
__int64 i; // rbx
__int64 result; // rax

for ( i = *a1; i; i = *(_QWORD *)(i + 8) )
result = a2(i);
return result;
}

original_code:
void list_visit_items(list_t *l, void (*visitor)(void *v)){
  list_item_t *current_item = l->head;
  while(current_item != ((void *)0))
    {
      visitor(current_item);
      current_item = current_item->next;
    }
}

canonical_original_code:
void list_visit_items(struct list *l, void (*visitor)(void *v)){
  struct list_item *current_item = l->head;
  while(current_item != ((void *)0))
    {
      visitor(current_item);
      current_item = current_item->next;
    }
}

variable_types:
visitor
void (*)(void *v)

variable_types: struct list_item { struct list_item *prev; void *data; } *


decompiled_code:
void __fastcall list_insert_tail(__int64 a1, __int64 a2)
{
_QWORD *v2; // rax
_QWORD *v3; // rbp

v2 = malloc(0x18uLL);
if ( !v2 )
{
perror("malloc failed to create new object.");
exit(-1);
}
v3 = v2;
list_item_init(v2, a2);
if ( *(_DWORD *)(a1 + 16) )
{
*(_QWORD *)(*(_QWORD *)(a1 + 8) + 8LL) = v3;
*v3 = *(_QWORD *)(a1 + 8);
}
else
{
*(_QWORD *)a1 = v3;
}
*(_QWORD *)(a1 + 8) = v3;
++*(_DWORD *)(a1 + 16);
}

canonical_decompiled_code:
void __fastcall func11(__int64 a1, __int64 a2)
{
_QWORD *v2; // rax
_QWORD *v3; // rbp

v2 = malloc(0x18uLL);
if ( !v2 )
{
perror("malloc failed to create new object.");
exit(-1);
}
v3 = v2;
func8(v2, a2);
if ( *(_DWORD *)(a1 + 16) )
{
*(_QWORD *)(*(_QWORD *)(a1 + 8) + 8LL) = v3;
*v3 = *(_QWORD *)(a1 + 8);
}
else
{
*(_QWORD *)a1 = v3;
}
*(_QWORD *)(a1 + 8) = v3;
++*(_DWORD *)(a1 + 16);
}

original_code:
void list_insert_tail(list_t *l, void *v){
  list_item_t *new = malloc(sizeof(list_item_t));
  if(new == ((void *)0))
    {
      perror("malloc failed to create new object.");
      exit(-1);
    }
  list_item_init(new, v);
  if( l->length == 0 )
    {
      l->head = new;
      l->tail = new;
    }
  else
    {
      l->tail->next = new;
      new->prev = l->tail;
      l->tail = new;
    }
  l->length++;
}

canonical_original_code:
void list_insert_tail(struct list *l, void *v){
  struct list_item *new = malloc(sizeof(list_item_t));
  if(new == ((void *)0))
    {
      perror("malloc failed to create new object.");
      exit(-1);
    }
  list_item_init(new, v);
  if( l->length == 0 )
    {
      l->head = new;
      l->tail = new;
    }
  else
    {
      l->tail->next = new;
      new->prev = l->tail;
      l->tail = new;
    }
  l->length++;
}

variable_types:
v
void *

user_defined_types: struct list_item { struct list_item *prev; void *data; }


original_code:
void thread_init(thread_t *t,
                 int pri, int id){
  t->pri = pri;
  t->id = id;
}

canonical_original_code:
void thread_init(struct thread *t, int pri, int id){
  t->pri = pri;
  t->id = id;
}

variable_types: struct thread { struct ucontext_t { unsigned long uc_flags; struct ucontext_t *uc_link; struct stack_t { void *ss_sp; int ss_flags; unsigned long ss_size; } uc_stack; struct mcontext_t { long long gregs[23]; struct _libc_fpstate { unsigned short cwd; unsigned short swd; unsigned short ftw; unsigned short fop; unsigned long rip; unsigned long rdp; unsigned int mxcsr; unsigned int mxcr_mask; struct _libc_fpxreg { unsigned short significand[4]; unsigned short exponent; unsigned short __glibc_reserved1[3]; } _st[8]; struct _libc_xmmreg { unsigned int element[4]; } _xmm[16]; unsigned int __glibc_reserved1[24]; } *fpregs; unsigned long long __reserved1[8]; } uc_mcontext; struct __sigset_t { unsigned long __val[-1]; } uc_sigmask; struct _libc_fpstate __fpregs_mem; unsigned long long __ssp[4]; } ucp; char ucp_stack[1048576]; int pri; int id; _Bool free_stack; } *

variable_types: pri int

variable_types: id int

user_defined_types: struct thread { struct ucontext_t ucp; char ucp_stack[1048576]; int pri; int id; _Bool free_stack; }


decompiled_code:
void __fastcall thread_data_delete(__int64 a1)
{
free(*(void **)(a1 + 16));
}

canonical_decompiled_code:
void __fastcall func15(__int64 a1)
{
free(*(void **)(a1 + 16));
}

original_code:
void thread_data_delete(void *item){
  thread_t *t = (thread_t*)(((list_item_t*)item)->data);
  free(t);
}

canonical_original_code:
void thread_data_delete(void *item){
  struct thread *t = (thread_t*)(((list_item_t*)item)->data);
  free(t);
}

variable_types:
item
void *

user_defined_types: struct stack_t { void *ss_sp; int ss_flags; unsigned long ss_size; }

user_defined_types: struct __sigset_t { unsigned long __val[-1]; }

user_defined_types: struct _libc_fpxreg { unsigned short significand[4]; unsigned short exponent; unsigned short __glibc_reserved1[3]; }

user_defined_types: struct _libc_xmmreg { unsigned int element[4]; }


decompiled_code:
__int64 __fastcall thread_compare_pri(__int64 a1, __int64 a2)
{
return (unsigned int)(*(_DWORD *)(*(_QWORD *)(*(_QWORD *)a1 + 16LL) + 1049544LL)
- *(_DWORD *)(*(_QWORD *)(*(_QWORD *)a2 + 16LL) + 1049544LL));
}

original_code:
int thread_compare_pri(const void *key, const void *with){
  list_item_t **arg1 = (list_item_t**)key;
  list_item_t **arg2 = (list_item_t**)with;
  thread_t *t1 = (thread_t*)((*arg1)->data);
  thread_t *t2 = (thread_t*)((*arg2)->data);
  int pri1 = t1->pri;
  int pri2 = t2->pri;
  return pri1 - pri2;
}

canonical_original_code:
int thread_compare_pri(void *key, void *with){
  struct list_item **arg1 = (list_item_t**)key;
  struct list_item **arg2 = (list_item_t**)with;
  struct thread *t1 = (thread_t*)((*arg1)->data);
  struct thread *t2 = (thread_t*)((*arg2)->data);
  int pri1 = t1->pri;
  int pri2 = t2->pri;
  return pri1 - pri2;
}

variable_types:
key
void *

variable_types:
with
void *

variable_types: struct list_item { struct list_item *prev; void *data; } **

return_type: int


decompiled_code:
void uthread_handler(void)
{
while ( 1 )
{
list_remove_head((__int64)&thread_queue);
if ( !dword_504490 )
break;
setcontext(*(const ucontext_t **)(thread_queue + 16));
}
}

canonical_decompiled_code:
void func17(void)
{
while ( 1 )
{
func13((__int64)&thread_queue);
if ( !dword_504490 )
break;
setcontext(*(const ucontext_t **)(thread_queue + 16));
}
}

original_code:
void uthread_handler(){
  while( 1 ){
    list_remove_head(&thread_queue);
    if( thread_queue.length >= 1 )
      {
        list_item_t *new_head = thread_queue.head;
        thread_t *head_thread = (thread_t*)new_head->data;
        setcontext(&(head_thread->ucp));
      }
    else break;
  }
}

canonical_original_code:
void uthread_handler(){
  while( 1 ){
    list_remove_head(&thread_queue);
    if( thread_queue.length >= 1 )
      {
        struct list_item *new_head = thread_queue.head;
        struct thread *head_thread = (thread_t*)new_head->data;
        setcontext(&(head_thread->ucp));
      }
    else break;
  }
}


main

canonical_name: main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
puts("Testing uthread_create");
uthread_init("Testing uthread_create", argv);
uthread_create(thread_start, 1LL, 0LL);
uthread_yield();
puts("back in main");
uthread_exit();
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
puts("Testing uthread_create");
func18("Testing uthread_create", argv);
func19(thread_start, 1LL, 0LL);
func20();
puts("back in main");
func21();
return 0;
}

original_code:
int main(int argc, char **argv) {
  printf("Testing uthread_create\n");
  uthread_init();
  uthread_create(thread_start, 1, 0);
  uthread_yield();
  printf("back in main\n");
  uthread_exit();
  return 0;
}

variable_types: argc int

variable_types:
argv
char **


decompiled_code:
int uthread_init()
{
ucontext_t *v0; // rbx

list_init((__int64)&thread_queue, (__int64)thread_compare_pri, (__int64)thread_data_delete);
getcontext(&handler);
handler.uc_stack.ss_sp = &handler_stack;
handler.uc_stack.ss_size = 0x100000LL;
handler.uc_link = 0LL;
makecontext(&handler, uthread_handler, 0);
v0 = (ucontext_t *)malloc(0x1003D8uLL);
thread_id = 0;
thread_init((__int64)v0, 0, 0);
++thread_id;
list_insert_tail((__int64)&thread_queue, (__int64)v0);
return getcontext(v0);
}

canonical_decompiled_code:
int func18()
{
ucontext_t *v0; // rbx

func9((__int64)&thread_queue, (__int64)thread_compare_pri, (__int64)thread_data_delete);
getcontext(&handler);
handler.uc_stack.ss_sp = &handler_stack;
handler.uc_stack.ss_size = 0x100000LL;
handler.uc_link = 0LL;
makecontext(&handler, uthread_handler, 0);
v0 = (ucontext_t *)malloc(0x1003D8uLL);
thread_id = 0;
func14((__int64)v0, 0, 0);
++thread_id;
func11((__int64)&thread_queue, (__int64)v0);
return getcontext(v0);
}

original_code:
void uthread_init(){
  list_init(&thread_queue, thread_compare_pri, thread_data_delete);
  getcontext(&handler);
  handler.uc_stack.ss_sp = &handler_stack;
  handler.uc_stack.ss_size = sizeof(handler_stack);
  handler.uc_link = ((void *)0);
  makecontext(&handler, uthread_handler, 0);
  thread_t *new_thread = malloc( sizeof(thread_t) );
  thread_id = 0;
  thread_init(new_thread, 0, thread_id);
  thread_id++;
  list_insert_tail(&thread_queue, new_thread);
  ucontext_t *new_context = &new_thread->ucp;
  getcontext(new_context);
}

canonical_original_code:
void uthread_init(){
  list_init(&thread_queue, thread_compare_pri, thread_data_delete);
  getcontext(&handler);
  handler.uc_stack.ss_sp = &handler_stack;
  handler.uc_stack.ss_size = sizeof(handler_stack);
  handler.uc_link = ((void *)0);
  makecontext(&handler, uthread_handler, 0);
  struct thread *new_thread = malloc( sizeof(thread_t) );
  thread_id = 0;
  thread_init(new_thread, 0, thread_id);
  thread_id++;
  list_insert_tail(&thread_queue, new_thread);
  struct ucontext_t *new_context = &new_thread->ucp;
  getcontext(new_context);
}

variable_types: struct ucontext_t { unsigned long uc_flags; struct ucontext_t *uc_link; struct stack_t { void *ss_sp; int ss_flags; unsigned long ss_size; } uc_stack; struct mcontext_t { long long gregs[23]; struct _libc_fpstate { unsigned short cwd; unsigned short swd; unsigned short ftw; unsigned short fop; unsigned long rip; unsigned long rdp; unsigned int mxcsr; unsigned int mxcr_mask; struct _libc_fpxreg { unsigned short significand[4]; unsigned short exponent; unsigned short __glibc_reserved1[3]; } _st[8]; struct _libc_xmmreg { unsigned int element[4]; } _xmm[16]; unsigned int __glibc_reserved1[24]; } *fpregs; unsigned long long __reserved1[8]; } uc_mcontext; struct __sigset_t { unsigned long __val[-1]; } uc_sigmask; struct _libc_fpstate __fpregs_mem; unsigned long long __ssp[4]; } *


decompiled_code:
__int64 __fastcall uthread_create(void (*a1)(void), unsigned int a2, int a3)
{
ucontext_t *v4; // rbx

v4 = (ucontext_t *)malloc(0x1003D8uLL);
thread_init((__int64)v4, a3, thread_id);
++thread_id;
v4->uc_stack.ss_sp = &v4[1].uc_stack.ss_size;
v4->uc_stack.ss_size = 0x100000LL;
v4->uc_link = 0LL;
getcontext(v4);
makecontext(v4, a1, 1, a2);
list_insert_tail((__int64)&thread_queue, (__int64)v4);
return (unsigned int)(thread_id - 1);
}

canonical_decompiled_code:
__int64 __fastcall func19(void (*a1)(void), unsigned int a2, int a3)
{
ucontext_t *v4; // rbx

v4 = (ucontext_t *)malloc(0x1003D8uLL);
func14((__int64)v4, a3, thread_id);
++thread_id;
v4->uc_stack.ss_sp = &v4[1].uc_stack.ss_size;
v4->uc_stack.ss_size = 0x100000LL;
v4->uc_link = 0LL;
getcontext(v4);
makecontext(v4, a1, 1, a2);
func11((__int64)&thread_queue, (__int64)v4);
return (unsigned int)(thread_id - 1);
}

original_code:
int uthread_create(void (*func)(int), int val, int pri){
  thread_t *new_thread = malloc( sizeof(thread_t) );
  thread_init(new_thread, pri, thread_id);
  thread_id++;
  new_thread->ucp.uc_stack.ss_sp = new_thread->ucp_stack;
  new_thread->ucp.uc_stack.ss_size = sizeof(new_thread->ucp_stack);
  new_thread->ucp.uc_link = ((void *)0);
  ucontext_t *new_context = &(new_thread->ucp);
  getcontext(new_context);
  makecontext(new_context, func, 1, val);
  list_insert_tail(&thread_queue, new_thread);
  return thread_id - 1;
}

canonical_original_code:
int uthread_create(void (*func)(int), int val, int pri){
  struct thread *new_thread = malloc( sizeof(thread_t) );
  thread_init(new_thread, pri, thread_id);
  thread_id++;
  new_thread->ucp.uc_stack.ss_sp = new_thread->ucp_stack;
  new_thread->ucp.uc_stack.ss_size = sizeof(new_thread->ucp_stack);
  new_thread->ucp.uc_link = ((void *)0);
  struct ucontext_t *new_context = &(new_thread->ucp);
  getcontext(new_context);
  makecontext(new_context, func, 1, val);
  list_insert_tail(&thread_queue, new_thread);
  return thread_id - 1;
}

variable_types:
func
void (*)(int)


decompiled_code:
int uthread_yield()
{
ucontext_t *v0; // rbx
int result; // eax

if ( (unsigned int)dword_504490 > 1 )
{
v0 = *(ucontext_t **)(thread_queue + 16);
list_rotate_one((__int64)&thread_queue);
result = swapcontext(v0, *(const ucontext_t **)(thread_queue + 16));
}
return result;
}

canonical_decompiled_code:
int func20()
{
ucontext_t *v0; // rbx
int result; // eax

if ( (unsigned int)dword_504490 > 1 )
{
v0 = *(ucontext_t **)(thread_queue + 16);
list_rotate_one((__int64)&thread_queue);
result = swapcontext(v0, *(const ucontext_t **)(thread_queue + 16));
}
return result;
}

original_code:
void uthread_yield(){
  if( thread_queue.length > 1)
    {
      list_item_t *cur_head = thread_queue.head;
      thread_t *cur_thread = (thread_t*)cur_head->data;
      list_rotate_one(&thread_queue);
      list_item_t *new_head = thread_queue.head;
      thread_t *new_thread = (thread_t*)new_head->data;
      ucontext_t *old_context = &cur_thread->ucp;
      ucontext_t *new_context = &new_thread->ucp;
      swapcontext(old_context, new_context);
    }
}

canonical_original_code:
void uthread_yield(){
  if( thread_queue.length > 1)
    {
      struct list_item *cur_head = thread_queue.head;
      struct thread *cur_thread = (thread_t*)cur_head->data;
      list_rotate_one(&thread_queue);
      struct list_item *new_head = thread_queue.head;
      struct thread *new_thread = (thread_t*)new_head->data;
      struct ucontext_t *old_context = &cur_thread->ucp;
      struct ucontext_t *new_context = &new_thread->ucp;
      swapcontext(old_context, new_context);
    }
}


decompiled_code:
int uthread_exit()
{
return setcontext(&handler);
}

canonical_decompiled_code:
int func21()
{
return setcontext(&handler);
}

original_code:
void uthread_exit(){
  setcontext(&handler);
}


whaleInit

decompiled_code:
_QWORD *whaleInit()
{
_QWORD *v0; // rbx
_QWORD *result; // rax

v0 = malloc(0x18uLL);
maleQ = (__int64)v0;
result = malloc(0x18uLL);
femaleQ = (__int64)result;
v0[1] = 0LL;
v0[2] = v0;
*(_DWORD *)v0 = 0;
result[1] = 0LL;
result[2] = result;
*(_DWORD *)result = 0;
return result;
}

canonical_decompiled_code:
_QWORD *func7()
{
_QWORD *v0; // rbx
_QWORD *result; // rax

v0 = malloc(0x18uLL);
maleQ = (__int64)v0;
result = malloc(0x18uLL);
femaleQ = (__int64)result;
v0[1] = 0LL;
v0[2] = v0;
*(_DWORD *)v0 = 0;
result[1] = 0LL;
result[2] = result;
*(_DWORD *)result = 0;
return result;
}

original_code:
void whaleInit(){
 maleQ=(whale_t*) malloc(sizeof(whale_t));
 femaleQ=(whale_t*) malloc(sizeof(whale_t));
 maleQ->next=((void *)0);
 maleQ->tail=maleQ;
 maleQ->id=0;
 femaleQ->next=((void *)0);
 femaleQ->tail=femaleQ;
 femaleQ->id=0;
}

canonical_original_code:
void whaleInit(){
 maleQ=(struct whale *) malloc(sizeof(whale_t));
 femaleQ=(struct whale *) malloc(sizeof(whale_t));
 maleQ->next=((void *)0);
 maleQ->tail=maleQ;
 maleQ->id=0;
 femaleQ->next=((void *)0);
 femaleQ->tail=femaleQ;
 femaleQ->id=0;
}

user_defined_types: struct whale { int id; struct whale *next; struct whale *tail; }


decompiled_code:
int __fastcall create_male(unsigned int a1)
{
double v1; // xmm0_8
int v2; // ebp
_QWORD *v3; // rax
__int64 v4; // rdx
__int64 v5; // rax
double v6; // xmm0_8
double v7; // xmm0_8
__int64 v8; // rcx
__int64 v9; // rdx
double v10; // xmm0_8
unsigned int v11; // ebp
double v12; // xmm0_8
_QWORD *v13; // rax
__int64 v14; // rdx

pthread_mutex_lock(&stdout_lock);
v1 = elapsed_time();
printf("(t=%f) %d: %s\n", v1, a1, "Male Created");
fflush(stdout);
pthread_mutex_unlock(&stdout_lock);
v2 = male;
if ( male <= 0 )
{
if ( female > 0 )
{
pthread_mutex_lock(&stdout_lock);
v10 = elapsed_time();
printf("(t=%f) %d: %s\n", v10, a1, "Found Mate");
fflush(stdout);
pthread_mutex_unlock(&stdout_lock);
pthread_mutex_lock(&stdout_lock);
v11 = *(_DWORD *)femaleQ;
v12 = elapsed_time();
printf("(t=%f) %d: %s\n", v12, v11, "Found Mate");
fflush(stdout);
pthread_mutex_unlock(&stdout_lock);
++male;
v13 = malloc(0x18uLL);
*(_DWORD *)v13 = a1;
v14 = maleQ;
*(_QWORD *)(*(_QWORD *)(maleQ + 16) + 8LL) = v13;
*(_QWORD *)(v14 + 16) = v13;
v13[1] = 0LL;
sem_post(&male_avail);
LODWORD(v5) = sem_wait(&maker_avail);
return v5;
}
goto LABEL_3;
}
if ( female <= 0 )
{
LABEL_3:
v3 = malloc(0x18uLL);
*(_DWORD *)v3 = a1;
v4 = maleQ;
*(_QWORD *)(*(_QWORD *)(maleQ + 16) + 8LL) = v3;
*(_QWORD *)(v4 + 16) = v3;
v3[1] = 0LL;
male = v2 + 1;
sem_post(&male_avail);
sem_wait(&fem_avail);
LODWORD(v5) = sem_wait(&maker_avail);
return v5;
}
sem_post(&maker_avail);
pthread_mutex_lock(&stdout_lock);
v6 = elapsed_time();
printf("(t=%f) %d: %s\n", v6, a1, "Became MatchMaker");
fflush(stdout);
pthread_mutex_unlock(&stdout_lock);
pthread_mutex_lock(&stdout_lock);
v7 = elapsed_time();
printf("(t=%f) %d: %s\n", v7, a1, "Mated");
fflush(stdout);
pthread_mutex_unlock(&stdout_lock);
v5 = maleQ;
v8 = *(_QWORD *)(maleQ + 8);
if ( v8 && (v9 = femaleQ, *(_QWORD *)(femaleQ + 8)) )
{
*(_QWORD *)(v8 + 16) = *(_QWORD *)(maleQ + 16);
maleQ = *(_QWORD *)(v5 + 8);
*(_QWORD *)(*(_QWORD *)(v9 + 8) + 16LL) = *(_QWORD *)(v9 + 16);
v5 = *(_QWORD *)(v9 + 8);
femaleQ = v5;
}
else
{
maleQ = 0LL;
femaleQ = 0LL;
}
--male;
--female;
return v5;
}

canonical_decompiled_code:
int __fastcall func9(unsigned int a1)
{
double v1; // xmm0_8
int v2; // ebp
_QWORD *v3; // rax
__int64 v4; // rdx
__int64 v5; // rax
double v6; // xmm0_8
double v7; // xmm0_8
__int64 v8; // rcx
__int64 v9; // rdx
double v10; // xmm0_8
unsigned int v11; // ebp
double v12; // xmm0_8
_QWORD *v13; // rax
__int64 v14; // rdx

pthread_mutex_lock(&stdout_lock);
v1 = func8();
printf("(t=%f) %d: %s\n", v1, a1, "Male Created");
fflush(stdout);
pthread_mutex_unlock(&stdout_lock);
v2 = male;
if ( male <= 0 )
{
if ( female > 0 )
{
pthread_mutex_lock(&stdout_lock);
v10 = func8();
printf("(t=%f) %d: %s\n", v10, a1, "Found Mate");
fflush(stdout);
pthread_mutex_unlock(&stdout_lock);
pthread_mutex_lock(&stdout_lock);
v11 = *(_DWORD *)femaleQ;
v12 = func8();
printf("(t=%f) %d: %s\n", v12, v11, "Found Mate");
fflush(stdout);
pthread_mutex_unlock(&stdout_lock);
++male;
v13 = malloc(0x18uLL);
*(_DWORD *)v13 = a1;
v14 = maleQ;
*(_QWORD *)(*(_QWORD *)(maleQ + 16) + 8LL) = v13;
*(_QWORD *)(v14 + 16) = v13;
v13[1] = 0LL;
sem_post(&male_avail);
LODWORD(v5) = sem_wait(&maker_avail);
return v5;
}
goto LABEL_3;
}
if ( female <= 0 )
{
LABEL_3:
v3 = malloc(0x18uLL);
*(_DWORD *)v3 = a1;
v4 = maleQ;
*(_QWORD *)(*(_QWORD *)(maleQ + 16) + 8LL) = v3;
*(_QWORD *)(v4 + 16) = v3;
v3[1] = 0LL;
male = v2 + 1;
sem_post(&male_avail);
sem_wait(&fem_avail);
LODWORD(v5) = sem_wait(&maker_avail);
return v5;
}
sem_post(&maker_avail);
pthread_mutex_lock(&stdout_lock);
v6 = func8();
printf("(t=%f) %d: %s\n", v6, a1, "Became MatchMaker");
fflush(stdout);
pthread_mutex_unlock(&stdout_lock);
pthread_mutex_lock(&stdout_lock);
v7 = func8();
printf("(t=%f) %d: %s\n", v7, a1, "Mated");
fflush(stdout);
pthread_mutex_unlock(&stdout_lock);
v5 = maleQ;
v8 = *(_QWORD *)(maleQ + 8);
if ( v8 && (v9 = femaleQ, *(_QWORD *)(femaleQ + 8)) )
{
*(_QWORD *)(v8 + 16) = *(_QWORD *)(maleQ + 16);
maleQ = *(_QWORD *)(v5 + 8);
*(_QWORD *)(*(_QWORD *)(v9 + 8) + 16LL) = *(_QWORD *)(v9 + 16);
v5 = *(_QWORD *)(v9 + 8);
femaleQ = v5;
}
else
{
maleQ = 0LL;
femaleQ = 0LL;
}
--male;
--female;
return v5;
}

original_code:
void create_male(int id) {
 pthread_mutex_lock(&stdout_lock); printf("(t=%f) %d: %s\n", elapsed_time(), id, "Male Created"); fflush(stdout); pthread_mutex_unlock(&stdout_lock);
 if((male > 0) && (female > 0))
 {
  sem_post(&maker_avail);
  pthread_mutex_lock(&stdout_lock); printf("(t=%f) %d: %s\n", elapsed_time(), id, "Became MatchMaker"); fflush(stdout); pthread_mutex_unlock(&stdout_lock);
  pthread_mutex_lock(&stdout_lock); printf("(t=%f) %d: %s\n", elapsed_time(), id, "Mated"); fflush(stdout); pthread_mutex_unlock(&stdout_lock);
  if(maleQ->next!=((void *)0) && femaleQ->next!=((void *)0))
  {
   maleQ->next->tail=maleQ->tail;
   maleQ=maleQ->next;
   femaleQ->next->tail=femaleQ->tail;
   femaleQ=femaleQ->next;
  }
  else{
   maleQ=((void *)0);
   femaleQ=((void *)0);
   }
  male--;
  female--;
 }
 else if (female > 0)
 {
  pthread_mutex_lock(&stdout_lock); printf("(t=%f) %d: %s\n", elapsed_time(), id, "Found Mate"); fflush(stdout); pthread_mutex_unlock(&stdout_lock);
  pthread_mutex_lock(&stdout_lock); printf("(t=%f) %d: %s\n", elapsed_time(), femaleQ->id, "Found Mate"); fflush(stdout); pthread_mutex_unlock(&stdout_lock);
  male++;
  whale_t *temp=(whale_t*) malloc(sizeof(whale_t));
  temp->id =id;
maleQ->tail->next=temp;
maleQ->tail=temp;
maleQ->tail->next=((void *)0);
  sem_post(&male_avail);
  sem_wait(&maker_avail);
 }
 else
 {
 whale_t *temp=(whale_t*) malloc(sizeof(whale_t));
  temp->id =id;
maleQ->tail->next=temp;
maleQ->tail=temp;
maleQ->tail->next=((void *)0);
  male++;
  sem_post(&male_avail);
  sem_wait(&fem_avail);
  sem_wait(&maker_avail);
 }
}

canonical_original_code:
void create_male(int id) {
 pthread_mutex_lock(&stdout_lock); printf("(t=%f) %d: %s\n", elapsed_time(), id, "Male Created"); fflush(stdout); pthread_mutex_unlock(&stdout_lock);
 if((male > 0) && (female > 0))
 {
  sem_post(&maker_avail);
  pthread_mutex_lock(&stdout_lock); printf("(t=%f) %d: %s\n", elapsed_time(), id, "Became MatchMaker"); fflush(stdout); pthread_mutex_unlock(&stdout_lock);
  pthread_mutex_lock(&stdout_lock); printf("(t=%f) %d: %s\n", elapsed_time(), id, "Mated"); fflush(stdout); pthread_mutex_unlock(&stdout_lock);
  if(maleQ->next!=((void *)0) && femaleQ->next!=((void *)0))
  {
   maleQ->next->tail=maleQ->tail;
   maleQ=maleQ->next;
   femaleQ->next->tail=femaleQ->tail;
   femaleQ=femaleQ->next;
  }
  else{
   maleQ=((void *)0);
   femaleQ=((void *)0);
   }
  male--;
  female--;
 }
 else if (female > 0)
 {
  pthread_mutex_lock(&stdout_lock); printf("(t=%f) %d: %s\n", elapsed_time(), id, "Found Mate"); fflush(stdout); pthread_mutex_unlock(&stdout_lock);
  pthread_mutex_lock(&stdout_lock); printf("(t=%f) %d: %s\n", elapsed_time(), femaleQ->id, "Found Mate"); fflush(stdout); pthread_mutex_unlock(&stdout_lock);
  male++;
  struct whale *temp = (whale_t*) malloc(sizeof(whale_t));
  temp->id =id;
maleQ->tail->next=temp;
maleQ->tail=temp;
maleQ->tail->next=((void *)0);
  sem_post(&male_avail);
  sem_wait(&maker_avail);
 }
 else
 {
 struct whale *temp = (whale_t*) malloc(sizeof(whale_t));
  temp->id =id;
maleQ->tail->next=temp;
maleQ->tail=temp;
maleQ->tail->next=((void *)0);
  male++;
  sem_post(&male_avail);
  sem_wait(&fem_avail);
  sem_wait(&maker_avail);
 }
}

variable_types: struct whale { int id; struct whale *next; struct whale *tail; } *


decompiled_code:
int __fastcall create_female(unsigned int a1)
{
double v1; // xmm0_8
unsigned int v2; // ebp
double v3; // xmm0_8
double v4; // xmm0_8
_QWORD *v5; // rax
__int64 v6; // rdx
__int64 v7; // rax
double v8; // xmm0_8
double v9; // xmm0_8
__int64 v10; // rcx
__int64 v11; // rdx
_QWORD *v12; // rax
__int64 v13; // rdx

pthread_mutex_lock(&stdout_lock);
v1 = elapsed_time();
printf("(t=%f) %d: %s\n", v1, a1, "Female Created");
fflush(stdout);
pthread_mutex_unlock(&stdout_lock);
if ( male <= 0 )
{
v12 = malloc(0x18uLL);
*(_DWORD *)v12 = a1;
v13 = femaleQ;
*(_QWORD *)(*(_QWORD *)(femaleQ + 16) + 8LL) = v12;
*(_QWORD *)(v13 + 16) = v12;
v12[1] = 0LL;
++female;
sem_post(&fem_avail);
sem_wait(&male_avail);
LODWORD(v7) = sem_wait(&maker_avail);
}
else if ( female > 0 )
{
sem_post(&maker_avail);
pthread_mutex_lock(&stdout_lock);
v8 = elapsed_time();
printf("(t=%f) %d: %s\n", v8, a1, "Became MatchMaker");
fflush(stdout);
pthread_mutex_unlock(&stdout_lock);
pthread_mutex_lock(&stdout_lock);
v9 = elapsed_time();
printf("(t=%f) %d: %s\n", v9, a1, "Mated");
fflush(stdout);
pthread_mutex_unlock(&stdout_lock);
v7 = maleQ;
v10 = *(_QWORD *)(maleQ + 8);
if ( v10 && (v11 = femaleQ, *(_QWORD *)(femaleQ + 8)) )
{
*(_QWORD *)(v10 + 16) = *(_QWORD *)(maleQ + 16);
maleQ = *(_QWORD *)(v7 + 8);
*(_QWORD *)(*(_QWORD *)(v11 + 8) + 16LL) = *(_QWORD *)(v11 + 16);
v7 = *(_QWORD *)(v11 + 8);
femaleQ = v7;
}
else
{
maleQ = 0LL;
femaleQ = 0LL;
}
--male;
--female;
}
else
{
pthread_mutex_lock(&stdout_lock);
v2 = *(_DWORD *)maleQ;
v3 = elapsed_time();
printf("(t=%f) %d: %s\n", v3, v2, "Found Mate");
fflush(stdout);
pthread_mutex_unlock(&stdout_lock);
pthread_mutex_lock(&stdout_lock);
v4 = elapsed_time();
printf("(t=%f) %d: %s\n", v4, a1, "Found Mate");
fflush(stdout);
pthread_mutex_unlock(&stdout_lock);
v5 = malloc(0x18uLL);
*(_DWORD *)v5 = a1;
v6 = femaleQ;
*(_QWORD *)(*(_QWORD *)(femaleQ + 16) + 8LL) = v5;
*(_QWORD *)(v6 + 16) = v5;
v5[1] = 0LL;
++female;
sem_post(&fem_avail);
LODWORD(v7) = sem_wait(&maker_avail);
}
return v7;
}

canonical_decompiled_code:
int __fastcall func10(unsigned int a1)
{
double v1; // xmm0_8
unsigned int v2; // ebp
double v3; // xmm0_8
double v4; // xmm0_8
_QWORD *v5; // rax
__int64 v6; // rdx
__int64 v7; // rax
double v8; // xmm0_8
double v9; // xmm0_8
__int64 v10; // rcx
__int64 v11; // rdx
_QWORD *v12; // rax
__int64 v13; // rdx

pthread_mutex_lock(&stdout_lock);
v1 = func8();
printf("(t=%f) %d: %s\n", v1, a1, "Female Created");
fflush(stdout);
pthread_mutex_unlock(&stdout_lock);
if ( male <= 0 )
{
v12 = malloc(0x18uLL);
*(_DWORD *)v12 = a1;
v13 = femaleQ;
*(_QWORD *)(*(_QWORD *)(femaleQ + 16) + 8LL) = v12;
*(_QWORD *)(v13 + 16) = v12;
v12[1] = 0LL;
++female;
sem_post(&fem_avail);
sem_wait(&male_avail);
LODWORD(v7) = sem_wait(&maker_avail);
}
else if ( female > 0 )
{
sem_post(&maker_avail);
pthread_mutex_lock(&stdout_lock);
v8 = func8();
printf("(t=%f) %d: %s\n", v8, a1, "Became MatchMaker");
fflush(stdout);
pthread_mutex_unlock(&stdout_lock);
pthread_mutex_lock(&stdout_lock);
v9 = func8();
printf("(t=%f) %d: %s\n", v9, a1, "Mated");
fflush(stdout);
pthread_mutex_unlock(&stdout_lock);
v7 = maleQ;
v10 = *(_QWORD *)(maleQ + 8);
if ( v10 && (v11 = femaleQ, *(_QWORD *)(femaleQ + 8)) )
{
*(_QWORD *)(v10 + 16) = *(_QWORD *)(maleQ + 16);
maleQ = *(_QWORD *)(v7 + 8);
*(_QWORD *)(*(_QWORD *)(v11 + 8) + 16LL) = *(_QWORD *)(v11 + 16);
v7 = *(_QWORD *)(v11 + 8);
femaleQ = v7;
}
else
{
maleQ = 0LL;
femaleQ = 0LL;
}
--male;
--female;
}
else
{
pthread_mutex_lock(&stdout_lock);
v2 = *(_DWORD *)maleQ;
v3 = func8();
printf("(t=%f) %d: %s\n", v3, v2, "Found Mate");
fflush(stdout);
pthread_mutex_unlock(&stdout_lock);
pthread_mutex_lock(&stdout_lock);
v4 = func8();
printf("(t=%f) %d: %s\n", v4, a1, "Found Mate");
fflush(stdout);
pthread_mutex_unlock(&stdout_lock);
v5 = malloc(0x18uLL);
*(_DWORD *)v5 = a1;
v6 = femaleQ;
*(_QWORD *)(*(_QWORD *)(femaleQ + 16) + 8LL) = v5;
*(_QWORD *)(v6 + 16) = v5;
v5[1] = 0LL;
++female;
sem_post(&fem_avail);
LODWORD(v7) = sem_wait(&maker_avail);
}
return v7;
}

original_code:
void create_female(int id) {
 pthread_mutex_lock(&stdout_lock); printf("(t=%f) %d: %s\n", elapsed_time(), id, "Female Created"); fflush(stdout); pthread_mutex_unlock(&stdout_lock);
 if((male > 0) && (female > 0))
 {
  sem_post(&maker_avail);
  pthread_mutex_lock(&stdout_lock); printf("(t=%f) %d: %s\n", elapsed_time(), id, "Became MatchMaker"); fflush(stdout); pthread_mutex_unlock(&stdout_lock);
  pthread_mutex_lock(&stdout_lock); printf("(t=%f) %d: %s\n", elapsed_time(), id, "Mated"); fflush(stdout); pthread_mutex_unlock(&stdout_lock);
  if(maleQ->next!=((void *)0) && femaleQ->next!=((void *)0))
  {
   maleQ->next->tail=maleQ->tail;
   maleQ=maleQ->next;
   femaleQ->next->tail=femaleQ->tail;
   femaleQ=femaleQ->next;
  }
  else{
   maleQ=((void *)0);
   femaleQ=((void *)0);
   }
  male--;
  female--;
 }
 else if (male > 0)
 {
  pthread_mutex_lock(&stdout_lock); printf("(t=%f) %d: %s\n", elapsed_time(), maleQ->id, "Found Mate"); fflush(stdout); pthread_mutex_unlock(&stdout_lock);
  pthread_mutex_lock(&stdout_lock); printf("(t=%f) %d: %s\n", elapsed_time(), id, "Found Mate"); fflush(stdout); pthread_mutex_unlock(&stdout_lock);
   whale_t *temp=(whale_t*) malloc(sizeof(whale_t));
  temp->id =id;
femaleQ->tail->next=temp;
femaleQ->tail=temp;
femaleQ->tail->next=((void *)0);
  female++;
  sem_post(&fem_avail);
  sem_wait(&maker_avail);
 }
 else
 {
whale_t *temp=(whale_t*) malloc(sizeof(whale_t));
  temp->id =id;
femaleQ->tail->next=temp;
femaleQ->tail=temp;
femaleQ->tail->next=((void *)0);
  female++;
  sem_post(&fem_avail);
  sem_wait(&male_avail);
  sem_wait(&maker_avail);
 }
}

canonical_original_code:
void create_female(int id) {
 pthread_mutex_lock(&stdout_lock); printf("(t=%f) %d: %s\n", elapsed_time(), id, "Female Created"); fflush(stdout); pthread_mutex_unlock(&stdout_lock);
 if((male > 0) && (female > 0))
 {
  sem_post(&maker_avail);
  pthread_mutex_lock(&stdout_lock); printf("(t=%f) %d: %s\n", elapsed_time(), id, "Became MatchMaker"); fflush(stdout); pthread_mutex_unlock(&stdout_lock);
  pthread_mutex_lock(&stdout_lock); printf("(t=%f) %d: %s\n", elapsed_time(), id, "Mated"); fflush(stdout); pthread_mutex_unlock(&stdout_lock);
  if(maleQ->next!=((void *)0) && femaleQ->next!=((void *)0))
  {
   maleQ->next->tail=maleQ->tail;
   maleQ=maleQ->next;
   femaleQ->next->tail=femaleQ->tail;
   femaleQ=femaleQ->next;
  }
  else{
   maleQ=((void *)0);
   femaleQ=((void *)0);
   }
  male--;
  female--;
 }
 else if (male > 0)
 {
  pthread_mutex_lock(&stdout_lock); printf("(t=%f) %d: %s\n", elapsed_time(), maleQ->id, "Found Mate"); fflush(stdout); pthread_mutex_unlock(&stdout_lock);
  pthread_mutex_lock(&stdout_lock); printf("(t=%f) %d: %s\n", elapsed_time(), id, "Found Mate"); fflush(stdout); pthread_mutex_unlock(&stdout_lock);
   struct whale *temp = (whale_t*) malloc(sizeof(whale_t));
  temp->id =id;
femaleQ->tail->next=temp;
femaleQ->tail=temp;
femaleQ->tail->next=((void *)0);
  female++;
  sem_post(&fem_avail);
  sem_wait(&maker_avail);
 }
 else
 {
struct whale *temp = (whale_t*) malloc(sizeof(whale_t));
  temp->id =id;
femaleQ->tail->next=temp;
femaleQ->tail=temp;
femaleQ->tail->next=((void *)0);
  female++;
  sem_post(&fem_avail);
  sem_wait(&male_avail);
  sem_wait(&maker_avail);
 }
}


decompiled_code:
void __fastcall __noreturn create_whale(void *a1)
{
unsigned int v1; // ebx

v1 = *(_DWORD *)a1;
if ( (rand() & 1) != 0 )
create_male(v1);
else
create_female(v1);
pthread_exit(0LL);
}

canonical_decompiled_code:
void __fastcall __noreturn func11(void *a1)
{
unsigned int v1; // ebx

v1 = *(_DWORD *)a1;
if ( (rand() & 1) != 0 )
func9(v1);
else
func10(v1);
pthread_exit(0LL);
}

original_code:
void *create_whale(void* arg) {
 int id = *((int *) arg);
 if (rand() & 1) {
  create_male(id);
 } else {
  create_female(id);
 }
 pthread_exit(((void *)0));
}

canonical_original_code:
void *create_whale(void *arg) {
 int id = *((int *) arg);
 if (rand() & 1) {
  create_male(id);
 } else {
  create_female(id);
 }
 pthread_exit(((void *)0));
}

variable_types:
arg
void *

return_type: void *


decompiled_code:
int __fastcall whale_sleep(int a1)
{
return usleep(1000 * a1);
}

canonical_decompiled_code:
int __fastcall func12(int a1)
{
return usleep(1000 * a1);
}

original_code:
void whale_sleep(int sem_wait_time_ms) {
 usleep(sem_wait_time_ms * 1000);
}


decompiled_code:
double elapsed_time()
{
struct timeval v1; // [rsp+0h] [rbp-18h] BYREF

gettimeofday(&v1, 0LL);
return (double)(LODWORD(v1.tv_usec) - LODWORD(time0.tv_usec)) / 1000000.0
+ (double)(LODWORD(v1.tv_sec) - LODWORD(time0.tv_sec));
}

canonical_decompiled_code:
double func8()
{
struct timeval v1; // [rsp+0h] [rbp-18h] BYREF

gettimeofday(&v1, 0LL);
return (double)(LODWORD(v1.tv_usec) - LODWORD(time0.tv_usec)) / 1000000.0
+ (double)(LODWORD(v1.tv_sec) - LODWORD(time0.tv_sec));
}

original_code:
double elapsed_time() {
 struct timeval tv;
 gettimeofday(&tv, ((void *)0));
 return (tv.tv_sec - time0.tv_sec + (tv.tv_usec - time0.tv_usec) / 1.e6 );
}

variable_types: struct timeval { long tv_sec; long tv_usec; }

return_type: double


usage

decompiled_code:
void __fastcall __noreturn usage(const char *a1)
{
fprintf(
stderr,
"Usage: %s num_whales sem_wait_time\n"
"\tnum_whales - the total number of whales to create\n"
"\tsem_wait_time - the amount of time to sem_wait before creating another whale (seconds)\n",
a1);
exit(-1);
}

canonical_decompiled_code:
void __fastcall __noreturn func13(const char *a1)
{
fprintf(
stderr,
"Usage: %s num_whales sem_wait_time\n"
"\tnum_whales - the total number of whales to create\n"
"\tsem_wait_time - the amount of time to sem_wait before creating another whale (seconds)\n",
a1);
exit(-1);
}

original_code:
void usage(char *arg0) {
 fprintf(stderr, "Usage: %s num_whales sem_wait_time\n"
     "\tnum_whales - the total number of whales to create\n"
      "\tsem_wait_time - the amount of time to sem_wait before creating another whale (seconds)\n",
     arg0);
 exit(-1);
}


main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // ebx
int v4; // ebp
int arg; // [rsp+4h] [rbp-74h] BYREF
pthread_t newthread; // [rsp+8h] [rbp-70h] BYREF
pthread_attr_t attr; // [rsp+10h] [rbp-68h] BYREF
struct timeval tv; // [rsp+50h] [rbp-28h] BYREF

if ( argc != 3 )
usage(*argv);
whaleInit();
pthread_mutex_init(&stdout_lock, 0LL);
gettimeofday(&tv, 0LL);
srand(tv.tv_usec);
gettimeofday(&time0, 0LL);
v3 = atoi(argv[1]);
v4 = (int)(atof(argv[2]) * 1000.0);
sem_init(&male_avail, 0, 0);
sem_init(&fem_avail, 0, 0);
sem_init(&maker_avail, 0, 0);
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, 1);
for ( arg = 0; arg < v3; ++arg )
{
whale_sleep(v4);
pthread_create(&newthread, &attr, (void *(*)(void *))create_whale, &arg);
}
whale_sleep((int)((double)v4 * 10.0));
pthread_mutex_destroy(&stdout_lock);
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // ebx
int v4; // ebp
int arg; // [rsp+4h] [rbp-74h] BYREF
pthread_t newthread; // [rsp+8h] [rbp-70h] BYREF
pthread_attr_t attr; // [rsp+10h] [rbp-68h] BYREF
struct timeval tv; // [rsp+50h] [rbp-28h] BYREF

if ( argc != 3 )
func13(*argv);
func7();
pthread_mutex_init(&stdout_lock, 0LL);
gettimeofday(&tv, 0LL);
srand(tv.tv_usec);
gettimeofday(&time0, 0LL);
v3 = atoi(argv[1]);
v4 = (int)(atof(argv[2]) * 1000.0);
sem_init(&male_avail, 0, 0);
sem_init(&fem_avail, 0, 0);
sem_init(&maker_avail, 0, 0);
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, 1);
for ( arg = 0; arg < v3; ++arg )
{
func12(v4);
pthread_create(&newthread, &attr, (void *(*)(void *))create_whale, &arg);
}
func12((int)((double)v4 * 10.0));
pthread_mutex_destroy(&stdout_lock);
return 0;
}

original_code:
int main(int argc, char *argv[]) {
 if (argc != 3) {
  usage(argv[0]);
 }
 whaleInit();
 pthread_mutex_init(&stdout_lock, ((void *)0));
 struct timeval tv;
 gettimeofday(&tv, ((void *)0));
 srand(tv.tv_usec);
 gettimeofday(&time0, ((void *)0));
 int num_whales = atoi(argv[1]);
 int sem_wait_time_ms = atof(argv[2]) * 1000;
   sem_init(&male_avail, 0, 0);
  sem_init(&fem_avail, 0, 0);
   sem_init(&maker_avail, 0, 0);
 pthread_attr_t thread_attr;
 pthread_attr_init(&thread_attr);
 pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
 for (int whale = 0; whale < num_whales; whale++) {
  whale_sleep(sem_wait_time_ms);
  pthread_t whale_thread_id;
  pthread_create(&whale_thread_id, &thread_attr, create_whale, (void *) &whale);
 }
 whale_sleep(sem_wait_time_ms * 10.0);
 pthread_mutex_destroy(&stdout_lock);
}

canonical_original_code:
int main(int argc, char *argv[]) {
 if (argc != 3) {
  usage(argv[0]);
 }
 whaleInit();
 pthread_mutex_init(&stdout_lock, ((void *)0));
 struct timeval tv;
 gettimeofday(&tv, ((void *)0));
 srand(tv.tv_usec);
 gettimeofday(&time0, ((void *)0));
 int num_whales = atoi(argv[1]);
 int sem_wait_time_ms = atof(argv[2]) * 1000;
   sem_init(&male_avail, 0, 0);
  sem_init(&fem_avail, 0, 0);
   sem_init(&maker_avail, 0, 0);
 union pthread_attr_t thread_attr;
 pthread_attr_init(&thread_attr);
 pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
 for (int whale = 0; whale < num_whales; whale++) {
  whale_sleep(sem_wait_time_ms);
  unsigned long whale_thread_id;
  pthread_create(&whale_thread_id, &thread_attr, create_whale, (void *) &whale);
 }
 whale_sleep(sem_wait_time_ms * 10.0);
 pthread_mutex_destroy(&stdout_lock);
}

variable_types:
argv
char *[]

variable_types: union pthread_attr_t { char __size[56]; long __align; }

variable_types: whale int

user_defined_types: struct timeval { long tv_sec; long tv_usec; }


decompiled_code:
void __fastcall string_data_delete(__int64 a1)
{
free(*(void **)(a1 + 16));
}

canonical_decompiled_code:
void __fastcall func1(__int64 a1)
{
free(*(void **)(a1 + 16));
}

original_code:
void string_data_delete(void *item){
  free(((list_item_t*)item)->data);
}

canonical_original_code:
void string_data_delete(void *item){
  free(((struct list_item *)item)->data);
}


decompiled_code:
int __fastcall print_data_string(__int64 a1)
{
return puts(*(const char **)(a1 + 16));
}

canonical_decompiled_code:
int __fastcall func2(__int64 a1)
{
return puts(*(const char **)(a1 + 16));
}

original_code:
void print_data_string(void *v){
  printf("%s\n", (char*)( ( (list_item_t*)v)->data));
}

canonical_original_code:
void print_data_string(void *v){
  printf("%s\n", (char *)( ( (struct list_item *)v)->data));
}

variable_types:
v
void *


decompiled_code:
int __fastcall list_item_compare_string(__int64 a1, __int64 a2)
{
return strcmp(*(const char **)(*(_QWORD *)a1 + 16LL), *(const char **)(*(_QWORD *)a2 + 16LL));
}

canonical_decompiled_code:
int __fastcall func3(__int64 a1, __int64 a2)
{
return strcmp(*(const char **)(*(_QWORD *)a1 + 16LL), *(const char **)(*(_QWORD *)a2 + 16LL));
}

original_code:
int list_item_compare_string(const void *key, const void *with){
  list_item_t **arg1 = (list_item_t**)key;
  list_item_t **arg2 = (list_item_t**)with;
  char *data1 = (char*)((*arg1)->data);
  char *data2 = (char*)((*arg2)->data);
  return strcmp(data1, data2);
}

canonical_original_code:
int list_item_compare_string(void *key, void *with){
  struct list_item **arg1 = (list_item_t**)key;
  struct list_item **arg2 = (list_item_t**)with;
  char *data1 = (char*)((*arg1)->data);
  char *data2 = (char*)((*arg2)->data);
  return strcmp(data1, data2);
}


decompiled_code:
__int64 __fastcall cleanup_list(_QWORD *a1)
{
__int64 result; // rax

for ( ; *a1; result = list_remove_head(a1) )
;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(_QWORD *a1)
{
__int64 result; // rax

for ( ; *a1; result = list_remove_head(a1) )
;
return result;
}

original_code:
void cleanup_list(list_t *l){
  while(l->head != ((void *)0))
    {
      list_remove_head(l);
    }
}

canonical_original_code:
void cleanup_list(struct list *l){
  while(l->head != ((void *)0))
    {
      list_remove_head(l);
    }
}

variable_types: struct list { struct list_item { struct list_item *prev; void *data; } *head; unsigned int length; int (*compare)(void *key, void *with); void (*data_delete)(void *data); } *


decompiled_code:
int __fastcall update_state(unsigned int *a1, unsigned int a2)
{
unsigned int v2; // ebp
unsigned int v3; // ebx
double v4; // xmm0_8

a1[1] = a2;
pthread_mutex_lock(&stdout_lock);
v2 = a1[1];
v3 = *a1;
v4 = elapsed_time();
printf("(t=%f) %d: %c\n", v4, v3, v2);
fflush(stdout);
return pthread_mutex_unlock(&stdout_lock);
}

canonical_decompiled_code:
int __fastcall func8(unsigned int *a1, unsigned int a2)
{
unsigned int v2; // ebp
unsigned int v3; // ebx
double v4; // xmm0_8

a1[1] = a2;
pthread_mutex_lock(&stdout_lock);
v2 = a1[1];
v3 = *a1;
v4 = func7();
printf("(t=%f) %d: %c\n", v4, v3, v2);
fflush(stdout);
return pthread_mutex_unlock(&stdout_lock);
}

original_code:
void
update_state (philosopher_t * philosopher, state_t state)
{
  philosopher->state = state;
  pthread_mutex_lock(&stdout_lock); printf("(t=%f) %d: %c\n", elapsed_time (), philosopher->id, philosopher->state); fflush(stdout); pthread_mutex_unlock(&stdout_lock);
}

canonical_original_code:
void update_state(struct _philosopher *philosopher, enum _state state)
{
  philosopher->state = state;
  pthread_mutex_lock(&stdout_lock); printf("(t=%f) %d: %c\n", elapsed_time (), philosopher->id, philosopher->state); fflush(stdout); pthread_mutex_unlock(&stdout_lock);
}

variable_types: struct _philosopher { int id; enum _state { STATE_THINKING=expr, STATE_HUNGRY=expr, STATE_EATING=expr } state; struct _chopstick { _Bool down; } *left; struct _philosopher *left_phil; double avg_wait; _Bool do_random; } *

user_defined_types: struct _philosopher { int id; enum _state state; struct _chopstick *left; struct _philosopher *left_phil; double avg_wait; _Bool do_random; }


decompiled_code:
int __fastcall pickup_left(int *a1)
{
unsigned int v1; // ebx
double v2; // xmm0_8

**((_BYTE **)a1 + 1) = 0;
pthread_mutex_lock(&stdout_lock);
v1 = *a1;
v2 = elapsed_time();
printf("(t=%f) %d: LEFT UP\n", v2, v1);
fflush(stdout);
return pthread_mutex_unlock(&stdout_lock);
}

canonical_decompiled_code:
int __fastcall func9(int *a1)
{
unsigned int v1; // ebx
double v2; // xmm0_8

**((_BYTE **)a1 + 1) = 0;
pthread_mutex_lock(&stdout_lock);
v1 = *a1;
v2 = func7();
printf("(t=%f) %d: LEFT UP\n", v2, v1);
fflush(stdout);
return pthread_mutex_unlock(&stdout_lock);
}

original_code:
void
pickup_left (philosopher_t * philosopher)
{
  philosopher->left->down = 0;
  pthread_mutex_lock(&stdout_lock); printf("(t=%f) %d: LEFT UP\n", elapsed_time (), philosopher->id); fflush(stdout); pthread_mutex_unlock(&stdout_lock);
}

canonical_original_code:
void pickup_left(struct _philosopher *philosopher)
{
  philosopher->left->down = 0;
  pthread_mutex_lock(&stdout_lock); printf("(t=%f) %d: LEFT UP\n", elapsed_time (), philosopher->id); fflush(stdout); pthread_mutex_unlock(&stdout_lock);
}

user_defined_types: enum _state { STATE_THINKING=expr, STATE_HUNGRY=expr, STATE_EATING=expr }


decompiled_code:
int __fastcall pickup_right(int *a1)
{
unsigned int v1; // ebx
double v2; // xmm0_8

**((_BYTE **)a1 + 2) = 0;
pthread_mutex_lock(&stdout_lock);
v1 = *a1;
v2 = elapsed_time();
printf("(t=%f) %d: RIGHT UP\n", v2, v1);
fflush(stdout);
return pthread_mutex_unlock(&stdout_lock);
}

canonical_decompiled_code:
int __fastcall func10(int *a1)
{
unsigned int v1; // ebx
double v2; // xmm0_8

**((_BYTE **)a1 + 2) = 0;
pthread_mutex_lock(&stdout_lock);
v1 = *a1;
v2 = func7();
printf("(t=%f) %d: RIGHT UP\n", v2, v1);
fflush(stdout);
return pthread_mutex_unlock(&stdout_lock);
}

original_code:
void
pickup_right (philosopher_t * philosopher)
{
  philosopher->right->down = 0;
  pthread_mutex_lock(&stdout_lock); printf("(t=%f) %d: RIGHT UP\n", elapsed_time (), philosopher->id); fflush(stdout); pthread_mutex_unlock(&stdout_lock);
}

canonical_original_code:
void pickup_right(struct _philosopher *philosopher)
{
  philosopher->right->down = 0;
  pthread_mutex_lock(&stdout_lock); printf("(t=%f) %d: RIGHT UP\n", elapsed_time (), philosopher->id); fflush(stdout); pthread_mutex_unlock(&stdout_lock);
}


decompiled_code:
int __fastcall putdown_left(int *a1)
{
unsigned int v1; // ebx
double v2; // xmm0_8

**((_BYTE **)a1 + 1) = 1;
pthread_mutex_lock(&stdout_lock);
v1 = *a1;
v2 = elapsed_time();
printf("(t=%f) %d: LEFT DOWN\n", v2, v1);
fflush(stdout);
return pthread_mutex_unlock(&stdout_lock);
}

canonical_decompiled_code:
int __fastcall func11(int *a1)
{
unsigned int v1; // ebx
double v2; // xmm0_8

**((_BYTE **)a1 + 1) = 1;
pthread_mutex_lock(&stdout_lock);
v1 = *a1;
v2 = func7();
printf("(t=%f) %d: LEFT DOWN\n", v2, v1);
fflush(stdout);
return pthread_mutex_unlock(&stdout_lock);
}

original_code:
void
putdown_left (philosopher_t * philosopher)
{
  philosopher->left->down = 1;
  pthread_mutex_lock(&stdout_lock); printf("(t=%f) %d: LEFT DOWN\n", elapsed_time (), philosopher->id); fflush(stdout); pthread_mutex_unlock(&stdout_lock);
}

canonical_original_code:
void putdown_left(struct _philosopher *philosopher)
{
  philosopher->left->down = 1;
  pthread_mutex_lock(&stdout_lock); printf("(t=%f) %d: LEFT DOWN\n", elapsed_time (), philosopher->id); fflush(stdout); pthread_mutex_unlock(&stdout_lock);
}


decompiled_code:
int __fastcall putdown_right(int *a1)
{
unsigned int v1; // ebx
double v2; // xmm0_8

**((_BYTE **)a1 + 2) = 1;
pthread_mutex_lock(&stdout_lock);
v1 = *a1;
v2 = elapsed_time();
printf("(t=%f) %d: RIGHT DOWN\n", v2, v1);
fflush(stdout);
return pthread_mutex_unlock(&stdout_lock);
}

canonical_decompiled_code:
int __fastcall func12(int *a1)
{
unsigned int v1; // ebx
double v2; // xmm0_8

**((_BYTE **)a1 + 2) = 1;
pthread_mutex_lock(&stdout_lock);
v1 = *a1;
v2 = func7();
printf("(t=%f) %d: RIGHT DOWN\n", v2, v1);
fflush(stdout);
return pthread_mutex_unlock(&stdout_lock);
}

original_code:
void
putdown_right (philosopher_t * philosopher)
{
  philosopher->right->down = 1;
  pthread_mutex_lock(&stdout_lock); printf("(t=%f) %d: RIGHT DOWN\n", elapsed_time (), philosopher->id); fflush(stdout); pthread_mutex_unlock(&stdout_lock);
}

canonical_original_code:
void putdown_right(struct _philosopher *philosopher)
{
  philosopher->right->down = 1;
  pthread_mutex_lock(&stdout_lock); printf("(t=%f) %d: RIGHT DOWN\n", elapsed_time (), philosopher->id); fflush(stdout); pthread_mutex_unlock(&stdout_lock);
}


original_code:
void
phil_sleep (philosopher_t * philosopher)
{
  int wait_time_us = philosopher->avg_wait * 1e6;
  if (philosopher->do_random)
    {
      wait_time_us = rand () / (2147483647 + 1.0) * 2.0 * wait_time_us;
    }
  usleep (wait_time_us);
}

canonical_original_code:
void phil_sleep(struct _philosopher *philosopher)
{
  int wait_time_us = philosopher->avg_wait * 1e6;
  if (philosopher->do_random)
    {
      wait_time_us = rand () / (2147483647 + 1.0) * 2.0 * wait_time_us;
    }
  usleep (wait_time_us);
}


decompiled_code:
void __fastcall __noreturn philosopher_thread(void *a1)
{
while ( 1 )
{
phil_sleep((__int64)a1);
update_state((unsigned int *)a1, 0x48u);
if ( pthread_mutex_trylock(&chopstick_manipulation_lock) )
{
pthread_mutex_lock(&canEat_mutex);
pthread_cond_wait(&canEat_cv, &canEat_mutex);
pthread_mutex_unlock(&canEat_mutex);
pthread_mutex_lock(&chopstick_manipulation_lock);
}
pickup_right((int *)a1);
pickup_left((int *)a1);
update_state((unsigned int *)a1, 0x45u);
phil_sleep((__int64)a1);
putdown_right((int *)a1);
putdown_left((int *)a1);
pthread_mutex_lock(&canEat_mutex);
pthread_cond_signal(&canEat_cv);
pthread_mutex_unlock(&canEat_mutex);
update_state((unsigned int *)a1, 0x54u);
pthread_mutex_unlock(&chopstick_manipulation_lock);
phil_sleep((__int64)a1);
}
}

canonical_decompiled_code:
void __fastcall __noreturn func14(void *a1)
{
while ( 1 )
{
func13((__int64)a1);
func8((unsigned int *)a1, 0x48u);
if ( pthread_mutex_trylock(&chopstick_manipulation_lock) )
{
pthread_mutex_lock(&canEat_mutex);
pthread_cond_wait(&canEat_cv, &canEat_mutex);
pthread_mutex_unlock(&canEat_mutex);
pthread_mutex_lock(&chopstick_manipulation_lock);
}
func10((int *)a1);
func9((int *)a1);
func8((unsigned int *)a1, 0x45u);
func13((__int64)a1);
func12((int *)a1);
func11((int *)a1);
pthread_mutex_lock(&canEat_mutex);
pthread_cond_signal(&canEat_cv);
pthread_mutex_unlock(&canEat_mutex);
func8((unsigned int *)a1, 0x54u);
pthread_mutex_unlock(&chopstick_manipulation_lock);
func13((__int64)a1);
}
}

original_code:
void *
philosopher_thread (void *arg)
{
  philosopher_t *philosopher = (philosopher_t *) arg;
  while (1)
    {
      phil_sleep (philosopher);
      update_state (philosopher, STATE_HUNGRY);
      int manipulate = pthread_mutex_trylock(&chopstick_manipulation_lock);
      if ( manipulate != 0 )
        {
          pthread_mutex_lock(&canEat_mutex);
          pthread_cond_wait(&canEat_cv, &canEat_mutex);
          pthread_mutex_unlock(&canEat_mutex);
          pthread_mutex_lock(&chopstick_manipulation_lock);
        }
      pickup_right(philosopher);
      pickup_left(philosopher);
      update_state(philosopher, STATE_EATING);
      phil_sleep(philosopher);
      putdown_right(philosopher);
      putdown_left(philosopher);
      pthread_mutex_lock(&canEat_mutex);
      pthread_cond_signal(&canEat_cv);
      pthread_mutex_unlock(&canEat_mutex);
      update_state(philosopher, STATE_THINKING);
      pthread_mutex_unlock(&chopstick_manipulation_lock);
      phil_sleep (philosopher);
    }
  pthread_exit (((void *)0));
}

canonical_original_code:
void *philosopher_thread(void *arg)
{
  struct _philosopher *philosopher = (philosopher_t *) arg;
  while (1)
    {
      phil_sleep (philosopher);
      update_state (philosopher, STATE_HUNGRY);
      int manipulate = pthread_mutex_trylock(&chopstick_manipulation_lock);
      if ( manipulate != 0 )
        {
          pthread_mutex_lock(&canEat_mutex);
          pthread_cond_wait(&canEat_cv, &canEat_mutex);
          pthread_mutex_unlock(&canEat_mutex);
          pthread_mutex_lock(&chopstick_manipulation_lock);
        }
      pickup_right(philosopher);
      pickup_left(philosopher);
      update_state(philosopher, STATE_EATING);
      phil_sleep(philosopher);
      putdown_right(philosopher);
      putdown_left(philosopher);
      pthread_mutex_lock(&canEat_mutex);
      pthread_cond_signal(&canEat_cv);
      pthread_mutex_unlock(&canEat_mutex);
      update_state(philosopher, STATE_THINKING);
      pthread_mutex_unlock(&chopstick_manipulation_lock);
      phil_sleep (philosopher);
    }
  pthread_exit (((void *)0));
}

variable_types: manipulate int


canonical_decompiled_code:
double func7()
{
struct timeval v1; // [rsp+0h] [rbp-18h] BYREF

gettimeofday(&v1, 0LL);
return (double)(LODWORD(v1.tv_usec) - LODWORD(time0.tv_usec)) / 1000000.0
+ (double)(LODWORD(v1.tv_sec) - LODWORD(time0.tv_sec));
}

original_code:
double
elapsed_time ()
{
  struct timeval tv;
  gettimeofday (&tv, ((void *)0));
  return (tv.tv_sec - time0.tv_sec + (tv.tv_usec - time0.tv_usec) / 1.e6);
}

canonical_original_code:
double elapsed_time()
{
  struct timeval tv;
  gettimeofday (&tv, ((void *)0));
  return (tv.tv_sec - time0.tv_sec + (tv.tv_usec - time0.tv_usec) / 1.e6);
}


usage

decompiled_code:
void __fastcall __noreturn usage(const char *a1)
{
fprintf(stderr, "Usage: %s num_philosophers avg_wait_seconds use_randomness\nExample: %s 5 0.5 1\n", a1, a1);
exit(-1);
}

canonical_decompiled_code:
void __fastcall __noreturn func15(const char *a1)
{
fprintf(stderr, "Usage: %s num_philosophers avg_wait_seconds use_randomness\nExample: %s 5 0.5 1\n", a1, a1);
exit(-1);
}

original_code:
void
usage (char *arg0)
{
  fprintf (stderr,
    "Usage: %s num_philosophers avg_wait_seconds use_randomness\n"
    "Example: %s 5 0.5 1\n", arg0, arg0);
  exit (-1);
}

canonical_original_code:
void usage(char *arg0)
{
  fprintf (stderr,
    "Usage: %s num_philosophers avg_wait_seconds use_randomness\n"
    "Example: %s 5 0.5 1\n", arg0, arg0);
  exit (-1);
}


main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // ebx
double v4; // xmm0_8
bool v5; // r15
char *v6; // r12
char *v7; // rax
char *v8; // r13
char *v9; // r8
__int64 v10; // rdx
char *v11; // rbp
char *v12; // rcx
int v13; // esi
__int64 v14; // rdi
pthread_t *v15; // r14
pthread_t *v16; // r15
pthread_t *v17; // rbx
pthread_t *ptr; // [rsp+8h] [rbp-40h]
void *ptra; // [rsp+8h] [rbp-40h]

gettimeofday(&time0, 0LL);
if ( argc <= 3 )
usage(*argv);
v3 = atoi(argv[1]);
v4 = atof(argv[2]);
v5 = atoi(argv[3]) != 0;
pthread_mutex_init(&stdout_lock, 0LL);
pthread_mutex_init(&chopstick_manipulation_lock, 0LL);
pthread_mutex_init(&canEat_mutex, 0LL);
pthread_cond_init(&canEat_cv, 0LL);
v6 = (char *)malloc(56LL * v3);
v7 = (char *)malloc(v3);
v8 = v7;
if ( v3 <= 0 )
{
ptra = malloc(8LL * v3);
free(ptra);
}
else
{
v9 = v7;
v10 = (__int64)&v7[v3 - 1 + 1];
do
*v7++ = 1;
while ( v7 != (char *)v10 );
v11 = v6;
v12 = v6;
v13 = 0;
do
{
*(_DWORD *)v12 = v13;
*((_QWORD *)v12 + 1) = v9;
v14 = ++v13 % v3;
*((_QWORD *)v12 + 2) = &v8[v14];
*((_QWORD *)v12 + 3) = &v6[56 * ((v3 - 2 + v13) % v3)];
*((_QWORD *)v12 + 4) = &v6[56 * v14];
*((double *)v12 + 5) = v4;
v12[48] = v5;
*((_DWORD *)v12 + 1) = 84;
v12 += 56;
++v9;
}
while ( v13 != v3 );
ptr = (pthread_t *)malloc(8LL * v3);
v15 = ptr;
v16 = &ptr[v3];
v17 = ptr;
do
{
pthread_create(v17++, 0LL, (void *(*)(void *))philosopher_thread, v11);
v11 += 56;
}
while ( v17 != v16 );
do
pthread_join(*v15++, 0LL);
while ( v15 != v16 );
free(ptr);
}
free(v6);
free(v8);
pthread_mutex_destroy(&stdout_lock);
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // ebx
double v4; // xmm0_8
bool v5; // r15
char *v6; // r12
char *v7; // rax
char *v8; // r13
char *v9; // r8
__int64 v10; // rdx
char *v11; // rbp
char *v12; // rcx
int v13; // esi
__int64 v14; // rdi
pthread_t *v15; // r14
pthread_t *v16; // r15
pthread_t *v17; // rbx
pthread_t *ptr; // [rsp+8h] [rbp-40h]
void *ptra; // [rsp+8h] [rbp-40h]

gettimeofday(&time0, 0LL);
if ( argc <= 3 )
func15(*argv);
v3 = atoi(argv[1]);
v4 = atof(argv[2]);
v5 = atoi(argv[3]) != 0;
pthread_mutex_init(&stdout_lock, 0LL);
pthread_mutex_init(&chopstick_manipulation_lock, 0LL);
pthread_mutex_init(&canEat_mutex, 0LL);
pthread_cond_init(&canEat_cv, 0LL);
v6 = (char *)malloc(56LL * v3);
v7 = (char *)malloc(v3);
v8 = v7;
if ( v3 <= 0 )
{
ptra = malloc(8LL * v3);
free(ptra);
}
else
{
v9 = v7;
v10 = (__int64)&v7[v3 - 1 + 1];
do
*v7++ = 1;
while ( v7 != (char *)v10 );
v11 = v6;
v12 = v6;
v13 = 0;
do
{
*(_DWORD *)v12 = v13;
*((_QWORD *)v12 + 1) = v9;
v14 = ++v13 % v3;
*((_QWORD *)v12 + 2) = &v8[v14];
*((_QWORD *)v12 + 3) = &v6[56 * ((v3 - 2 + v13) % v3)];
*((_QWORD *)v12 + 4) = &v6[56 * v14];
*((double *)v12 + 5) = v4;
v12[48] = v5;
*((_DWORD *)v12 + 1) = 84;
v12 += 56;
++v9;
}
while ( v13 != v3 );
ptr = (pthread_t *)malloc(8LL * v3);
v15 = ptr;
v16 = &ptr[v3];
v17 = ptr;
do
{
pthread_create(v17++, 0LL, (void *(*)(void *))philosopher_thread, v11);
v11 += 56;
}
while ( v17 != v16 );
do
pthread_join(*v15++, 0LL);
while ( v15 != v16 );
free(ptr);
}
free(v6);
free(v8);
pthread_mutex_destroy(&stdout_lock);
return 0;
}

original_code:
int
main (int argc, char *argv[])
{
  gettimeofday (&time0, ((void *)0));
  int n;
  double avg_wait;
  _Bool do_random;
  if (argc < 4)
    {
      usage (argv[0]);
    }
  n = atoi (argv[1]);
  avg_wait = atof (argv[2]);
  do_random = atoi (argv[3]);
  pthread_mutex_init (&stdout_lock, ((void *)0));
  pthread_mutex_init(&chopstick_manipulation_lock, ((void *)0));
  pthread_mutex_init(&canEat_mutex, ((void *)0));
  pthread_cond_init(&canEat_cv, ((void *)0));
  philosopher_t *philosophers =
    (philosopher_t *) malloc (sizeof (philosopher_t) * n);
  chopstick_t *chopsticks = (chopstick_t *) malloc (sizeof (chopstick_t) * n);
  for (int i = 0; i < n; i++)
    {
      chopsticks[i].down = 1;
    }
  for (int i = 0; i < n; i++)
    {
      philosophers[i].id = i;
      philosophers[i].left = &chopsticks[i];
      philosophers[i].right = &chopsticks[(i + 1) % n];
      philosophers[i].left_phil = &philosophers[(i + n - 1) % n];
      philosophers[i].right_phil = &philosophers[(i + 1) % n];
      philosophers[i].avg_wait = avg_wait;
      philosophers[i].do_random = do_random;
      philosophers[i].state = STATE_THINKING;
    }
  pthread_t *pids = (pthread_t *) malloc (sizeof (pthread_t) * n);
  for (int i = 0; i < n; i++)
    {
      pthread_create (&pids[i], ((void *)0), philosopher_thread, &philosophers[i]);
    }
  for (int i = 0; i < n; i++)
    {
      pthread_join (pids[i], ((void *)0));
    }
  free (pids);
  free (philosophers);
  free (chopsticks);
  pthread_mutex_destroy (&stdout_lock);
}

canonical_original_code:
int main(int argc, char *argv[])
{
  gettimeofday (&time0, ((void *)0));
  int n;
  double avg_wait;
  _Bool do_random;
  if (argc < 4)
    {
      usage (argv[0]);
    }
  n = atoi (argv[1]);
  avg_wait = atof (argv[2]);
  do_random = atoi (argv[3]);
  pthread_mutex_init (&stdout_lock, ((void *)0));
  pthread_mutex_init(&chopstick_manipulation_lock, ((void *)0));
  pthread_mutex_init(&canEat_mutex, ((void *)0));
  pthread_cond_init(&canEat_cv, ((void *)0));
  struct _philosopher *philosophers = (philosopher_t *) malloc (sizeof (philosopher_t) * n);
  struct _chopstick *chopsticks = (chopstick_t *) malloc (sizeof (chopstick_t) * n);
  for (int i = 0; i < n; i++)
    {
      chopsticks[i].down = 1;
    }
  for (int i = 0; i < n; i++)
    {
      philosophers[i].id = i;
      philosophers[i].left = &chopsticks[i];
      philosophers[i].right = &chopsticks[(i + 1) % n];
      philosophers[i].left_phil = &philosophers[(i + n - 1) % n];
      philosophers[i].right_phil = &philosophers[(i + 1) % n];
      philosophers[i].avg_wait = avg_wait;
      philosophers[i].do_random = do_random;
      philosophers[i].state = STATE_THINKING;
    }
  unsigned long *pids = (pthread_t *) malloc (sizeof (pthread_t) * n);
  for (int i = 0; i < n; i++)
    {
      pthread_create (&pids[i], ((void *)0), philosopher_thread, &philosophers[i]);
    }
  for (int i = 0; i < n; i++)
    {
      pthread_join (pids[i], ((void *)0));
    }
  free (pids);
  free (philosophers);
  free (chopsticks);
  pthread_mutex_destroy (&stdout_lock);
}

variable_types: n int

variable_types:
chopsticks
struct _chopstick { _Bool down; } *

variable_types: i int

variable_types:
pids
unsigned long *


decompiled_code:
__int64 __fastcall find_redirect(__int64 a1, unsigned int *a2)
{
unsigned int v2; // er8
__int64 v3; // r10
__int64 v4; // rax

v2 = *a2;
if ( *a2 )
{
v3 = v2;
v4 = 0LL;
while ( 1 )
{
v2 = v4;
if ( !strcmp(*(const char **)(a1 + 8 * v4), ">")
|| !strcmp(*(const char **)(a1 + 8 * v4), ">>")
|| !strcmp(*(const char **)(a1 + 8 * v4), "<") )
{
break;
}
if ( ++v4 == v3 )
return 0;
}
}
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func7(__int64 a1, unsigned int *a2)
{
unsigned int v2; // er8
__int64 v3; // r10
__int64 v4; // rax

v2 = *a2;
if ( *a2 )
{
v3 = v2;
v4 = 0LL;
while ( 1 )
{
v2 = v4;
if ( !strcmp(*(const char **)(a1 + 8 * v4), ">")
|| !strcmp(*(const char **)(a1 + 8 * v4), ">>")
|| !strcmp(*(const char **)(a1 + 8 * v4), "<") )
{
break;
}
if ( ++v4 == v3 )
return 0;
}
}
return v2;
}

original_code:
unsigned int find_redirect(char **token_buf, unsigned int *token_buf_len)
{
  unsigned int i;
  for(i = 0; i < *token_buf_len; i++)
    {
      if( (strcmp(token_buf[i], ">") == 0) ||
   (strcmp(token_buf[i], ">>") == 0) ||
   (strcmp(token_buf[i], "<") == 0)) return i;
    }
  return 0;
}

variable_types:
i
unsigned int

return_type: unsigned int


decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
void *v3; // r13
char v4; // al
unsigned int v5; // ebx
_QWORD *v6; // rax
_QWORD *v7; // r14
_QWORD *v8; // rdx
char *v9; // rax
unsigned int v10; // er15
char *v11; // rbx
unsigned int v12; // er12
const char *v13; // rsi
unsigned int v14; // ebx
unsigned int v15; // er12
void *v16; // rax
int v17; // eax
_QWORD *v18; // rax
unsigned int v19; // eax
unsigned int v20; // er9
unsigned int v21; // eax
void *v22; // rsp
__int64 v23; // rax
const char *v24; // rbx
char *v26[2]; // [rsp+0h] [rbp-60h] BYREF
char *filename; // [rsp+10h] [rbp-50h]
size_t size; // [rsp+1Ch] [rbp-44h]
unsigned int v29; // [rsp+28h] [rbp-38h] BYREF
int stat_loc[13]; // [rsp+2Ch] [rbp-34h] BYREF

v3 = malloc(0x50uLL);
LODWORD(size) = 80;
while ( 1 )
{
printf("$ ");
v5 = 0;
do
{
if ( (_DWORD)size == v5 )
{
LODWORD(size) = size + 40;
v3 = realloc(v3, (unsigned int)size);
if ( !v3 )
{
perror("Error increasing size of input buffer.");
exit(-1);
}
}
v4 = getchar();
*((_BYTE *)v3 + v5++) = v4;
}
while ( v4 != 10 );
v6 = malloc(0xA0uLL);
v7 = v6;
v8 = v6 + 20;
do
*v6++ = 0LL;
while ( v6 != v8 );
v9 = strtok((char *)v3, " \n");
v10 = 20;
if ( v9 )
{
*v7 = v9;
v11 = strtok(0LL, " \n");
v12 = 1;
v10 = 20;
while ( v11 )
{
v7[v12] = v11;
v11 = strtok(0LL, " \n");
if ( v10 == ++v12 )
{
v10 += 10;
v7 = realloc(v7, 8LL * v10);
if ( !v7 )
{
perror("Error increasing size of token buffer.");
exit(-1);
}
}
}
}
v29 = 0;
v13 = (const char *)*v7;
if ( !v10 || !v13 )
goto LABEL_27;
v14 = 0;
do
v15 = v14++;
while ( v7[v14] && v14 < v10 );
v29 = v14;
if ( !v14 )
goto LABEL_27;
if ( !strcmp(v13, "exit") )
break;
v17 = fork();
if ( v17 < 0 )
{
perror("Fork was unsuccesful in creating a new process.");
exit(-1);
}
if ( v17 )
{
if ( strcmp((const char *)v7[v15], "&") )
waitpid(v17, stat_loc, 0);
}
else
{
v26[1] = (char *)v26;
v19 = find_redirect((__int64)v7, &v29);
v20 = v19;
if ( v19 )
{
v21 = v19 + 1;
filename = (char *)"";
if ( v14 > v21 )
filename = (char *)v7[v21];
v14 = v20;
}
v22 = alloca(16 * ((8 * (unsigned __int64)(v14 + 1) + 15) >> 4));
v23 = 0LL;
while ( strcmp((const char *)v7[v23], "&") )
{
v26[v23] = (char *)v7[v23];
if ( v14 <= (unsigned int)++v23 )
{
v26[v14] = 0LL;
if ( !v20 )
goto LABEL_41;
goto LABEL_38;
}
}
v26[v14] = 0LL;
if ( v20 )
{
LABEL_38:
v24 = (const char *)v7[v20];
if ( !strcmp(v24, ">") )
{
fclose(_bss_start);
_bss_start = fopen(filename, "w");
if ( !_bss_start )
{
perror("Couldn't open output file for writing.");
exit(-1);
}
}
if ( !strcmp(v24, ">>") )
{
fclose(_bss_start);
_bss_start = fopen(filename, "a");
if ( !_bss_start )
{
perror("Couldn't open output file for appending.");
exit(-1);
}
}
if ( !strcmp(v24, "<") )
{
fclose(stdin);
stdin = fopen(filename, "r");
if ( !stdin )
{
perror("Couldn't open input file for reading.");
exit(-1);
}
}
goto LABEL_41;
}
fclose(_bss_start);
_bss_start = fopen("/dev/null", "w");
if ( !_bss_start )
{
perror("Couldn't open /dev/null for writing.");
exit(-1);
}
LABEL_41:
if ( execvp(*(const char **)(8 * (((unsigned __int64)v26 + 7) >> 3)), v26) == -1 )
{
printf("Could not exec: %s\n", v26[0]);
exit(-1);
}
}
LABEL_27:
free(v7);
v18 = realloc(v3, 0x50uLL);
v3 = v18;
if ( !v18 )
goto LABEL_22;
*v18 = 0LL;
v18[1] = 0LL;
v18[2] = 0LL;
v18[3] = 0LL;
v18[4] = 0LL;
v18[5] = 0LL;
v18[6] = 0LL;
v18[7] = 0LL;
v18[8] = 0LL;
v18[9] = 0LL;
}
free(v7);
v16 = realloc(v3, 0x50uLL);
if ( !v16 )
{
LABEL_22:
perror("Error decreasing size of input buffer.");
exit(-1);
}
free(v16);
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
void *v3; // r13
char v4; // al
unsigned int v5; // ebx
_QWORD *v6; // rax
_QWORD *v7; // r14
_QWORD *v8; // rdx
char *v9; // rax
unsigned int v10; // er15
char *v11; // rbx
unsigned int v12; // er12
const char *v13; // rsi
unsigned int v14; // ebx
unsigned int v15; // er12
void *v16; // rax
int v17; // eax
_QWORD *v18; // rax
unsigned int v19; // eax
unsigned int v20; // er9
unsigned int v21; // eax
void *v22; // rsp
__int64 v23; // rax
const char *v24; // rbx
char *v26[2]; // [rsp+0h] [rbp-60h] BYREF
char *filename; // [rsp+10h] [rbp-50h]
size_t size; // [rsp+1Ch] [rbp-44h]
unsigned int v29; // [rsp+28h] [rbp-38h] BYREF
int stat_loc[13]; // [rsp+2Ch] [rbp-34h] BYREF

v3 = malloc(0x50uLL);
LODWORD(size) = 80;
while ( 1 )
{
printf("$ ");
v5 = 0;
do
{
if ( (_DWORD)size == v5 )
{
LODWORD(size) = size + 40;
v3 = realloc(v3, (unsigned int)size);
if ( !v3 )
{
perror("Error increasing size of input buffer.");
exit(-1);
}
}
v4 = getchar();
*((_BYTE *)v3 + v5++) = v4;
}
while ( v4 != 10 );
v6 = malloc(0xA0uLL);
v7 = v6;
v8 = v6 + 20;
do
*v6++ = 0LL;
while ( v6 != v8 );
v9 = strtok((char *)v3, " \n");
v10 = 20;
if ( v9 )
{
*v7 = v9;
v11 = strtok(0LL, " \n");
v12 = 1;
v10 = 20;
while ( v11 )
{
v7[v12] = v11;
v11 = strtok(0LL, " \n");
if ( v10 == ++v12 )
{
v10 += 10;
v7 = realloc(v7, 8LL * v10);
if ( !v7 )
{
perror("Error increasing size of token buffer.");
exit(-1);
}
}
}
}
v29 = 0;
v13 = (const char *)*v7;
if ( !v10 || !v13 )
goto LABEL_27;
v14 = 0;
do
v15 = v14++;
while ( v7[v14] && v14 < v10 );
v29 = v14;
if ( !v14 )
goto LABEL_27;
if ( !strcmp(v13, "exit") )
break;
v17 = fork();
if ( v17 < 0 )
{
perror("Fork was unsuccesful in creating a new process.");
exit(-1);
}
if ( v17 )
{
if ( strcmp((const char *)v7[v15], "&") )
waitpid(v17, stat_loc, 0);
}
else
{
v26[1] = (char *)v26;
v19 = func7((__int64)v7, &v29);
v20 = v19;
if ( v19 )
{
v21 = v19 + 1;
filename = (char *)"";
if ( v14 > v21 )
filename = (char *)v7[v21];
v14 = v20;
}
v22 = alloca(16 * ((8 * (unsigned __int64)(v14 + 1) + 15) >> 4));
v23 = 0LL;
while ( strcmp((const char *)v7[v23], "&") )
{
v26[v23] = (char *)v7[v23];
if ( v14 <= (unsigned int)++v23 )
{
v26[v14] = 0LL;
if ( !v20 )
goto LABEL_41;
goto LABEL_38;
}
}
v26[v14] = 0LL;
if ( v20 )
{
LABEL_38:
v24 = (const char *)v7[v20];
if ( !strcmp(v24, ">") )
{
fclose(_bss_start);
_bss_start = fopen(filename, "w");
if ( !_bss_start )
{
perror("Couldn't open output file for writing.");
exit(-1);
}
}
if ( !strcmp(v24, ">>") )
{
fclose(_bss_start);
_bss_start = fopen(filename, "a");
if ( !_bss_start )
{
perror("Couldn't open output file for appending.");
exit(-1);
}
}
if ( !strcmp(v24, "<") )
{
fclose(stdin);
stdin = fopen(filename, "r");
if ( !stdin )
{
perror("Couldn't open input file for reading.");
exit(-1);
}
}
goto LABEL_41;
}
fclose(_bss_start);
_bss_start = fopen("/dev/null", "w");
if ( !_bss_start )
{
perror("Couldn't open /dev/null for writing.");
exit(-1);
}
LABEL_41:
if ( execvp(*(const char **)(8 * (((unsigned __int64)v26 + 7) >> 3)), v26) == -1 )
{
printf("Could not exec: %s\n", v26[0]);
exit(-1);
}
}
LABEL_27:
free(v7);
v18 = realloc(v3, 0x50uLL);
v3 = v18;
if ( !v18 )
goto LABEL_22;
*v18 = 0LL;
v18[1] = 0LL;
v18[2] = 0LL;
v18[3] = 0LL;
v18[4] = 0LL;
v18[5] = 0LL;
v18[6] = 0LL;
v18[7] = 0LL;
v18[8] = 0LL;
v18[9] = 0LL;
}
free(v7);
v16 = realloc(v3, 0x50uLL);
if ( !v16 )
{
LABEL_22:
perror("Error decreasing size of input buffer.");
exit(-1);
}
free(v16);
return 0;
}

original_code:
int main(int argc, char* argv[])
{
  unsigned int buf_base_size = 80;
  unsigned int buf_size = buf_base_size;
  char *input_buf = malloc(buf_size*sizeof(char));
  _Bool exit_status = 0;
  while(exit_status == 0)
    {
      printf("$ ");
      char in_char = '\0';
      unsigned int buf_pos = 0;
      while( in_char != '\n' )
 {
   if( buf_pos == buf_size )
     {
       buf_size += buf_base_size/2;
       input_buf = realloc(input_buf, buf_size*sizeof(char));
       if(input_buf == ((void *)0))
  {
    perror("Error increasing size of input buffer.");
    exit(-1);
  }
     }
   in_char = getchar();
   input_buf[buf_pos] = in_char;
   buf_pos++;
 }
      unsigned int token_buf_base_size = 20;
      unsigned int token_buf_size = token_buf_base_size;
      char** token_buf = malloc(token_buf_base_size*sizeof(char*));
      unsigned int token_pos;
      for(token_pos = 0; token_pos < token_buf_size; token_pos++)
 {
   token_buf[token_pos] = ((void *)0);
 }
      char *token = strtok(input_buf, " \n");
      token_pos = 0;
      while(token != ((void *)0))
 {
   token_buf[token_pos] = token;
   token = strtok(((void *)0), " \n");
   token_pos++;
   if(token_pos == token_buf_size)
     {
       token_buf_size += token_buf_base_size/2;
       token_buf = realloc(token_buf, token_buf_size*sizeof(char*));
       if(token_buf == ((void *)0))
  {
    perror("Error increasing size of token buffer.");
    exit(-1);
  }
     }
 }
      unsigned int token_buf_len = 0;
      while((token_buf[token_buf_len] != ((void *)0)) && (token_buf_len < token_buf_size)) token_buf_len++;
      if( token_buf_len > 0 )
 {
   if( strcmp(token_buf[0], "exit") == 0) exit_status = 1;
   else
     {
       pid_t child_pid = fork();
       if(child_pid >= 0)
  {
    if(child_pid == 0)
      {
        unsigned int redirect_token_pos = find_redirect(token_buf, &token_buf_len);
        char* redirect_file_name;
        if( redirect_token_pos > 0 )
   {
     if( redirect_token_pos + 1 < token_buf_len ) redirect_file_name = token_buf[redirect_token_pos + 1];
     else redirect_file_name = "";
   }
        unsigned int param_buf_size;
        if( redirect_token_pos > 0 ) param_buf_size = redirect_token_pos;
        else param_buf_size = token_buf_len;
        char *param_buf[param_buf_size + 1];
        _Bool is_background = 0;
        unsigned int i;
        for( i = 0; i < param_buf_size; i++)
   {
     if( strcmp(token_buf[i], "&") == 0 )
       {
         is_background = 1;
         break;
       }
     param_buf[i] = token_buf[i];
   }
        param_buf[param_buf_size] = ((void *)0);
        if( ( redirect_token_pos == 0) && ( is_background == 1 ) )
   {
     fclose(stdout);
     stdout = fopen("/dev/null", "w");
     if( stdout == ((void *)0) )
       {
         perror("Couldn't open /dev/null for writing.");
         exit(-1);
       }
   }
        if( redirect_token_pos > 0 )
   {
     if( strcmp(token_buf[redirect_token_pos], ">") == 0 )
       {
         fclose(stdout);
         stdout = fopen(redirect_file_name, "w");
         if( stdout == ((void *)0) )
    {
      perror("Couldn't open output file for writing.");
      exit(-1);
    }
       }
     if( strcmp(token_buf[redirect_token_pos], ">>") == 0 )
       {
         fclose(stdout);
         stdout = fopen(redirect_file_name, "a");
         if( stdout == ((void *)0) )
    {
      perror("Couldn't open output file for appending.");
      exit(-1);
    }
       }
     if( strcmp(token_buf[redirect_token_pos], "<") == 0 )
       {
         fclose(stdin);
         stdin = fopen(redirect_file_name, "r");
         if( stdin == ((void *)0) )
    {
      perror("Couldn't open input file for reading.");
      exit(-1);
    }
       }
   }
        int retval = execvp(param_buf[0], param_buf);
        if( retval == -1 )
   {
     printf("Could not exec: %s\n", param_buf[0]);
     exit(-1);
   }
      }
    else
      {
        if( strcmp(token_buf[token_buf_len - 1], "&") != 0 )
   {
     int status;
     waitpid(child_pid, &status, 0);
   }
      }
  }
       else
  {
    perror("Fork was unsuccesful in creating a new process.");
    exit(-1);
  }
     }
 }
      free(token_buf);
      input_buf = realloc(input_buf, buf_base_size*sizeof(char));
      if(input_buf == ((void *)0))
 {
   perror("Error decreasing size of input buffer.");
   exit(-1);
 }
      memset(input_buf,'\0',buf_base_size*sizeof(char));
    }
  free(input_buf);
  return 0;
}

canonical_original_code:
int main(int argc, char *argv[])
{
  unsigned int buf_base_size = 80;
  unsigned int buf_size = buf_base_size;
  char *input_buf = malloc(buf_size*sizeof(char));
  _Bool exit_status = 0;
  while(exit_status == 0)
    {
      printf("$ ");
      char in_char = '\0';
      unsigned int buf_pos = 0;
      while( in_char != '\n' )
 {
   if( buf_pos == buf_size )
     {
       buf_size += buf_base_size/2;
       input_buf = realloc(input_buf, buf_size*sizeof(char));
       if(input_buf == ((void *)0))
  {
    perror("Error increasing size of input buffer.");
    exit(-1);
  }
     }
   in_char = getchar();
   input_buf[buf_pos] = in_char;
   buf_pos++;
 }
      unsigned int token_buf_base_size = 20;
      unsigned int token_buf_size = token_buf_base_size;
      char **token_buf = malloc(token_buf_base_size*sizeof(char*));
      unsigned int token_pos;
      for(token_pos = 0; token_pos < token_buf_size; token_pos++)
 {
   token_buf[token_pos] = ((void *)0);
 }
      char *token = strtok(input_buf, " \n");
      token_pos = 0;
      while(token != ((void *)0))
 {
   token_buf[token_pos] = token;
   token = strtok(((void *)0), " \n");
   token_pos++;
   if(token_pos == token_buf_size)
     {
       token_buf_size += token_buf_base_size/2;
       token_buf = realloc(token_buf, token_buf_size*sizeof(char *));
       if(token_buf == ((void *)0))
  {
    perror("Error increasing size of token buffer.");
    exit(-1);
  }
     }
 }
      unsigned int token_buf_len = 0;
      while((token_buf[token_buf_len] != ((void *)0)) && (token_buf_len < token_buf_size)) token_buf_len++;
      if( token_buf_len > 0 )
 {
   if( strcmp(token_buf[0], "exit") == 0) exit_status = 1;
   else
     {
       int child_pid = fork();
       if(child_pid >= 0)
  {
    if(child_pid == 0)
      {
        unsigned int redirect_token_pos = find_redirect(token_buf, &token_buf_len);
        char *redirect_file_name;
        if( redirect_token_pos > 0 )
   {
     if( redirect_token_pos + 1 < token_buf_len ) redirect_file_name = token_buf[redirect_token_pos + 1];
     else redirect_file_name = "";
   }
        unsigned int param_buf_size;
        if( redirect_token_pos > 0 ) param_buf_size = redirect_token_pos;
        else param_buf_size = token_buf_len;
        char *param_buf[-1];
        _Bool is_background = 0;
        unsigned int i;
        for( i = 0; i < param_buf_size; i++)
   {
     if( strcmp(token_buf[i], "&") == 0 )
       {
         is_background = 1;
         break;
       }
     param_buf[i] = token_buf[i];
   }
        param_buf[param_buf_size] = ((void *)0);
        if( ( redirect_token_pos == 0) && ( is_background == 1 ) )
   {
     fclose(stdout);
     stdout = fopen("/dev/null", "w");
     if( stdout == ((void *)0) )
       {
         perror("Couldn't open /dev/null for writing.");
         exit(-1);
       }
   }
        if( redirect_token_pos > 0 )
   {
     if( strcmp(token_buf[redirect_token_pos], ">") == 0 )
       {
         fclose(stdout);
         stdout = fopen(redirect_file_name, "w");
         if( stdout == ((void *)0) )
    {
      perror("Couldn't open output file for writing.");
      exit(-1);
    }
       }
     if( strcmp(token_buf[redirect_token_pos], ">>") == 0 )
       {
         fclose(stdout);
         stdout = fopen(redirect_file_name, "a");
         if( stdout == ((void *)0) )
    {
      perror("Couldn't open output file for appending.");
      exit(-1);
    }
       }
     if( strcmp(token_buf[redirect_token_pos], "<") == 0 )
       {
         fclose(stdin);
         stdin = fopen(redirect_file_name, "r");
         if( stdin == ((void *)0) )
    {
      perror("Couldn't open input file for reading.");
      exit(-1);
    }
       }
   }
        int retval = execvp(param_buf[0], param_buf);
        if( retval == -1 )
   {
     printf("Could not exec: %s\n", param_buf[0]);
     exit(-1);
   }
      }
    else
      {
        if( strcmp(token_buf[token_buf_len - 1], "&") != 0 )
   {
     int status;
     waitpid(child_pid, &status, 0);
   }
      }
  }
       else
  {
    perror("Fork was unsuccesful in creating a new process.");
    exit(-1);
  }
     }
 }
      free(token_buf);
      input_buf = realloc(input_buf, buf_base_size*sizeof(char));
      if(input_buf == ((void *)0))
 {
   perror("Error decreasing size of input buffer.");
   exit(-1);
 }
      memset(input_buf,'\0',buf_base_size*sizeof(char));
    }
  free(input_buf);
  return 0;
}

variable_types: argc int

variable_types:
token
char *

variable_types: retval int

variable_types: status int


programOptionsCreate

repo: afumoleau/Parangon

decompiled_code:
_DWORD *programOptionsCreate()
{
_DWORD *result; // rax

result = malloc(0x28uLL);
*result = 0;
result[7] = 0;
*((_QWORD *)result + 1) = 0LL;
*((_QWORD *)result + 2) = 0LL;
result[6] = 0;
result[8] = 0;
result[9] = 0;
return result;
}

canonical_decompiled_code:
_DWORD *func0()
{
_DWORD *result; // rax

result = malloc(0x28uLL);
*result = 0;
result[7] = 0;
*((_QWORD *)result + 1) = 0LL;
*((_QWORD *)result + 2) = 0LL;
result[6] = 0;
result[8] = 0;
result[9] = 0;
return result;
}

original_code:
programOptions programOptionsCreate()
{
 programOptions instance = (programOptions) malloc(sizeof(struct programOptions));
 instance->mode = 0;
 instance->verbose = 0;
 instance->archiveFilename = ((void *)0);
 instance->filesNames = ((void *)0);
 instance->filesCount = 0;
 instance->gzip = 0;
 instance->sparse = 0;
 return instance;
}

canonical_original_code:
struct programOptions *programOptionsCreate()
{
 struct programOptions *instance = (programOptions) malloc(sizeof(struct programOptions));
 instance->mode = 0;
 instance->verbose = 0;
 instance->archiveFilename = ((void *)0);
 instance->filesNames = ((void *)0);
 instance->filesCount = 0;
 instance->gzip = 0;
 instance->sparse = 0;
 return instance;
}

variable_types: struct programOptions { unsigned int mode; char *archiveFilename; char **filesNames; unsigned int filesCount; unsigned int verbose; unsigned int gzip; unsigned int sparse; } *


programOptionsDestroy

decompiled_code:
void __fastcall programOptionsDestroy(void *a1)
{
free(a1);
}

canonical_decompiled_code:
void __fastcall func1(void *a1)
{
free(a1);
}

original_code:
void programOptionsDestroy(programOptions po)
{
 free(po);
}

canonical_original_code:
void programOptionsDestroy(struct programOptions *po)
{
 free(po);
}

user_defined_types: struct programOptions { unsigned int mode; char *archiveFilename; char **filesNames; unsigned int filesCount; unsigned int verbose; unsigned int gzip; unsigned int sparse; }


programOptionsGetMode

decompiled_code:
__int64 __fastcall programOptionsGetMode(unsigned int *a1)
{
return *a1;
}

canonical_decompiled_code:
__int64 __fastcall func2(unsigned int *a1)
{
return *a1;
}

original_code:
unsigned int programOptionsGetMode(programOptions po)
{
 return po->mode;
}

canonical_original_code:
unsigned int programOptionsGetMode(struct programOptions *po)
{
 return po->mode;
}


programOptionsAddFile

decompiled_code:
void *__fastcall programOptionsAddFile(__int64 a1, __int64 a2)
{
unsigned int v3; // ebp
void *result; // rax
_QWORD *v5; // rcx
__int64 v6; // rdi

v3 = *(_DWORD *)(a1 + 24);
*(_DWORD *)(a1 + 24) = v3 + 1;
result = malloc(8LL * (v3 + 1));
v5 = result;
if ( v3 )
{
v6 = *(_QWORD *)(a1 + 16);
result = 0LL;
do
{
v5[(_QWORD)result] = *(_QWORD *)(v6 + 8LL * (_QWORD)result);
result = (char *)result + 1;
}
while ( result != (void *)v3 );
}
v5[v3] = a2;
*(_QWORD *)(a1 + 16) = v5;
return result;
}

canonical_decompiled_code:
void *__fastcall func4(__int64 a1, __int64 a2)
{
unsigned int v3; // ebp
void *result; // rax
_QWORD *v5; // rcx
__int64 v6; // rdi

v3 = *(_DWORD *)(a1 + 24);
*(_DWORD *)(a1 + 24) = v3 + 1;
result = malloc(8LL * (v3 + 1));
v5 = result;
if ( v3 )
{
v6 = *(_QWORD *)(a1 + 16);
result = 0LL;
do
{
v5[(_QWORD)result] = *(_QWORD *)(v6 + 8LL * (_QWORD)result);
result = (char *)result + 1;
}
while ( result != (void *)v3 );
}
v5[v3] = a2;
*(_QWORD *)(a1 + 16) = v5;
return result;
}

original_code:
void programOptionsAddFile(programOptions po, char* filename)
{
 ++po->filesCount;
 char** tmp = (char**) malloc(sizeof(char*) * po->filesCount);
 for (int i = 0; i < po->filesCount - 1; ++i)
  tmp[i] = po->filesNames[i];
 tmp[po->filesCount - 1] = filename;
 po->filesNames = tmp;
}

canonical_original_code:
void programOptionsAddFile(struct programOptions *po, char *filename)
{
 ++po->filesCount;
 char **tmp = (char**) malloc(sizeof(char*) * po->filesCount);
 for (int i = 0; i < po->filesCount - 1; ++i)
  tmp[i] = po->filesNames[i];
 tmp[po->filesCount - 1] = filename;
 po->filesNames = tmp;
}

variable_types:
filename
char *

variable_types:
tmp
char **


programOptionsSetArchiveName

decompiled_code:
void __fastcall programOptionsSetArchiveName(__int64 a1, __int64 a2)
{
*(_QWORD *)(a1 + 8) = a2;
}

canonical_decompiled_code:
void __fastcall func5(__int64 a1, __int64 a2)
{
*(_QWORD *)(a1 + 8) = a2;
}

original_code:
void programOptionsSetArchiveName(programOptions po, char* archiveName)
{
 po->archiveFilename = archiveName;
}

canonical_original_code:
void programOptionsSetArchiveName(struct programOptions *po, char *archiveName)
{
 po->archiveFilename = archiveName;
}

variable_types:
archiveName
char *


programOptionsGetArchiveName

decompiled_code:
__int64 __fastcall programOptionsGetArchiveName(__int64 a1)
{
void *v2; // rax

if ( !*(_QWORD *)(a1 + 8) )
{
v2 = malloc(0x64uLL);
*(_QWORD *)(a1 + 8) = v2;
_isoc99_scanf(&unk_129, v2);
}
return *(_QWORD *)(a1 + 8);
}

original_code:
char* programOptionsGetArchiveName(programOptions po)
{
 if (po->archiveFilename == ((void *)0))
 {
  po->archiveFilename = (char*) malloc(100 * sizeof(char));
  scanf("%s", po->archiveFilename);
 }
 return po->archiveFilename;
}

canonical_original_code:
char *programOptionsGetArchiveName(struct programOptions *po)
{
 if (po->archiveFilename == ((void *)0))
 {
  po->archiveFilename = (char *) malloc(100 * sizeof(char));
  scanf("%s", po->archiveFilename);
 }
 return po->archiveFilename;
}

return_type: char *


programOptionsGetFilesName

decompiled_code:
__int64 __fastcall programOptionsGetFilesName(__int64 a1)
{
return *(_QWORD *)(a1 + 16);
}

canonical_decompiled_code:
__int64 __fastcall func7(__int64 a1)
{
return *(_QWORD *)(a1 + 16);
}

original_code:
char** programOptionsGetFilesName(programOptions po)
{
 return po->filesNames;
}

canonical_original_code:
char **programOptionsGetFilesName(struct programOptions *po)
{
 return po->filesNames;
}

return_type: char **


programOptionsGetFilesCount

decompiled_code:
__int64 __fastcall programOptionsGetFilesCount(__int64 a1)
{
return *(unsigned int *)(a1 + 24);
}

canonical_decompiled_code:
__int64 __fastcall func8(__int64 a1)
{
return *(unsigned int *)(a1 + 24);
}

original_code:
unsigned int programOptionsGetFilesCount(programOptions po)
{
 return po->filesCount;
}

canonical_original_code:
unsigned int programOptionsGetFilesCount(struct programOptions *po)
{
 return po->filesCount;
}


programOptionsGetVerbose

decompiled_code:
__int64 __fastcall programOptionsGetVerbose(__int64 a1)
{
return *(unsigned int *)(a1 + 28);
}

canonical_decompiled_code:
__int64 __fastcall func9(__int64 a1)
{
return *(unsigned int *)(a1 + 28);
}

original_code:
unsigned int programOptionsGetVerbose(programOptions po)
{
 return po->verbose;
}

canonical_original_code:
unsigned int programOptionsGetVerbose(struct programOptions *po)
{
 return po->verbose;
}


programOptionsSetVerbose

decompiled_code:
void __fastcall programOptionsSetVerbose(__int64 a1, int a2)
{
*(_DWORD *)(a1 + 28) = a2;
}

canonical_decompiled_code:
void __fastcall func10(__int64 a1, int a2)
{
*(_DWORD *)(a1 + 28) = a2;
}

original_code:
void programOptionsSetVerbose(programOptions po, unsigned int verbose)
{
 po->verbose = verbose;
}

canonical_original_code:
void programOptionsSetVerbose(struct programOptions *po, unsigned int verbose)
{
 po->verbose = verbose;
}

variable_types:
verbose
unsigned int


programOptionsSetGZip

decompiled_code:
void __fastcall programOptionsSetGZip(__int64 a1, int a2)
{
*(_DWORD *)(a1 + 32) = a2;
}

canonical_decompiled_code:
void __fastcall func11(__int64 a1, int a2)
{
*(_DWORD *)(a1 + 32) = a2;
}

original_code:
void programOptionsSetGZip(programOptions po, unsigned int gzip)
{
 po->gzip = gzip;
}

canonical_original_code:
void programOptionsSetGZip(struct programOptions *po, unsigned int gzip)
{
 po->gzip = gzip;
}

variable_types:
gzip
unsigned int


programOptionsGetGZip

decompiled_code:
__int64 __fastcall programOptionsGetGZip(__int64 a1)
{
return *(unsigned int *)(a1 + 32);
}

canonical_decompiled_code:
__int64 __fastcall func12(__int64 a1)
{
return *(unsigned int *)(a1 + 32);
}

original_code:
unsigned int programOptionsGetGZip(programOptions po)
{
 return po->gzip;
}

canonical_original_code:
unsigned int programOptionsGetGZip(struct programOptions *po)
{
 return po->gzip;
}


programOptionsSetSparse

decompiled_code:
void __fastcall programOptionsSetSparse(__int64 a1, int a2)
{
*(_DWORD *)(a1 + 36) = a2;
}

canonical_decompiled_code:
void __fastcall func13(__int64 a1, int a2)
{
*(_DWORD *)(a1 + 36) = a2;
}

original_code:
void programOptionsSetSparse(programOptions po, unsigned int sparse)
{
 po->sparse = sparse;
}

canonical_original_code:
void programOptionsSetSparse(struct programOptions *po, unsigned int sparse)
{
 po->sparse = sparse;
}

variable_types:
sparse
unsigned int


multipleCommandError

decompiled_code:
void __noreturn multipleCommandError()
{
fwrite("Multiple commands found\n", 1uLL, 0x18uLL, stderr);
exit(1);
}

canonical_decompiled_code:
void __noreturn func14()
{
fwrite("Multiple commands found\n", 1uLL, 0x18uLL, stderr);
exit(1);
}

original_code:
void multipleCommandError()
{
 fprintf(stderr, "Multiple commands found\n");
 exit(1);
}


usage

decompiled_code:
void __noreturn usage()
{
puts("Usage: par <operation> [options]");
puts("For more help, type : par -h ");
exit(1);
}

canonical_decompiled_code:
void __noreturn func0()
{
puts("Usage: par <operation> [options]");
puts("For more help, type : par -h ");
exit(1);
}

original_code:
void usage()
{
 printf("Usage: par <operation> [options]\n");
 printf("For more help, type : par -h \n");
 exit(1);
}


repo: agalakhov/lr-experiments

decompiled_code:
__int64 __fastcall strarr_destroy(__int64 a1)
{
unsigned __int64 v1; // rbx
__int64 result; // rax

if ( *(_QWORD *)(a1 + 8) )
{
v1 = 0LL;
do
result = rcunref(*(_QWORD *)(a1 + 8 * v1++ + 16));
while ( *(_QWORD *)(a1 + 8) > v1 );
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1)
{
unsigned __int64 v1; // rbx
__int64 result; // rax

if ( *(_QWORD *)(a1 + 8) )
{
v1 = 0LL;
do
result = rcunref(*(_QWORD *)(a1 + 8 * v1++ + 16));
while ( *(_QWORD *)(a1 + 8) > v1 );
}
return result;
}

original_code:
static void
strarr_destroy(void *ptr)
{
    strarr_t arr = (strarr_t) ptr;
    size_t i;
    for (i = 0; i < arr->size; ++i)
        rcunref((void*)arr->data[i]);
}

canonical_original_code:
static void strarr_destroy(void *ptr)
{
    struct strarr *arr = (strarr_t) ptr;
    unsigned long i;
    for (i = 0; i < arr->size; ++i)
        rcunref((void *)arr->data[i]);
}

variable_types:
ptr
void *

variable_types: struct strarr { unsigned long space; unsigned long size; char *data[]; } *

variable_types:
i
unsigned long


decompiled_code:
__int64 __fastcall strarr_push(__int64 *a1, __int64 a2)
{
_QWORD *v2; // rbx
unsigned __int64 v3; // rax
__int64 v4; // rdx
__int64 result; // rax

v2 = a1;
v3 = a1[1] + 1;
a1[1] = v3;
if ( v3 <= *a1
|| (v4 = 2 * *a1, *a1 = v4, result = rcrealloc_free(a1, 8 * v4 + 16, strarr_destroy), (v2 = (_QWORD *)result) != 0LL) )
{
rcref(a2);
v2[v2[1] + 1] = a2;
result = (__int64)v2;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 *a1, __int64 a2)
{
_QWORD *v2; // rbx
unsigned __int64 v3; // rax
__int64 v4; // rdx
__int64 result; // rax

v2 = a1;
v3 = a1[1] + 1;
a1[1] = v3;
if ( v3 <= *a1
|| (v4 = 2 * *a1, *a1 = v4, result = rcrealloc_free(a1, 8 * v4 + 16, strarr_destroy), (v2 = (_QWORD *)result) != 0LL) )
{
rcref(a2);
v2[v2[1] + 1] = a2;
result = (__int64)v2;
}
return result;
}

original_code:
strarr_t
strarr_push(strarr_t arr, const char *str)
{
    ++(arr->size);
    if (arr->size > arr->space) {
        arr->space *= 2;
        arr = (strarr_t)rcrealloc_free(arr, sizeof(struct strarr) + arr->space * (sizeof(const char*)), strarr_destroy);
        if (! arr)
            return ((void *)0);
    }
    rcref((void*)str);
    arr->data[arr->size - 1] = str;
    return arr;
}

canonical_original_code:
struct strarr *strarr_push(struct strarr *arr, char *str)
{
    ++(arr->size);
    if (arr->size > arr->space) {
        arr->space *= 2;
        arr = (struct strarr *)rcrealloc_free(arr, sizeof(struct strarr) + arr->space * (sizeof(char *)), strarr_destroy);
        if (! arr)
            return ((void *)0);
    }
    rcref((void *)str);
    arr->data[arr->size - 1] = str;
    return arr;
}

variable_types:
arr
struct strarr *

variable_types:
str
char *

return_type: struct strarr { unsigned long space; unsigned long size; char *data[]; } *


decompiled_code:
__int64 __fastcall strarr_data(__int64 a1)
{
return a1 + 16;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1)
{
return a1 + 16;
}

original_code:
const char **
strarr_data(strarr_t arr)
{
    return arr->data;
}

canonical_original_code:
char **strarr_data(struct strarr *arr)
{
    return arr->data;
}

user_defined_types: struct strarr { unsigned long space; unsigned long size; char *data[]; }


decompiled_code:
__int64 __fastcall strarr_size(__int64 a1)
{
return *(_QWORD *)(a1 + 8);
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1)
{
return *(_QWORD *)(a1 + 8);
}

original_code:
size_t
strarr_size(strarr_t arr)
{
    return arr->size;
}

canonical_original_code:
unsigned long strarr_size(struct strarr *arr)
{
    return arr->size;
}

return_type: unsigned long


decompiled_code:
__int64 __fastcall strarr_ref(__int64 a1)
{
return rcref(a1);
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 a1)
{
return rcref(a1);
}

original_code:
void
strarr_ref(strarr_t arr)
{
    rcref(arr);
}

canonical_original_code:
void strarr_ref(struct strarr *arr)
{
    rcref(arr);
}


decompiled_code:
__int64 __fastcall strarr_unref(__int64 a1)
{
return rcunref_free(a1, strarr_destroy);
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1)
{
return rcunref_free(a1, strarr_destroy);
}

original_code:
void
strarr_unref(strarr_t arr)
{
    rcunref_free(arr, strarr_destroy);
}

canonical_original_code:
void strarr_unref(struct strarr *arr)
{
    rcunref_free(arr, strarr_destroy);
}


decompiled_code:
int __fastcall do_print(const char *a1, void *a2)
{
return vprintf(a1, a2);
}

canonical_decompiled_code:
int __fastcall func0(const char *a1, void *a2)
{
return vprintf(a1, a2);
}

original_code:
static void
do_print(const char *fmt, va_list ap)
{
    vprintf(fmt, ap);
}

canonical_original_code:
static void do_print(char *fmt, __builtin_va_list ap)
{
    vprintf(fmt, ap);
}

variable_types:
fmt
char *


canonical_decompiled_code:
void func1(void)
{
set_free(options);
}

original_code:
static void
print_options_free(void)
{
    set_free(options);
}

canonical_original_code:
static void print_options_free()
{
    set_free(options);
}


decompiled_code:
__int64 __fastcall print_opt(unsigned int a1)
{
return set_has(options, a1);
}

canonical_decompiled_code:
__int64 __fastcall func2(unsigned int a1)
{
return set_has(options, a1);
}

original_code:
_Bool
print_opt(enum print opt)
{
    return set_has(options, opt);
}

variable_types: enum print { P_GRAMMAR=0, P_SYMBOLS=1, P_NULLABLE=2, P_LR0_KERNELS=3, P_LR0_CLOSURES=4, P_LR0_GOTO=5, P_LR_REDUCE=6, P_MAX_=7 }