decompiled_code:
void __fastcall delete_handler_threads_pool(__int64 a1)
{
pthread_t *v1; // rax
pthread_t *v2; // rbp
void *thread_return; // [rsp+8h] [rbp-20h] BYREF

if ( !a1 )
_assert_fail("pool", "handler_threads_pool.c", 0x8Fu, "delete_handler_threads_pool");
while ( *(int *)(a1 + 16) > 0 )
{
v1 = (pthread_t *)remove_first_handler_thread((__int64 *)a1);
v2 = v1;
if ( !v1 )
_assert_fail("a_thread", "handler_threads_pool.c", 0x94u, "delete_handler_threads_pool");
pthread_join(*v1, &thread_return);
free(v2);
}
}

canonical_decompiled_code:
void __fastcall func4(__int64 a1)
{
pthread_t *v1; // rax
pthread_t *v2; // rbp
void *thread_return; // [rsp+8h] [rbp-20h] BYREF

if ( !a1 )
_assert_fail("pool", "handler_threads_pool.c", 0x8Fu, "delete_handler_threads_pool");
while ( *(int *)(a1 + 16) > 0 )
{
v1 = (pthread_t *)func0((__int64 *)a1);
v2 = v1;
if ( !v1 )
_assert_fail("a_thread", "handler_threads_pool.c", 0x94u, "delete_handler_threads_pool");
pthread_join(*v1, &thread_return);
free(v2);
}
}

original_code:
void
delete_handler_threads_pool(struct handler_threads_pool* pool)
{
    void* thr_retval;
    struct handler_thread* a_thread;
    ((void) sizeof ((pool) ? 1 : 0), __extension__ ({ if (pool) ; else __assert_fail ("pool", "handler_threads_pool.c", 143, __extension__ __PRETTY_FUNCTION__); }));
    while (pool->num_threads > 0) {
 a_thread = remove_first_handler_thread(pool);
 ((void) sizeof ((a_thread) ? 1 : 0), __extension__ ({ if (a_thread) ; else __assert_fail ("a_thread", "handler_threads_pool.c", 148, __extension__ __PRETTY_FUNCTION__); }));
 pthread_join(a_thread->thread, &thr_retval);
        free(a_thread);
    }
}

canonical_original_code:
void delete_handler_threads_pool(struct handler_threads_pool *pool)
{
    void *thr_retval;
    struct handler_thread *a_thread;
    ((void) sizeof ((pool) ? 1 : 0), __extension__ ({ if (pool) ; else __assert_fail ("pool", "handler_threads_pool.c", 143, __extension__ __PRETTY_FUNCTION__); }));
    while (pool->num_threads > 0) {
 a_thread = remove_first_handler_thread(pool);
 ((void) sizeof ((a_thread) ? 1 : 0), __extension__ ({ if (a_thread) ; else __assert_fail ("a_thread", "handler_threads_pool.c", 148, __extension__ __PRETTY_FUNCTION__); }));
 pthread_join(a_thread->thread, &thr_retval);
        free(a_thread);
    }
}


decompiled_code:
int __fastcall add_request(__int64 a1, int a2)
{
_QWORD *v3; // rax
_QWORD *v4; // rbp
pthread_mutex_t *v5; // rdi
int v6; // eax
pthread_mutex_t *v7; // rdi

if ( !a1 )
_assert_fail("queue", "requests_queue.c", 0x2Fu, "add_request");
v3 = malloc(0x10uLL);
v4 = v3;
if ( !v3 )
{
fwrite("add_request: out of memory\n", 1uLL, 0x1BuLL, stderr);
exit(1);
}
*(_DWORD *)v3 = a2;
v5 = *(pthread_mutex_t **)(a1 + 24);
v3[1] = 0LL;
pthread_mutex_lock(v5);
v6 = *(_DWORD *)(a1 + 16);
if ( v6 )
*(_QWORD *)(*(_QWORD *)(a1 + 8) + 8LL) = v4;
else
*(_QWORD *)a1 = v4;
*(_QWORD *)(a1 + 8) = v4;
v7 = *(pthread_mutex_t **)(a1 + 24);
*(_DWORD *)(a1 + 16) = v6 + 1;
pthread_mutex_unlock(v7);
return pthread_cond_signal(*(pthread_cond_t **)(a1 + 32));
}

canonical_decompiled_code:
int __fastcall func0(__int64 a1, int a2)
{
_QWORD *v3; // rax
_QWORD *v4; // rbp
pthread_mutex_t *v5; // rdi
int v6; // eax
pthread_mutex_t *v7; // rdi

if ( !a1 )
_assert_fail("queue", "requests_queue.c", 0x2Fu, "add_request");
v3 = malloc(0x10uLL);
v4 = v3;
if ( !v3 )
{
fwrite("add_request: out of memory\n", 1uLL, 0x1BuLL, stderr);
exit(1);
}
*(_DWORD *)v3 = a2;
v5 = *(pthread_mutex_t **)(a1 + 24);
v3[1] = 0LL;
pthread_mutex_lock(v5);
v6 = *(_DWORD *)(a1 + 16);
if ( v6 )
*(_QWORD *)(*(_QWORD *)(a1 + 8) + 8LL) = v4;
else
*(_QWORD *)a1 = v4;
*(_QWORD *)(a1 + 8) = v4;
v7 = *(pthread_mutex_t **)(a1 + 24);
*(_DWORD *)(a1 + 16) = v6 + 1;
pthread_mutex_unlock(v7);
return pthread_cond_signal(*(pthread_cond_t **)(a1 + 32));
}

original_code:
void
add_request(struct requests_queue* queue, int request_num)
{
    int rc;
    struct request* a_request;
    ((void) sizeof ((queue) ? 1 : 0), __extension__ ({ if (queue) ; else __assert_fail ("queue", "requests_queue.c", 47, __extension__ __PRETTY_FUNCTION__); }));
    a_request = (struct request*)malloc(sizeof(struct request));
    if (!a_request) {
 fprintf(stderr, "add_request: out of memory\n");
 exit(1);
    }
    a_request->number = request_num;
    a_request->next = ((void *)0);
    rc = pthread_mutex_lock(queue->p_mutex);
    if (queue->num_requests == 0) {
 queue->requests = a_request;
 queue->last_request = a_request;
    }
    else {
 queue->last_request->next = a_request;
 queue->last_request = a_request;
    }
    queue->num_requests++;
    rc = pthread_mutex_unlock(queue->p_mutex);
    rc = pthread_cond_signal(queue->p_cond_var);
}

canonical_original_code:
void add_request(struct requests_queue *queue, int request_num)
{
    int rc;
    struct request *a_request;
    ((void) sizeof ((queue) ? 1 : 0), __extension__ ({ if (queue) ; else __assert_fail ("queue", "requests_queue.c", 47, __extension__ __PRETTY_FUNCTION__); }));
    a_request = (struct request *)malloc(sizeof(struct request));
    if (!a_request) {
 fprintf(stderr, "add_request: out of memory\n");
 exit(1);
    }
    a_request->number = request_num;
    a_request->next = ((void *)0);
    rc = pthread_mutex_lock(queue->p_mutex);
    if (queue->num_requests == 0) {
 queue->requests = a_request;
 queue->last_request = a_request;
    }
    else {
 queue->last_request->next = a_request;
 queue->last_request = a_request;
    }
    queue->num_requests++;
    rc = pthread_mutex_unlock(queue->p_mutex);
    rc = pthread_cond_signal(queue->p_cond_var);
}

variable_types: struct requests_queue { struct request { int number; struct request *next; } *requests; struct request *last_request; int num_requests; union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } *p_mutex; union pthread_cond_t { struct __pthread_cond_s { union { unsigned long long __wseq; struct { unsigned int __low; unsigned int __high; } __wseq32; }; union { unsigned long long __g1_start; struct { unsigned int __low; unsigned int __high; } __g1_start32; }; unsigned int __g_refs[2]; unsigned int __g_size[2]; unsigned int __g1_orig_size; unsigned int __wrefs; unsigned int __g_signals[2]; } __data; char __size[48]; long long __align; } *p_cond_var; } *

variable_types: rc int

return_type: void

user_defined_types: struct requests_queue { struct request *requests; struct request *last_request; int num_requests; union pthread_mutex_t *p_mutex; union pthread_cond_t *p_cond_var; }

user_defined_types: union pthread_mutex_t { struct __pthread_mutex_s __data; char __size[40]; long __align; }

user_defined_types: union pthread_cond_t { struct __pthread_cond_s __data; char __size[48]; long long __align; }

user_defined_types: struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list __list; }


decompiled_code:
__int64 __fastcall get_request(__int64 *a1)
{
__int64 v1; // r12
int v2; // eax
__int64 v3; // rdx

if ( !a1 )
_assert_fail("queue", "requests_queue.c", 0x67u, "get_request");
v1 = 0LL;
pthread_mutex_lock((pthread_mutex_t *)a1[3]);
v2 = *((_DWORD *)a1 + 4);
if ( v2 > 0 )
{
v1 = *a1;
v3 = *(_QWORD *)(*a1 + 8);
*a1 = v3;
if ( !v3 )
a1[1] = 0LL;
*((_DWORD *)a1 + 4) = v2 - 1;
}
pthread_mutex_unlock((pthread_mutex_t *)a1[3]);
return v1;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 *a1)
{
__int64 v1; // r12
int v2; // eax
__int64 v3; // rdx

if ( !a1 )
_assert_fail("queue", "requests_queue.c", 0x67u, "get_request");
v1 = 0LL;
pthread_mutex_lock((pthread_mutex_t *)a1[3]);
v2 = *((_DWORD *)a1 + 4);
if ( v2 > 0 )
{
v1 = *a1;
v3 = *(_QWORD *)(*a1 + 8);
*a1 = v3;
if ( !v3 )
a1[1] = 0LL;
*((_DWORD *)a1 + 4) = v2 - 1;
}
pthread_mutex_unlock((pthread_mutex_t *)a1[3]);
return v1;
}

original_code:
struct request*
get_request(struct requests_queue* queue)
{
    int rc;
    struct request* a_request;
    ((void) sizeof ((queue) ? 1 : 0), __extension__ ({ if (queue) ; else __assert_fail ("queue", "requests_queue.c", 103, __extension__ __PRETTY_FUNCTION__); }));
    rc = pthread_mutex_lock(queue->p_mutex);
    if (queue->num_requests > 0) {
 a_request = queue->requests;
 queue->requests = a_request->next;
 if (queue->requests == ((void *)0)) {
     queue->last_request = ((void *)0);
 }
 queue->num_requests--;
    }
    else {
 a_request = ((void *)0);
    }
    rc = pthread_mutex_unlock(queue->p_mutex);
    return a_request;
}

canonical_original_code:
struct request *get_request(struct requests_queue *queue)
{
    int rc;
    struct request *a_request;
    ((void) sizeof ((queue) ? 1 : 0), __extension__ ({ if (queue) ; else __assert_fail ("queue", "requests_queue.c", 103, __extension__ __PRETTY_FUNCTION__); }));
    rc = pthread_mutex_lock(queue->p_mutex);
    if (queue->num_requests > 0) {
 a_request = queue->requests;
 queue->requests = a_request->next;
 if (queue->requests == ((void *)0)) {
     queue->last_request = ((void *)0);
 }
 queue->num_requests--;
    }
    else {
 a_request = ((void *)0);
    }
    rc = pthread_mutex_unlock(queue->p_mutex);
    return a_request;
}

variable_types: struct requests_queue { struct request *requests; struct request *last_request; int num_requests; union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } *p_mutex; union pthread_cond_t { struct __pthread_cond_s { union { unsigned long long __wseq; struct { unsigned int __low; unsigned int __high; } __wseq32; }; union { unsigned long long __g1_start; struct { unsigned int __low; unsigned int __high; } __g1_start32; }; unsigned int __g_refs[2]; unsigned int __g_size[2]; unsigned int __g1_orig_size; unsigned int __wrefs; unsigned int __g_signals[2]; } __data; char __size[48]; long long __align; } *p_cond_var; } *

variable_types: struct request { int number; struct request *next; } *


decompiled_code:
__int64 __fastcall get_requests_number(__int64 a1)
{
unsigned int v1; // er12

if ( !a1 )
_assert_fail("queue", "requests_queue.c", 0x8Cu, "get_requests_number");
pthread_mutex_lock(*(pthread_mutex_t **)(a1 + 24));
v1 = *(_DWORD *)(a1 + 16);
pthread_mutex_unlock(*(pthread_mutex_t **)(a1 + 24));
return v1;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1)
{
unsigned int v1; // er12

if ( !a1 )
_assert_fail("queue", "requests_queue.c", 0x8Cu, "get_requests_number");
pthread_mutex_lock(*(pthread_mutex_t **)(a1 + 24));
v1 = *(_DWORD *)(a1 + 16);
pthread_mutex_unlock(*(pthread_mutex_t **)(a1 + 24));
return v1;
}

original_code:
int
get_requests_number(struct requests_queue* queue)
{
    int rc;
    int num_requests;
    ((void) sizeof ((queue) ? 1 : 0), __extension__ ({ if (queue) ; else __assert_fail ("queue", "requests_queue.c", 140, __extension__ __PRETTY_FUNCTION__); }));
    rc = pthread_mutex_lock(queue->p_mutex);
    num_requests = queue->num_requests;
    rc = pthread_mutex_unlock(queue->p_mutex);
    return num_requests;
}

canonical_original_code:
int get_requests_number(struct requests_queue *queue)
{
    int rc;
    int num_requests;
    ((void) sizeof ((queue) ? 1 : 0), __extension__ ({ if (queue) ; else __assert_fail ("queue", "requests_queue.c", 140, __extension__ __PRETTY_FUNCTION__); }));
    rc = pthread_mutex_lock(queue->p_mutex);
    num_requests = queue->num_requests;
    rc = pthread_mutex_unlock(queue->p_mutex);
    return num_requests;
}

return_type: int

user_defined_types: struct request { int number; struct request *next; }

user_defined_types: struct __pthread_cond_s { union { unsigned long long __wseq; struct { unsigned int __low; unsigned int __high; } __wseq32; }; union { unsigned long long __g1_start; struct { unsigned int __low; unsigned int __high; } __g1_start32; }; unsigned int __g_refs[2]; unsigned int __g_size[2]; unsigned int __g1_orig_size; unsigned int __wrefs; unsigned int __g_signals[2]; }

user_defined_types: struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; }


decompiled_code:
void __fastcall delete_requests_queue(void *ptr)
{
void *v1; // rax

if ( !ptr )
_assert_fail("queue", "requests_queue.c", 0xA5u, "delete_requests_queue");
while ( *((int *)ptr + 4) > 0 )
{
v1 = (void *)get_request((__int64 *)ptr);
free(v1);
}
free(ptr);
}

canonical_decompiled_code:
void __fastcall func3(void *ptr)
{
void *v1; // rax

if ( !ptr )
_assert_fail("queue", "requests_queue.c", 0xA5u, "delete_requests_queue");
while ( *((int *)ptr + 4) > 0 )
{
v1 = (void *)func1((__int64 *)ptr);
free(v1);
}
free(ptr);
}

original_code:
void
delete_requests_queue(struct requests_queue* queue)
{
    struct request* a_request;
    ((void) sizeof ((queue) ? 1 : 0), __extension__ ({ if (queue) ; else __assert_fail ("queue", "requests_queue.c", 165, __extension__ __PRETTY_FUNCTION__); }));
    while (queue->num_requests > 0) {
 a_request = get_request(queue);
 free(a_request);
    }
    free(queue);
}

canonical_original_code:
void delete_requests_queue(struct requests_queue *queue)
{
    struct request *a_request;
    ((void) sizeof ((queue) ? 1 : 0), __extension__ ({ if (queue) ; else __assert_fail ("queue", "requests_queue.c", 165, __extension__ __PRETTY_FUNCTION__); }));
    while (queue->num_requests > 0) {
 a_request = get_request(queue);
 free(a_request);
    }
    free(queue);
}


decompiled_code:
int __fastcall cleanup_free_mutex(pthread_mutex_t *a1)
{
int result; // eax

if ( a1 )
result = pthread_mutex_unlock(a1);
return result;
}

canonical_decompiled_code:
int __fastcall func0(pthread_mutex_t *a1)
{
int result; // eax

if ( a1 )
result = pthread_mutex_unlock(a1);
return result;
}

original_code:
static void
cleanup_free_mutex(void* a_mutex)
{
    pthread_mutex_t* p_mutex = (pthread_mutex_t*)a_mutex;
    if (p_mutex)
        pthread_mutex_unlock(p_mutex);
}

canonical_original_code:
static void cleanup_free_mutex(void *a_mutex)
{
    union pthread_mutex_t *p_mutex = (pthread_mutex_t*)a_mutex;
    if (p_mutex)
        pthread_mutex_unlock(p_mutex);
}

variable_types: union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } *


decompiled_code:
void __fastcall __noreturn handle_requests_loop(unsigned int *a1)
{
void *v1; // rbp
pthread_mutex_t *v2; // [rsp+8h] [rbp-90h]
__pthread_unwind_buf_t buf; // [rsp+10h] [rbp-88h] BYREF

if ( a1 )
{
printf("Starting thread '%d'\n", *a1);
fflush(stdout);
pthread_setcancelstate(0, 0LL);
pthread_setcanceltype(0, 0LL);
v2 = (pthread_mutex_t *)*((_QWORD *)a1 + 1);
if ( !_sigsetjmp((struct __jmp_buf_tag *)&buf, 0) )
{
_pthread_register_cancel(&buf);
pthread_mutex_lock(*((pthread_mutex_t **)a1 + 1));
while ( 1 )
{
while ( (int)get_requests_number(*((_QWORD *)a1 + 3)) <= 0 )
{
if ( done_creating_requests )
{
pthread_mutex_unlock(*((pthread_mutex_t **)a1 + 1));
printf("thread '%d' exiting\n", *a1);
fflush(stdout);
pthread_exit(0LL);
}
pthread_cond_wait(*((pthread_cond_t **)a1 + 2), *((pthread_mutex_t **)a1 + 1));
}
v1 = (void *)get_request(*((_QWORD *)a1 + 3));
if ( v1 )
{
pthread_mutex_unlock(*((pthread_mutex_t **)a1 + 1));
free(v1);
pthread_mutex_lock(*((pthread_mutex_t **)a1 + 1));
}
}
}
cleanup_free_mutex(v2);
_pthread_unwind_next(&buf);
}
_assert_fail("data", "handler_thread.c", 0x42u, "handle_requests_loop");
}

canonical_decompiled_code:
void __fastcall __noreturn func1(unsigned int *a1)
{
void *v1; // rbp
pthread_mutex_t *v2; // [rsp+8h] [rbp-90h]
__pthread_unwind_buf_t buf; // [rsp+10h] [rbp-88h] BYREF

if ( a1 )
{
printf("Starting thread '%d'\n", *a1);
fflush(stdout);
pthread_setcancelstate(0, 0LL);
pthread_setcanceltype(0, 0LL);
v2 = (pthread_mutex_t *)*((_QWORD *)a1 + 1);
if ( !_sigsetjmp((struct __jmp_buf_tag *)&buf, 0) )
{
_pthread_register_cancel(&buf);
pthread_mutex_lock(*((pthread_mutex_t **)a1 + 1));
while ( 1 )
{
while ( (int)get_requests_number(*((_QWORD *)a1 + 3)) <= 0 )
{
if ( done_creating_requests )
{
pthread_mutex_unlock(*((pthread_mutex_t **)a1 + 1));
printf("thread '%d' exiting\n", *a1);
fflush(stdout);
pthread_exit(0LL);
}
pthread_cond_wait(*((pthread_cond_t **)a1 + 2), *((pthread_mutex_t **)a1 + 1));
}
v1 = (void *)get_request(*((_QWORD *)a1 + 3));
if ( v1 )
{
pthread_mutex_unlock(*((pthread_mutex_t **)a1 + 1));
free(v1);
pthread_mutex_lock(*((pthread_mutex_t **)a1 + 1));
}
}
}
func0(v2);
_pthread_unwind_next(&buf);
}
_assert_fail("data", "handler_thread.c", 0x42u, "handle_requests_loop");
}

original_code:
void*
handle_requests_loop(void* thread_params)
{
    int rc;
    struct request* a_request;
    struct handler_thread_params *data;
    data = (struct handler_thread_params*)thread_params;
    ((void) sizeof ((data) ? 1 : 0), __extension__ ({ if (data) ; else __assert_fail ("data", "handler_thread.c", 66, __extension__ __PRETTY_FUNCTION__); }));
    printf("Starting thread '%d'\n", data->thread_id);
    fflush(stdout);
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, ((void *)0));
    pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, ((void *)0));
    do { __pthread_unwind_buf_t __cancel_buf; void (*__cancel_routine) (void *) = (cleanup_free_mutex); void *__cancel_arg = ((void*)data->request_mutex); int __not_first_call = __sigsetjmp ((struct __jmp_buf_tag *) (void *) __cancel_buf.__cancel_jmp_buf, 0); if (__builtin_expect ((__not_first_call), 0)) { __cancel_routine (__cancel_arg); __pthread_unwind_next (&__cancel_buf); } __pthread_register_cancel (&__cancel_buf); do {;
    rc = pthread_mutex_lock(data->request_mutex);
    while (1) {
        int num_requests = get_requests_number(data->requests);
 if (num_requests > 0) {
     a_request = get_request(data->requests);
     if (a_request) {
      rc = pthread_mutex_unlock(data->request_mutex);
  handle_request(a_request, data->thread_id);
  free(a_request);
      rc = pthread_mutex_lock(data->request_mutex);
     }
 }
 else {
     if (done_creating_requests) {
                pthread_mutex_unlock(data->request_mutex);
  printf("thread '%d' exiting\n", data->thread_id);
  fflush(stdout);
  pthread_exit(((void *)0));
     }
     rc = pthread_cond_wait(data->got_request, data->request_mutex);
 }
    }
    do { } while (0); } while (0); __pthread_unregister_cancel (&__cancel_buf); if (0) __cancel_routine (__cancel_arg); } while (0);
}

canonical_original_code:
void *handle_requests_loop(void *thread_params)
{
    int rc;
    struct request *a_request;
    struct handler_thread_params *data;
    data = (struct handler_thread_params *)thread_params;
    ((void) sizeof ((data) ? 1 : 0), __extension__ ({ if (data) ; else __assert_fail ("data", "handler_thread.c", 66, __extension__ __PRETTY_FUNCTION__); }));
    printf("Starting thread '%d'\n", data->thread_id);
    fflush(stdout);
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, ((void *)0));
    pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, ((void *)0));
    do { struct __pthread_unwind_buf_t __cancel_buf; void (*__cancel_routine)(void *) = (cleanup_free_mutex); void *__cancel_arg = ((void*)data->request_mutex); int __not_first_call = __sigsetjmp ((struct __jmp_buf_tag *) (void *) __cancel_buf.__cancel_jmp_buf, 0); if (__builtin_expect ((__not_first_call), 0)) { __cancel_routine (__cancel_arg); __pthread_unwind_next (&__cancel_buf); } __pthread_register_cancel (&__cancel_buf); do {;
    rc = pthread_mutex_lock(data->request_mutex);
    while (1) {
        int num_requests = get_requests_number(data->requests);
 if (num_requests > 0) {
     a_request = get_request(data->requests);
     if (a_request) {
      rc = pthread_mutex_unlock(data->request_mutex);
  handle_request(a_request, data->thread_id);
  free(a_request);
      rc = pthread_mutex_lock(data->request_mutex);
     }
 }
 else {
     if (done_creating_requests) {
                pthread_mutex_unlock(data->request_mutex);
  printf("thread '%d' exiting\n", data->thread_id);
  fflush(stdout);
  pthread_exit(((void *)0));
     }
     rc = pthread_cond_wait(data->got_request, data->request_mutex);
 }
    }
    do { } while (0); } while (0); __pthread_unregister_cancel (&__cancel_buf); if (0) __cancel_routine (__cancel_arg); } while (0);
}

variable_types: struct handler_thread_params { int thread_id; union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } *request_mutex; union pthread_cond_t { struct __pthread_cond_s { union { unsigned long long __wseq; struct { unsigned int __low; unsigned int __high; } __wseq32; }; union { unsigned long long __g1_start; struct { unsigned int __low; unsigned int __high; } __g1_start32; }; unsigned int __g_refs[2]; unsigned int __g_size[2]; unsigned int __g1_orig_size; unsigned int __wrefs; unsigned int __g_signals[2]; } __data; char __size[48]; long long __align; } *got_request; struct requests_queue { struct request { int number; struct request *next; } *requests; struct request *last_request; int num_requests; union pthread_mutex_t *p_mutex; union pthread_cond_t *p_cond_var; } *requests; } *

variable_types: struct __pthread_unwind_buf_t { struct { long __cancel_jmp_buf[8]; int __mask_was_saved; } __cancel_jmp_buf[1]; void *__pad[4]; }

return_type: void *

user_defined_types: struct handler_thread_params { int thread_id; union pthread_mutex_t *request_mutex; union pthread_cond_t *got_request; struct requests_queue *requests; }


zlibVersion

decompiled_code:
const char *zlibVersion()
{
return "1.2.3";
}

canonical_decompiled_code:
const char *func0()
{
return "1.2.3";
}

original_code:
const char * zlibVersion()
{
    return "1.2.3";
}

canonical_original_code:
char *zlibVersion()
{
    return "1.2.3";
}

return_type: char *


zlibCompileFlags

decompiled_code:
__int64 zlibCompileFlags()
{
return 169LL;
}

canonical_decompiled_code:
__int64 func1()
{
return 169LL;
}

original_code:
uLong zlibCompileFlags()
{
    uLong flags;
    flags = 0;
    switch (sizeof(uInt)) {
    case 2: break;
    case 4: flags += 1; break;
    case 8: flags += 2; break;
    default: flags += 3;
    }
    switch (sizeof(uLong)) {
    case 2: break;
    case 4: flags += 1 << 2; break;
    case 8: flags += 2 << 2; break;
    default: flags += 3 << 2;
    }
    switch (sizeof(voidpf)) {
    case 2: break;
    case 4: flags += 1 << 4; break;
    case 8: flags += 2 << 4; break;
    default: flags += 3 << 4;
    }
    switch (sizeof(long)) {
    case 2: break;
    case 4: flags += 1 << 6; break;
    case 8: flags += 2 << 6; break;
    default: flags += 3 << 6;
    }
    return flags;
}

canonical_original_code:
unsigned long zlibCompileFlags()
{
    unsigned long flags;
    flags = 0;
    switch (sizeof(uInt)) {
    case 2: break;
    case 4: flags += 1; break;
    case 8: flags += 2; break;
    default: flags += 3;
    }
    switch (sizeof(uLong)) {
    case 2: break;
    case 4: flags += 1 << 2; break;
    case 8: flags += 2 << 2; break;
    default: flags += 3 << 2;
    }
    switch (sizeof(voidpf)) {
    case 2: break;
    case 4: flags += 1 << 4; break;
    case 8: flags += 2 << 4; break;
    default: flags += 3 << 4;
    }
    switch (sizeof(long)) {
    case 2: break;
    case 4: flags += 1 << 6; break;
    case 8: flags += 2 << 6; break;
    default: flags += 3 << 6;
    }
    return flags;
}

variable_types:
flags
unsigned long

return_type: unsigned long


decompiled_code:
__int64 *get_crc_table()
{
return crc_table;
}

canonical_decompiled_code:
__int64 *func3()
{
return crc_table;
}

original_code:
const unsigned long * get_crc_table()
{
    return (const unsigned long *)crc_table;
}

canonical_original_code:
unsigned long *get_crc_table()
{
    return (unsigned long *)crc_table;
}

return_type: unsigned long *


decompiled_code:
int print_config()
{
printf("In this computer, sizeof int = %u\n", 4LL);
return printf("and sizeof uint16_t = %u\n\n", 2LL);
}

canonical_decompiled_code:
int func0()
{
printf("In this computer, sizeof int = %u\n", 4LL);
return printf("and sizeof uint16_t = %u\n\n", 2LL);
}

original_code:
void print_config(void)
{
    printf("In this computer, sizeof int = %u\n",sizeof(int));
    printf("and sizeof uint16_t = %u\n\n",sizeof(uint16_t));
}

canonical_original_code:
void print_config()
{
    printf("In this computer, sizeof int = %u\n",sizeof(int));
    printf("and sizeof uint16_t = %u\n\n",sizeof(unsigned short));
}


main

canonical_name: main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // esi
__int64 *v4; // rsi
__int64 *v5; // r8
__int64 v6; // rdx
_QWORD *v7; // rcx
_QWORD *v8; // r13
unsigned int v9; // er14
__int64 v10; // rax
__int64 v11; // rax
__int64 v12; // rbx
__int64 v13; // rax
unsigned __int16 *v14; // rdx
unsigned __int16 *v15; // rax
__int64 v16; // rdi
unsigned __int16 v17; // ax
__int64 v18; // rbp
unsigned __int16 v19; // ax
unsigned int v20; // ebp
unsigned __int16 v21; // ax
unsigned __int16 *v23; // [rsp+8h] [rbp-17E0h]
__int64 v24; // [rsp+10h] [rbp-17D8h]
__int16 v25; // [rsp+18h] [rbp-17D0h]
unsigned int v26; // [rsp+1Ch] [rbp-17CCh]
_QWORD *v27; // [rsp+20h] [rbp-17C8h]
_QWORD *v28; // [rsp+28h] [rbp-17C0h]
__int64 v29; // [rsp+30h] [rbp-17B8h]
__int64 v30; // [rsp+38h] [rbp-17B0h]
unsigned int v31; // [rsp+44h] [rbp-17A4h]
_QWORD *v32; // [rsp+48h] [rbp-17A0h]
__int64 v33; // [rsp+50h] [rbp-1798h]
unsigned __int16 *ptr; // [rsp+58h] [rbp-1790h]
unsigned __int16 v35; // [rsp+6Ch] [rbp-177Ch] BYREF
unsigned __int16 v36; // [rsp+6Eh] [rbp-177Ah] BYREF
unsigned __int16 v37; // [rsp+70h] [rbp-1778h] BYREF
unsigned __int16 v38; // [rsp+72h] [rbp-1776h] BYREF
unsigned __int16 v39; // [rsp+74h] [rbp-1774h] BYREF
unsigned __int16 v40; // [rsp+76h] [rbp-1772h] BYREF
unsigned __int16 v41; // [rsp+78h] [rbp-1770h] BYREF
unsigned __int16 v42; // [rsp+7Ah] [rbp-176Eh] BYREF
unsigned __int16 v43; // [rsp+7Ch] [rbp-176Ch] BYREF
unsigned __int16 v44; // [rsp+7Eh] [rbp-176Ah] BYREF
unsigned __int16 v45; // [rsp+80h] [rbp-1768h] BYREF
__int16 v46; // [rsp+82h] [rbp-1766h] BYREF
unsigned int v47; // [rsp+84h] [rbp-1764h] BYREF
unsigned int v48; // [rsp+88h] [rbp-1760h] BYREF
unsigned int v49; // [rsp+8Ch] [rbp-175Ch] BYREF
char v50[6]; // [rsp+90h] [rbp-1758h] BYREF
char v51; // [rsp+96h] [rbp-1752h] BYREF
char v52[32]; // [rsp+A0h] [rbp-1748h] BYREF
__int64 v53[4]; // [rsp+C0h] [rbp-1728h] BYREF
__int64 v54[2]; // [rsp+E0h] [rbp-1708h] BYREF
char v55; // [rsp+F0h] [rbp-16F8h] BYREF
char v56; // [rsp+6A0h] [rbp-1148h] BYREF
char v57; // [rsp+C50h] [rbp-B98h] BYREF
char v58; // [rsp+1200h] [rbp-5E8h] BYREF

v29 = ui16colorim(0LL, 479LL, 0LL, 719LL);
v30 = ui16colorim(0LL, 479LL, 0LL, 719LL);
printf("Image pipeline version %f\n", *(double *)&LC2);
print_config();
ptr = (unsigned __int16 *)malloc(0x10uLL);
readPGM("inputGRBG10bitg2p2.pgm", ptr);
v32 = (_QWORD *)*((_QWORD *)ptr + 1);
v3 = *ptr - 1;
v53[0] = (__int64)&v55;
v53[1] = (__int64)&v56;
v53[2] = (__int64)&v57;
v53[3] = (__int64)&v58;
v54[0] = (__int64)&v51;
v33 = ui16vector(0LL, v3);
v24 = ui16vector(0LL, ptr[1] - 1);
construct_lens_profile(0LL, v33, v24);
v35 = 32;
v36 = 32;
v37 = 32;
choosematrix(v52, 32LL, 32LL);
v39 = 8;
v4 = v53;
v5 = v54;
v38 = 1;
v46 = 1;
v49 = 0;
v48 = 0;
v47 = 0;
do
{
v6 = *v4++;
*(_QWORD *)v6 = 0LL;
*(_QWORD *)(v6 + 1440) = 0LL;
memset(
(void *)((v6 + 8) & 0xFFFFFFFFFFFFFFF8LL),
0,
8LL * (((unsigned int)v6 - (((_DWORD)v6 + 8) & 0xFFFFFFF8) + 1448) >> 3));
}
while ( v54 != v4 );
v7 = 0LL;
v8 = v32;
v9 = 0;
v10 = v54[0];
v25 = -181;
v31 = 0;
*(_QWORD *)v54[0] = 0LL;
*(_WORD *)(v10 + 8) = 0;
v26 = 0;
v23 = (unsigned __int16 *)v33;
do
{
v11 = 8LL * (unsigned __int16)(v25 + 177);
v27 = (_QWORD *)(v11 + v30);
v12 = 0LL;
v28 = (_QWORD *)(v29 + v11);
while ( 1 )
{
v16 = (unsigned __int16)black_level_subtract(*(unsigned __int16 *)(*v8 + 2 * v12), 1LL, v6, v7, v5);
v17 = lens_shading_correction(v16, *v23, *(unsigned __int16 *)(v24 + 2 * v12));
v18 = (unsigned __int16)awb_sums_and_cga(v17, v9, (unsigned int)v12, v35, v36, v37, &v47, &v48, &v49);
update_buffer(v18, v53);
if ( (unsigned __int16)v9 <= 3u )
{
v42 = v18;
v41 = v18;
v40 = v18;
}
else
{
colorinterpolate_noisereduce(v53, (unsigned __int16)(v25 + 177), (unsigned int)v12, 34LL, &v40, &v41, &v42);
}
colorcorrect(v52, &v40, &v41, &v42);
v40 = gammacorrect_LUT(v40);
v41 = gammacorrect_LUT(v41);
v19 = gammacorrect_LUT(v42);
v20 = v43;
v42 = v19;
rgb2yuv(v40, v41, v19, &v43, &v44, &v45);
v26 += (unsigned __int16)absdiff16(v20, v43);
if ( (unsigned __int16)v25 <= 0x166u && (unsigned __int16)(v12 - 181) <= 0x166u )
{
v31 += (unsigned __int16)absdiff16(v20, v43);
LABEL_6:
v13 = (unsigned __int16)(v12 - 2);
v14 = *(unsigned __int16 **)(*v27 + 8 * v13);
*v14 = v40;
v14[1] = v41;
v14[2] = v42;
v7 = v28;
v15 = *(unsigned __int16 **)(*v28 + 8 * v13);
*v15 = v43;
v15[1] = v44;
v6 = v45;
v15[2] = v45;
goto LABEL_7;
}
if ( (unsigned __int16)v12 > 1u && (unsigned __int16)v9 > 3u && (unsigned __int16)v12 <= 0x2D1u )
goto LABEL_6;
if ( (_WORD)v12 == 723 )
break;
LABEL_7:
++v12;
}
++v25;
++v9;
++v8;
++v23;
}
while ( v25 != 303 );
awb(v47, v48, v49, &v35, &v36, &v37);
printf("awb output: R=%d, G=%d, B=%d\n", v35, v36, v37);
choosematrix(v52, v35, v37);
autoexposure(v47, v48, v49, &v38, &v39);
printf("ae output: Texp=%d Gain=%d\n", v39, v38);
v21 = autofocus(16LL, v31, v50, &v46, 1LL);
printf("af output: E=%d EW=%d and focus setting %d\n", v26, v31, v21);
puts("Output in RGB 444 format");
writeppm("output.ppm", v30);
free_ui16vector(v33, 0LL, 483LL);
free_ui16vector(v24, 0LL, 723LL);
free_ui16colorim(v29, 0LL, 479LL, 0LL, 719LL);
free_ui16colorim(v30, 0LL, 479LL, 0LL, 719LL);
free_ui16matrix(v32, 0LL, 479LL, 0LL, 719LL);
free(ptr);
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // esi
__int64 *v4; // rsi
__int64 *v5; // r8
__int64 v6; // rdx
_QWORD *v7; // rcx
_QWORD *v8; // r13
unsigned int v9; // er14
__int64 v10; // rax
__int64 v11; // rax
__int64 v12; // rbx
__int64 v13; // rax
unsigned __int16 *v14; // rdx
unsigned __int16 *v15; // rax
__int64 v16; // rdi
unsigned __int16 v17; // ax
__int64 v18; // rbp
unsigned __int16 v19; // ax
unsigned int v20; // ebp
unsigned __int16 v21; // ax
unsigned __int16 *v23; // [rsp+8h] [rbp-17E0h]
__int64 v24; // [rsp+10h] [rbp-17D8h]
__int16 v25; // [rsp+18h] [rbp-17D0h]
unsigned int v26; // [rsp+1Ch] [rbp-17CCh]
_QWORD *v27; // [rsp+20h] [rbp-17C8h]
_QWORD *v28; // [rsp+28h] [rbp-17C0h]
__int64 v29; // [rsp+30h] [rbp-17B8h]
__int64 v30; // [rsp+38h] [rbp-17B0h]
unsigned int v31; // [rsp+44h] [rbp-17A4h]
_QWORD *v32; // [rsp+48h] [rbp-17A0h]
__int64 v33; // [rsp+50h] [rbp-1798h]
unsigned __int16 *ptr; // [rsp+58h] [rbp-1790h]
unsigned __int16 v35; // [rsp+6Ch] [rbp-177Ch] BYREF
unsigned __int16 v36; // [rsp+6Eh] [rbp-177Ah] BYREF
unsigned __int16 v37; // [rsp+70h] [rbp-1778h] BYREF
unsigned __int16 v38; // [rsp+72h] [rbp-1776h] BYREF
unsigned __int16 v39; // [rsp+74h] [rbp-1774h] BYREF
unsigned __int16 v40; // [rsp+76h] [rbp-1772h] BYREF
unsigned __int16 v41; // [rsp+78h] [rbp-1770h] BYREF
unsigned __int16 v42; // [rsp+7Ah] [rbp-176Eh] BYREF
unsigned __int16 v43; // [rsp+7Ch] [rbp-176Ch] BYREF
unsigned __int16 v44; // [rsp+7Eh] [rbp-176Ah] BYREF
unsigned __int16 v45; // [rsp+80h] [rbp-1768h] BYREF
__int16 v46; // [rsp+82h] [rbp-1766h] BYREF
unsigned int v47; // [rsp+84h] [rbp-1764h] BYREF
unsigned int v48; // [rsp+88h] [rbp-1760h] BYREF
unsigned int v49; // [rsp+8Ch] [rbp-175Ch] BYREF
char v50[6]; // [rsp+90h] [rbp-1758h] BYREF
char v51; // [rsp+96h] [rbp-1752h] BYREF
char v52[32]; // [rsp+A0h] [rbp-1748h] BYREF
__int64 v53[4]; // [rsp+C0h] [rbp-1728h] BYREF
__int64 v54[2]; // [rsp+E0h] [rbp-1708h] BYREF
char v55; // [rsp+F0h] [rbp-16F8h] BYREF
char v56; // [rsp+6A0h] [rbp-1148h] BYREF
char v57; // [rsp+C50h] [rbp-B98h] BYREF
char v58; // [rsp+1200h] [rbp-5E8h] BYREF

v29 = ui16colorim(0LL, 479LL, 0LL, 719LL);
v30 = ui16colorim(0LL, 479LL, 0LL, 719LL);
printf("Image pipeline version %f\n", *(double *)&LC2);
func0();
ptr = (unsigned __int16 *)malloc(0x10uLL);
readPGM("inputGRBG10bitg2p2.pgm", ptr);
v32 = (_QWORD *)*((_QWORD *)ptr + 1);
v3 = *ptr - 1;
v53[0] = (__int64)&v55;
v53[1] = (__int64)&v56;
v53[2] = (__int64)&v57;
v53[3] = (__int64)&v58;
v54[0] = (__int64)&v51;
v33 = ui16vector(0LL, v3);
v24 = ui16vector(0LL, ptr[1] - 1);
construct_lens_profile(0LL, v33, v24);
v35 = 32;
v36 = 32;
v37 = 32;
choosematrix(v52, 32LL, 32LL);
v39 = 8;
v4 = v53;
v5 = v54;
v38 = 1;
v46 = 1;
v49 = 0;
v48 = 0;
v47 = 0;
do
{
v6 = *v4++;
*(_QWORD *)v6 = 0LL;
*(_QWORD *)(v6 + 1440) = 0LL;
memset(
(void *)((v6 + 8) & 0xFFFFFFFFFFFFFFF8LL),
0,
8LL * (((unsigned int)v6 - (((_DWORD)v6 + 8) & 0xFFFFFFF8) + 1448) >> 3));
}
while ( v54 != v4 );
v7 = 0LL;
v8 = v32;
v9 = 0;
v10 = v54[0];
v25 = -181;
v31 = 0;
*(_QWORD *)v54[0] = 0LL;
*(_WORD *)(v10 + 8) = 0;
v26 = 0;
v23 = (unsigned __int16 *)v33;
do
{
v11 = 8LL * (unsigned __int16)(v25 + 177);
v27 = (_QWORD *)(v11 + v30);
v12 = 0LL;
v28 = (_QWORD *)(v29 + v11);
while ( 1 )
{
v16 = (unsigned __int16)black_level_subtract(*(unsigned __int16 *)(*v8 + 2 * v12), 1LL, v6, v7, v5);
v17 = lens_shading_correction(v16, *v23, *(unsigned __int16 *)(v24 + 2 * v12));
v18 = (unsigned __int16)awb_sums_and_cga(v17, v9, (unsigned int)v12, v35, v36, v37, &v47, &v48, &v49);
update_buffer(v18, v53);
if ( (unsigned __int16)v9 <= 3u )
{
v42 = v18;
v41 = v18;
v40 = v18;
}
else
{
colorinterpolate_noisereduce(v53, (unsigned __int16)(v25 + 177), (unsigned int)v12, 34LL, &v40, &v41, &v42);
}
colorcorrect(v52, &v40, &v41, &v42);
v40 = gammacorrect_LUT(v40);
v41 = gammacorrect_LUT(v41);
v19 = gammacorrect_LUT(v42);
v20 = v43;
v42 = v19;
rgb2yuv(v40, v41, v19, &v43, &v44, &v45);
v26 += (unsigned __int16)absdiff16(v20, v43);
if ( (unsigned __int16)v25 <= 0x166u && (unsigned __int16)(v12 - 181) <= 0x166u )
{
v31 += (unsigned __int16)absdiff16(v20, v43);
LABEL_6:
v13 = (unsigned __int16)(v12 - 2);
v14 = *(unsigned __int16 **)(*v27 + 8 * v13);
*v14 = v40;
v14[1] = v41;
v14[2] = v42;
v7 = v28;
v15 = *(unsigned __int16 **)(*v28 + 8 * v13);
*v15 = v43;
v15[1] = v44;
v6 = v45;
v15[2] = v45;
goto LABEL_7;
}
if ( (unsigned __int16)v12 > 1u && (unsigned __int16)v9 > 3u && (unsigned __int16)v12 <= 0x2D1u )
goto LABEL_6;
if ( (_WORD)v12 == 723 )
break;
LABEL_7:
++v12;
}
++v25;
++v9;
++v8;
++v23;
}
while ( v25 != 303 );
awb(v47, v48, v49, &v35, &v36, &v37);
printf("awb output: R=%d, G=%d, B=%d\n", v35, v36, v37);
choosematrix(v52, v35, v37);
autoexposure(v47, v48, v49, &v38, &v39);
printf("ae output: Texp=%d Gain=%d\n", v39, v38);
v21 = autofocus(16LL, v31, v50, &v46, 1LL);
printf("af output: E=%d EW=%d and focus setting %d\n", v26, v31, v21);
puts("Output in RGB 444 format");
writeppm("output.ppm", v30);
free_ui16vector(v33, 0LL, 483LL);
free_ui16vector(v24, 0LL, 723LL);
free_ui16colorim(v29, 0LL, 479LL, 0LL, 719LL);
free_ui16colorim(v30, 0LL, 479LL, 0LL, 719LL);
free_ui16matrix(v32, 0LL, 479LL, 0LL, 719LL);
free(ptr);
return 0;
}

original_code:
int main ()
{
    uint16_t **I,**Irgb565,***Ic,***Iyuv,***Iycc, ***Ibtu;
    PGMData *inputpgm, *outputpgm;
    uint16_t noise_threshold;
    uint32_t rsum,gsum,bsum;
    uint16_t awb_R,awb_G,awb_B;
    uint16_t Gain,Texp;
    uint16_t *row_prf, *col_prf;
    uint16_t r,c;
    uint16_t r2,c2;
    uint16_t pixel;
    uint16_t red,green,blue;
    uint16_t y,u,v,prevy;
    int16_t ccm[3][3];
    uint32_t edginess;
    uint32_t edginess_window;
    uint32_t prev_edginess;
    uint32_t focus;
    uint16_t focus_stepsize;
    int16_t focus_direction;
    uint16_t field = 0;
    InputFormat input = PIXELARRAY;
    OutputFormat output = RGB444;
    Iyuv = ui16colorim(0,480 -1,0,720 -1);
    Ic = ui16colorim(0,480 -1,0,720 -1);
    printf("Image pipeline version %f\n",0.5);
    print_config();
    inputpgm = (PGMData *)malloc(sizeof(PGMData));
    if (input != TESTPATTERN)
    {
        readPGM("inputGRBG10bitg2p2.pgm",inputpgm);
        I = inputpgm->matrix;
    }
 uint16_t row1[724],row2[724],row3[724],row4[724],row5[5] ;
 uint16_t *buffer[5] = {row1,row2,row3,row4,row5};
    row_prf = ui16vector(0,inputpgm->height-1);
    col_prf = ui16vector(0,inputpgm->width-1);
    construct_lens_profile(0, row_prf, col_prf);
    awb_R = 1<<5; awb_G = 1<<5; awb_B = 1<<5;
    choosematrix(ccm,awb_R,awb_B);
    Texp = 8;
    Gain = 1;
    focus_direction = 1;
 focus = 16;
 focus_stepsize = 1;
    rsum = gsum = bsum = 0;
    noise_threshold = 33 - Gain + (Texp>>2);
    if (noise_threshold < 16)
        noise_threshold = 16;
    for (r=0; r<5 -1;r++)
        for (c=0; c<724; c++)
            buffer[r][c] = 0;
  for (c=0; c<5; c++)
            buffer[4][c] = 0;
    edginess = 0;
    edginess_window = 0;
    for (r=0; r<484; r++)
    {
        for (c=0; c<724; c++)
        {
            if (input == TESTPATTERN)
                pixel = test_pattern_generator();
            else
                pixel = I[r][c];
            pixel = black_level_subtract(pixel,1);
            pixel = lens_shading_correction(pixel, row_prf[r], col_prf[c]);
            pixel = awb_sums_and_cga(pixel, r, c, awb_R, awb_G, awb_B, &rsum, &gsum, &bsum);
            update_buffer(pixel, buffer);
            if (r >= (5 - 1))
            {
                colorinterpolate_noisereduce(buffer,r-(5 - 1),c,noise_threshold,&red,&green,&blue);
            } else {
                red = green = blue = pixel;
            }
            colorcorrect(ccm,&red,&green,&blue);
            red = gammacorrect_LUT(red);
   green = gammacorrect_LUT(green);
            blue = gammacorrect_LUT(blue);
            prevy = y;
            rgb2yuv(red,green,blue,&y,&u,&v);
            edginess = edginess + absdiff16(prevy,y);
            if (r > 180 && r < 540 && c > 180 && c < 540)
                edginess_window = edginess_window + absdiff16(prevy,y);
            if (r>= (5 - 1) && c > 1 && c < 724 -2)
            {
             r2 = r-(5 - 1); c2 = c-2;
                Ic[r2][c2][0] = red; Ic[r2][c2][1] = green; Ic[r2][c2][2] = blue;
                Iyuv[r2][c2][0] = y; Iyuv[r2][c2][1] = u; Iyuv[r2][c2][2] = v;
            }
        }
    }
    awb(rsum,gsum,bsum,&awb_R,&awb_G,&awb_B);
    printf("awb output: R=%d, G=%d, B=%d\n",awb_R,awb_G,awb_B);
    choosematrix(ccm,awb_R,awb_B);
    autoexposure(rsum,gsum,bsum,&Gain,&Texp);
    printf("ae output: Texp=%d Gain=%d\n",Texp,Gain);
    focus=autofocus(focus, edginess_window, &prev_edginess, &focus_direction, focus_stepsize);
    printf("af output: E=%d EW=%d and focus setting %d\n",edginess,edginess_window,focus);
    switch (output) {
        case YUV444:
            printf("Output in YUV 444 format\n");
            writeppm("outputyuv.ppm",Iyuv);
            break;
        case YCbCr422:
            printf("Output in YCbCr 422 format\n");
            Iycc = ui16colorim(0,480 -1,0,720 -1);
            rgb2ycbcr422(Ic,Iycc);
            writeppm("outputycbcr422.ppm",Iycc);
            free_ui16colorim(Iycc,0,480 -1,0,720 -1);
            break;
        case RGB565:
            printf("Output in RGB 565 format\n");
            Irgb565 = ui16matrix(0,480 -1,0,720 -1);
            rgb2rgb565(Ic,Irgb565);
            inputpgm->matrix = Irgb565;
            outputpgm = inputpgm;
            writePGM("outputrgb565.ppm",outputpgm);
            free_ui16matrix(Irgb565,0,480 -1,0,720 -1);
            break;
        case ITUBT656:
            printf("Output in ITU BT 565 format\n");
            Ibtu = ui16colorim(0,480 -1,0,720 -1);
            rgb2ycbcr422(Ic,Ibtu);
            writebtu656("outputbtu",Ibtu,field);
            free_ui16colorim(Ibtu,0,480 -1,0,720 -1);
            if (field == 0)
                field = 1;
            else
                field = 0;
            break;
        case RGB444:
        default:
            printf("Output in RGB 444 format\n");
            writeppm("output.ppm",Ic);
    }
    free_ui16vector(row_prf,0,484 -1);
    free_ui16vector(col_prf,0,724 -1);
    free_ui16colorim(Iyuv,0,480 -1,0,720 -1);
    free_ui16colorim(Ic,0,480 -1,0,720 -1);
    free_ui16matrix(I,0,480 -1,0,720 -1);
    free(inputpgm);
    return 0;
}

canonical_original_code:
int main()
{
    unsigned short **I; unsigned short **Irgb565; unsigned short ***Ic; unsigned short ***Iyuv; unsigned short ***Iycc; unsigned short ***Ibtu;
    struct _PGMData *inputpgm; struct _PGMData *outputpgm;
    unsigned short noise_threshold;
    unsigned int rsum; unsigned int gsum; unsigned int bsum;
    unsigned short awb_R; unsigned short awb_G; unsigned short awb_B;
    unsigned short Gain; unsigned short Texp;
    unsigned short *row_prf; unsigned short *col_prf;
    unsigned short r; unsigned short c;
    unsigned short r2; unsigned short c2;
    unsigned short pixel;
    unsigned short red; unsigned short green; unsigned short blue;
    unsigned short y; unsigned short u; unsigned short v; unsigned short prevy;
    short ccm[3][3];
    unsigned int edginess;
    unsigned int edginess_window;
    unsigned int prev_edginess;
    unsigned int focus;
    unsigned short focus_stepsize;
    short focus_direction;
    unsigned short field = 0;
    enum _InputFormat input = PIXELARRAY;
    enum _OutputFormat output = RGB444;
    Iyuv = ui16colorim(0,480 -1,0,720 -1);
    Ic = ui16colorim(0,480 -1,0,720 -1);
    printf("Image pipeline version %f\n",0.5);
    print_config();
    inputpgm = (struct _PGMData *)malloc(sizeof(PGMData));
    if (input != TESTPATTERN)
    {
        readPGM("inputGRBG10bitg2p2.pgm",inputpgm);
        I = inputpgm->matrix;
    }
 unsigned short row1[724]; unsigned short row2[724]; unsigned short row3[724]; unsigned short row4[724]; unsigned short row5[5];
 unsigned short *buffer[5] = {row1,row2,row3,row4,row5};
    row_prf = ui16vector(0,inputpgm->height-1);
    col_prf = ui16vector(0,inputpgm->width-1);
    construct_lens_profile(0, row_prf, col_prf);
    awb_R = 1<<5; awb_G = 1<<5; awb_B = 1<<5;
    choosematrix(ccm,awb_R,awb_B);
    Texp = 8;
    Gain = 1;
    focus_direction = 1;
 focus = 16;
 focus_stepsize = 1;
    rsum = gsum = bsum = 0;
    noise_threshold = 33 - Gain + (Texp>>2);
    if (noise_threshold < 16)
        noise_threshold = 16;
    for (r=0; r<5 -1;r++)
        for (c=0; c<724; c++)
            buffer[r][c] = 0;
  for (c=0; c<5; c++)
            buffer[4][c] = 0;
    edginess = 0;
    edginess_window = 0;
    for (r=0; r<484; r++)
    {
        for (c=0; c<724; c++)
        {
            if (input == TESTPATTERN)
                pixel = test_pattern_generator();
            else
                pixel = I[r][c];
            pixel = black_level_subtract(pixel,1);
            pixel = lens_shading_correction(pixel, row_prf[r], col_prf[c]);
            pixel = awb_sums_and_cga(pixel, r, c, awb_R, awb_G, awb_B, &rsum, &gsum, &bsum);
            update_buffer(pixel, buffer);
            if (r >= (5 - 1))
            {
                colorinterpolate_noisereduce(buffer,r-(5 - 1),c,noise_threshold,&red,&green,&blue);
            } else {
                red = green = blue = pixel;
            }
            colorcorrect(ccm,&red,&green,&blue);
            red = gammacorrect_LUT(red);
   green = gammacorrect_LUT(green);
            blue = gammacorrect_LUT(blue);
            prevy = y;
            rgb2yuv(red,green,blue,&y,&u,&v);
            edginess = edginess + absdiff16(prevy,y);
            if (r > 180 && r < 540 && c > 180 && c < 540)
                edginess_window = edginess_window + absdiff16(prevy,y);
            if (r>= (5 - 1) && c > 1 && c < 724 -2)
            {
             r2 = r-(5 - 1); c2 = c-2;
                Ic[r2][c2][0] = red; Ic[r2][c2][1] = green; Ic[r2][c2][2] = blue;
                Iyuv[r2][c2][0] = y; Iyuv[r2][c2][1] = u; Iyuv[r2][c2][2] = v;
            }
        }
    }
    awb(rsum,gsum,bsum,&awb_R,&awb_G,&awb_B);
    printf("awb output: R=%d, G=%d, B=%d\n",awb_R,awb_G,awb_B);
    choosematrix(ccm,awb_R,awb_B);
    autoexposure(rsum,gsum,bsum,&Gain,&Texp);
    printf("ae output: Texp=%d Gain=%d\n",Texp,Gain);
    focus=autofocus(focus, edginess_window, &prev_edginess, &focus_direction, focus_stepsize);
    printf("af output: E=%d EW=%d and focus setting %d\n",edginess,edginess_window,focus);
    switch (output) {
        case YUV444:
            printf("Output in YUV 444 format\n");
            writeppm("outputyuv.ppm",Iyuv);
            break;
        case YCbCr422:
            printf("Output in YCbCr 422 format\n");
            Iycc = ui16colorim(0,480 -1,0,720 -1);
            rgb2ycbcr422(Ic,Iycc);
            writeppm("outputycbcr422.ppm",Iycc);
            free_ui16colorim(Iycc,0,480 -1,0,720 -1);
            break;
        case RGB565:
            printf("Output in RGB 565 format\n");
            Irgb565 = ui16matrix(0,480 -1,0,720 -1);
            rgb2rgb565(Ic,Irgb565);
            inputpgm->matrix = Irgb565;
            outputpgm = inputpgm;
            writePGM("outputrgb565.ppm",outputpgm);
            free_ui16matrix(Irgb565,0,480 -1,0,720 -1);
            break;
        case ITUBT656:
            printf("Output in ITU BT 565 format\n");
            Ibtu = ui16colorim(0,480 -1,0,720 -1);
            rgb2ycbcr422(Ic,Ibtu);
            writebtu656("outputbtu",Ibtu,field);
            free_ui16colorim(Ibtu,0,480 -1,0,720 -1);
            if (field == 0)
                field = 1;
            else
                field = 0;
            break;
        case RGB444:
        default:
            printf("Output in RGB 444 format\n");
            writeppm("output.ppm",Ic);
    }
    free_ui16vector(row_prf,0,484 -1);
    free_ui16vector(col_prf,0,724 -1);
    free_ui16colorim(Iyuv,0,480 -1,0,720 -1);
    free_ui16colorim(Ic,0,480 -1,0,720 -1);
    free_ui16matrix(I,0,480 -1,0,720 -1);
    free(inputpgm);
    return 0;
}

variable_types:
I
unsigned short **

variable_types:
Ic
unsigned short ***

variable_types:
Iyuv
unsigned short ***

variable_types:
Iycc
unsigned short ***

variable_types:
Ibtu
unsigned short ***

variable_types: struct _PGMData { unsigned short height; unsigned short width; unsigned short max_gray; unsigned short **matrix; } *

variable_types:
rsum
unsigned int

variable_types:
gsum
unsigned int

variable_types:
bsum
unsigned int

variable_types:
Gain
unsigned short

variable_types:
Texp
unsigned short

variable_types:
r
unsigned short

variable_types:
c
unsigned short

variable_types:
pixel
unsigned short

variable_types:
red
unsigned short

variable_types:
green
unsigned short

variable_types:
blue
unsigned short

variable_types:
y
unsigned short

variable_types:
u
unsigned short

variable_types:
v
unsigned short

variable_types:
prevy
unsigned short

variable_types:
ccm
short [3][3]

variable_types:
edginess
unsigned int

variable_types:
focus
unsigned int

variable_types:
field
unsigned short

variable_types: enum _InputFormat { TESTPATTERN=0, PIXELARRAY=1 }

variable_types: enum _OutputFormat { YUV444=0, YCbCr422=1, RGB565=2, RGB444=3, ITUBT656=4 }

variable_types:
buffer
unsigned short *[5]


choosematrix

decompiled_code:
int __fastcall choosematrix(__int64 a1, unsigned __int16 a2, unsigned __int16 a3)
{
unsigned int v3; // er12
__int16 v4; // bx
unsigned __int16 v5; // bx
int v6; // er13
int v7; // eax
__int16 v8; // r13
int v9; // er15
int v10; // er15
__int16 v11; // r12
__int64 v12; // rsi
__int16 v13; // bx

v3 = a3;
v4 = absdiff16(32LL, a3);
v5 = absdiff16(32LL, a2) + v4;
if ( (v5 & 0x8000u) != 0 )
v5 = 0x8000;
v6 = absdiff16(40LL, v3);
v7 = v6 + absdiff16(24LL, a2);
v8 = 0;
if ( v5 > (unsigned __int16)v7 )
{
v5 = v7;
v8 = 1;
}
v9 = absdiff16(24LL, v3);
v10 = absdiff16(40LL, a2) + v9;
if ( v5 > (unsigned __int16)v10 )
{
v13 = absdiff16(28LL, v3);
if ( (unsigned __int16)v10 <= (unsigned __int16)(absdiff16(36LL, a2) + v13) )
{
*(_QWORD *)a1 = 32LL;
v12 = 2LL;
*(_QWORD *)(a1 + 8) = 32LL;
*(_WORD *)(a1 + 16) = 32;
return printf("Illuminant #%d chosen\n", v12);
}
goto LABEL_10;
}
v11 = absdiff16(28LL, v3);
if ( v5 > (unsigned __int16)(absdiff16(36LL, a2) + v11) )
{
LABEL_10:
*(_QWORD *)a1 = 32LL;
v12 = 3LL;
*(_QWORD *)(a1 + 8) = 32LL;
*(_WORD *)(a1 + 16) = 32;
return printf("Illuminant #%d chosen\n", v12);
}
*(_QWORD *)a1 = 32LL;
v12 = 0LL;
*(_QWORD *)(a1 + 8) = 32LL;
*(_WORD *)(a1 + 16) = 32;
if ( v8 == 1 )
v12 = 1LL;
return printf("Illuminant #%d chosen\n", v12);
}

canonical_original_code:
void choosematrix(short ccm[3][3], unsigned short awb_R, unsigned short awb_B)
{
    unsigned short dist; unsigned short min_dist; unsigned short illum_ndx;
    min_dist = 1<<15;
    dist = absdiff16(32,awb_B) +
               absdiff16(32,awb_R);
    if (dist < min_dist) {
        illum_ndx = 0;
  min_dist = dist;
 }
 dist = absdiff16(40,awb_B) +
               absdiff16(24,awb_R);
 if (dist < min_dist) {
  illum_ndx = 1;
  min_dist = dist;
 }
 dist = absdiff16(24,awb_B) +
               absdiff16(40,awb_R);
 if (dist < min_dist) {
  illum_ndx = 2;
  min_dist = dist;
 }
 dist = absdiff16(28,awb_B) +
               absdiff16(36,awb_R);
 if (dist < min_dist) {
  illum_ndx = 3;
  min_dist = dist;
 }
 switch (illum_ndx) {
  case 0:
        ccm[0][0] = 32; ccm[0][1] = 0; ccm[0][2] = 0;
        ccm[1][0] = 0; ccm[1][1] = 32; ccm[1][2] = 0;
        ccm[2][0] = 0; ccm[2][1] = 0; ccm[2][2] = 32;
  break;
  case 1:
     ccm[0][0] = 32; ccm[0][1] = 0; ccm[0][2] = 0;
        ccm[1][0] = 0; ccm[1][1] = 32; ccm[1][2] = 0;
        ccm[2][0] = 0; ccm[2][1] = 0; ccm[2][2] = 32;
  break;
  case 2:
     ccm[0][0] = 32; ccm[0][1] = 0; ccm[0][2] = 0;
        ccm[1][0] = 0; ccm[1][1] = 32; ccm[1][2] = 0;
        ccm[2][0] = 0; ccm[2][1] = 0; ccm[2][2] = 32;
  break;
  case 3:
  ccm[0][0] = 32; ccm[0][1] = 0; ccm[0][2] = 0;
        ccm[1][0] = 0; ccm[1][1] = 32; ccm[1][2] = 0;
        ccm[2][0] = 0; ccm[2][1] = 0; ccm[2][2] = 32;
  break;
    }
   printf("Illuminant #%d chosen\n",illum_ndx);
}

variable_types:
dist
unsigned short


colorcorrect

original_code:
void colorcorrect(int16_t ccm[3][3], uint16_t *red, uint16_t *green, uint16_t *blue)
{
    uint16_t localred,localgreen,localblue;
    int32_t sum;
    uint32_t temp;
 localred = *red; localgreen = *green; localblue = *blue;
 sum = ccm[0][0]*localred + ccm[0][1]*localgreen + ccm[0][2]*localblue;
 if (sum<0)
  sum = 0;
    temp = sum >> 5;
    if (temp > ((1<<10)-1))
        temp = ((1<<10)-1);
 *red = temp;
 sum = ccm[1][0]*localred + ccm[1][1]*localgreen + ccm[1][2]*localblue;
 if (sum<0)
  sum = 0;
    temp = sum >> 5;
    if (temp > ((1<<10)-1))
        temp = ((1<<10)-1);
 *green = temp;
 sum = ccm[2][0]*localred + ccm[2][1]*localgreen + ccm[2][2]*localblue;
 if (sum<0)
  sum = 0;
    temp = sum >> 5;
    if (temp > ((1<<10)-1))
        temp = ((1<<10)-1);
 *blue = temp;
}

canonical_original_code:
void colorcorrect(short ccm[3][3], unsigned short *red, unsigned short *green, unsigned short *blue)
{
    unsigned short localred; unsigned short localgreen; unsigned short localblue;
    int sum;
    unsigned int temp;
 localred = *red; localgreen = *green; localblue = *blue;
 sum = ccm[0][0]*localred + ccm[0][1]*localgreen + ccm[0][2]*localblue;
 if (sum<0)
  sum = 0;
    temp = sum >> 5;
    if (temp > ((1<<10)-1))
        temp = ((1<<10)-1);
 *red = temp;
 sum = ccm[1][0]*localred + ccm[1][1]*localgreen + ccm[1][2]*localblue;
 if (sum<0)
  sum = 0;
    temp = sum >> 5;
    if (temp > ((1<<10)-1))
        temp = ((1<<10)-1);
 *green = temp;
 sum = ccm[2][0]*localred + ccm[2][1]*localgreen + ccm[2][2]*localblue;
 if (sum<0)
  sum = 0;
    temp = sum >> 5;
    if (temp > ((1<<10)-1))
        temp = ((1<<10)-1);
 *blue = temp;
}

variable_types:
red
unsigned short *

variable_types:
green
unsigned short *

variable_types:
blue
unsigned short *

variable_types:
localred
unsigned short

variable_types:
localgreen
unsigned short

variable_types:
localblue
unsigned short

variable_types: sum int

variable_types:
temp
unsigned int


iperror

decompiled_code:
void __fastcall __noreturn iperror(const char *a1)
{
fwrite("Ipipe run-time error...\n", 1uLL, 0x18uLL, stderr);
fprintf(stderr, "%s\n", a1);
fwrite("...now exiting to system...\n", 1uLL, 0x1CuLL, stderr);
exit(1);
}

canonical_decompiled_code:
void __fastcall __noreturn func0(const char *a1)
{
fwrite("Ipipe run-time error...\n", 1uLL, 0x18uLL, stderr);
fprintf(stderr, "%s\n", a1);
fwrite("...now exiting to system...\n", 1uLL, 0x1CuLL, stderr);
exit(1);
}

original_code:
void iperror(char error_text[])
{
 fprintf(stderr,"Ipipe run-time error...\n");
 fprintf(stderr,"%s\n",error_text);
 fprintf(stderr,"...now exiting to system...\n");
 exit(1);
}


decompiled_code:
char *__fastcall ui16vector(__int64 a1, __int64 a2)
{
char *v2; // rax

v2 = (char *)malloc(2 * (a2 - a1) + 4);
if ( !v2 )
iperror("allocation failure in ui16vector()");
return &v2[2 * (1 - a1)];
}

canonical_decompiled_code:
char *__fastcall func1(__int64 a1, __int64 a2)
{
char *v2; // rax

v2 = (char *)malloc(2 * (a2 - a1) + 4);
if ( !v2 )
func0("allocation failure in ui16vector()");
return &v2[2 * (1 - a1)];
}

original_code:
unsigned short *ui16vector(long nl, long nh)
{
 unsigned short *v;
 v=(unsigned short *)malloc((size_t) ((nh-nl+1+1)*sizeof(unsigned short)));
 if (!v) iperror("allocation failure in ui16vector()");
 return v-nl+1;
}

canonical_original_code:
unsigned short *ui16vector(long nl, long nh)
{
 unsigned short *v;
 v=(unsigned short *)malloc((unsigned long) ((nh-nl+1+1)*sizeof(unsigned short)));
 if (!v) iperror("allocation failure in ui16vector()");
 return v-nl+1;
}

variable_types: nl long

variable_types: nh long

variable_types:
v
unsigned short *

return_type: unsigned short *


original_code:
unsigned short **ui16matrix(long nrl, long nrh, long ncl, long nch)
{
 long i, nrow=nrh-nrl+1,ncol=nch-ncl+1;
 unsigned short **m;
 m=(unsigned short **) malloc((size_t)((nrow+1)*sizeof(unsigned short *)));
 if (!m) iperror("allocation failure 1 in matrix()");
 m += 1;
 m -= nrl;
 m[nrl]=(unsigned short *) malloc((size_t)((nrow*ncol+1)*sizeof(unsigned short)));
 if (!m[nrl]) iperror("allocation failure 2 in matrix()");
 m[nrl] += 1;
 m[nrl] -= ncl;
 for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol;
 return m;
}

canonical_original_code:
unsigned short **ui16matrix(long nrl, long nrh, long ncl, long nch)
{
 long i; long nrow = nrh-nrl+1; long ncol = nch-ncl+1;
 unsigned short **m;
 m=(unsigned short **) malloc((unsigned long)((nrow+1)*sizeof(unsigned short *)));
 if (!m) iperror("allocation failure 1 in matrix()");
 m += 1;
 m -= nrl;
 m[nrl]=(unsigned short *) malloc((unsigned long)((nrow*ncol+1)*sizeof(unsigned short)));
 if (!m[nrl]) iperror("allocation failure 2 in matrix()");
 m[nrl] += 1;
 m[nrl] -= ncl;
 for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol;
 return m;
}

variable_types: nrl long

variable_types: nrh long

variable_types: ncl long

variable_types: nch long

variable_types: i long

variable_types: nrow long

variable_types: ncol long

variable_types:
m
unsigned short **

return_type: unsigned short **


original_code:
unsigned short ***ui16colorim(long nrl, long nrh, long ncl, long nch)
{
 long i,j,nrow=nrh-nrl+1,ncol=nch-ncl+1,ndep=3;
 unsigned short ***t;
 t=(unsigned short ***) malloc((size_t)((nrow+1)*sizeof(unsigned short**)));
 if (!t) iperror("allocation failure 1 in ui16colorim()");
 t += 1;
 t -= nrl;
 t[nrl]=(unsigned short **) malloc((size_t)((nrow*ncol+1)*sizeof(unsigned short*)));
 if (!t[nrl]) iperror("allocation failure 2 in ui16colorim()");
 t[nrl] += 1;
 t[nrl] -= ncl;
 t[nrl][ncl]=(unsigned short *) malloc((size_t)((nrow*ncol*ndep+1)*sizeof(unsigned short)));
 if (!t[nrl][ncl]) iperror("allocation failure 3 in ui16colorim()");
 t[nrl][ncl] += 1;
 t[nrl][ncl] -= 0;
 for(j=ncl+1;j<=nch;j++) t[nrl][j]=t[nrl][j-1]+ndep;
 for(i=nrl+1;i<=nrh;i++) {
  t[i]=t[i-1]+ncol;
  t[i][ncl]=t[i-1][ncl]+ncol*ndep;
  for(j=ncl+1;j<=nch;j++) t[i][j]=t[i][j-1]+ndep;
 }
 return t;
}

canonical_original_code:
unsigned short ***ui16colorim(long nrl, long nrh, long ncl, long nch)
{
 long i; long j; long nrow = nrh-nrl+1; long ncol = nch-ncl+1; long ndep = 3;
 unsigned short ***t;
 t=(unsigned short ***) malloc((unsigned long)((nrow+1)*sizeof(unsigned short **)));
 if (!t) iperror("allocation failure 1 in ui16colorim()");
 t += 1;
 t -= nrl;
 t[nrl]=(unsigned short **) malloc((unsigned long)((nrow*ncol+1)*sizeof(unsigned short *)));
 if (!t[nrl]) iperror("allocation failure 2 in ui16colorim()");
 t[nrl] += 1;
 t[nrl] -= ncl;
 t[nrl][ncl]=(unsigned short *) malloc((unsigned long)((nrow*ncol*ndep+1)*sizeof(unsigned short)));
 if (!t[nrl][ncl]) iperror("allocation failure 3 in ui16colorim()");
 t[nrl][ncl] += 1;
 t[nrl][ncl] -= 0;
 for(j=ncl+1;j<=nch;j++) t[nrl][j]=t[nrl][j-1]+ndep;
 for(i=nrl+1;i<=nrh;i++) {
  t[i]=t[i-1]+ncol;
  t[i][ncl]=t[i-1][ncl]+ncol*ndep;
  for(j=ncl+1;j<=nch;j++) t[i][j]=t[i][j-1]+ndep;
 }
 return t;
}

variable_types: j long

variable_types: ndep long

variable_types:
t
unsigned short ***

return_type: unsigned short ***


decompiled_code:
void __fastcall free_ui16vector(__int64 a1, __int64 a2)
{
free((void *)(a1 + 2 * a2 - 2));
}

canonical_decompiled_code:
void __fastcall func4(__int64 a1, __int64 a2)
{
free((void *)(a1 + 2 * a2 - 2));
}

original_code:
void free_ui16vector(unsigned short *v, long nl, long nh)
{
 free((char*) (v+nl-1));
}

canonical_original_code:
void free_ui16vector(unsigned short *v, long nl, long nh)
{
 free((char *) (v+nl-1));
}


original_code:
void free_ui16matrix(unsigned short **m, long nrl, long nrh, long ncl, long nch)
{
 free((char*) (m[nrl]+ncl-1));
 free((char*) (m+nrl-1));
}

canonical_original_code:
void free_ui16matrix(unsigned short **m, long nrl, long nrh, long ncl, long nch)
{
 free((char *) (m[nrl]+ncl-1));
 free((char *) (m+nrl-1));
}


original_code:
void free_ui16colorim(unsigned short ***t, long nrl, long nrh, long ncl, long nch)
{
 free((char*) (t[nrl][ncl]+0-1));
 free((char*) (t[nrl]+ncl-1));
 free((char*) (t+nrl-1));
}

canonical_original_code:
void free_ui16colorim(unsigned short ***t, long nrl, long nrh, long ncl, long nch)
{
 free((char *) (t[nrl][ncl]+0-1));
 free((char *) (t[nrl]+ncl-1));
 free((char *) (t+nrl-1));
}


autoexposure

decompiled_code:
__int64 __fastcall autoexposure(int a1, int a2, int a3, __int16 *a4, __int16 *a5)
{
unsigned int v7; // ebx
__int16 v8; // ax
unsigned __int16 v9; // r13
unsigned __int16 v10; // si
unsigned __int16 v11; // si
__int16 v12; // dx
__int64 result; // rax
unsigned int v14; // er14

v7 = (unsigned int)(a3 + a2 + a1) >> 18;
printf("image mean = %d targe = %d band=%d\n", v7, 683LL, 42LL);
v8 = *a5;
v9 = *a4;
v10 = *a4 * *a5;
if ( v7 > 0x2D5 )
{
v14 = 683 * (unsigned int)v10 / v7;
printf("current=%d new exposure=%d\n", v10, v14);
v8 = (unsigned __int16)v14 / v9;
if ( (unsigned __int16)((unsigned __int16)v14 / v9) <= 1u )
{
v8 = 2;
v9 = (unsigned __int16)v14 >> 1;
}
}
else if ( v7 <= 0x280 )
{
v11 = 683 * (unsigned int)v10 / v7;
v8 = v11 / v9;
if ( (unsigned __int16)(v11 / v9) > 0x64u )
{
v8 = 100;
v9 = v11 / 0x64u;
}
}
v12 = 1;
*a5 = v8;
if ( v9 )
v12 = v9;
result = 16LL;
if ( (unsigned __int16)v12 > 0x10u )
v12 = 16;
*a4 = v12;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(int a1, int a2, int a3, __int16 *a4, __int16 *a5)
{
unsigned int v7; // ebx
__int16 v8; // ax
unsigned __int16 v9; // r13
unsigned __int16 v10; // si
unsigned __int16 v11; // si
__int16 v12; // dx
__int64 result; // rax
unsigned int v14; // er14

v7 = (unsigned int)(a3 + a2 + a1) >> 18;
printf("image mean = %d targe = %d band=%d\n", v7, 683LL, 42LL);
v8 = *a5;
v9 = *a4;
v10 = *a4 * *a5;
if ( v7 > 0x2D5 )
{
v14 = 683 * (unsigned int)v10 / v7;
printf("current=%d new exposure=%d\n", v10, v14);
v8 = (unsigned __int16)v14 / v9;
if ( (unsigned __int16)((unsigned __int16)v14 / v9) <= 1u )
{
v8 = 2;
v9 = (unsigned __int16)v14 >> 1;
}
}
else if ( v7 <= 0x280 )
{
v11 = 683 * (unsigned int)v10 / v7;
v8 = v11 / v9;
if ( (unsigned __int16)(v11 / v9) > 0x64u )
{
v8 = 100;
v9 = v11 / 0x64u;
}
}
v12 = 1;
*a5 = v8;
if ( v9 )
v12 = v9;
result = 16LL;
if ( (unsigned __int16)v12 > 0x10u )
v12 = 16;
*a4 = v12;
return result;
}

original_code:
void autoexposure(uint32_t rsum, uint32_t gsum, uint32_t bsum, uint16_t *Gain, uint16_t *Texp)
{
    uint32_t image_mean;
    uint16_t current_exposure;
    uint16_t new_exposure;
    uint16_t Te,G;
    uint32_t band;
    image_mean = (rsum+gsum+bsum) >> 18;
    band = (((((1<<10)-1)>>1)*724*484)>>18) >> 4;
    printf("image mean = %d targe = %d band=%d\n",image_mean,(((((1<<10)-1)>>1)*724*484)>>18),band);
    Te = *Texp; G = *Gain;
    current_exposure = Te * G;
    if (image_mean > ((((((1<<10)-1)>>1)*724*484)>>18) + band))
    {
        new_exposure = ((((((1<<10)-1)>>1)*724*484)>>18)*current_exposure)/image_mean;
        printf("current=%d new exposure=%d\n",current_exposure,new_exposure);
        Te = new_exposure/G;
        if (Te < 2)
        {
   Te = 2;
            G = new_exposure/Te;
        }
    } else {
             if (image_mean < (uint32_t)((((((1<<10)-1)>>1)*724*484)>>18) - band))
             {
                new_exposure = ((((((1<<10)-1)>>1)*724*484)>>18)*current_exposure)/image_mean;
                Te = new_exposure/G;
                if (Te > 100)
                {
       Te = 100;
                   G = new_exposure/Te;
                }
             }
    }
 if (G > 16)
  G = 16;
 if (G < 1)
  G = 1;
    *Texp = Te; *Gain = G;
}

canonical_original_code:
void autoexposure(unsigned int rsum, unsigned int gsum, unsigned int bsum, unsigned short *Gain, unsigned short *Texp)
{
    unsigned int image_mean;
    unsigned short current_exposure;
    unsigned short new_exposure;
    unsigned short Te; unsigned short G;
    unsigned int band;
    image_mean = (rsum+gsum+bsum) >> 18;
    band = (((((1<<10)-1)>>1)*724*484)>>18) >> 4;
    printf("image mean = %d targe = %d band=%d\n",image_mean,(((((1<<10)-1)>>1)*724*484)>>18),band);
    Te = *Texp; G = *Gain;
    current_exposure = Te * G;
    if (image_mean > ((((((1<<10)-1)>>1)*724*484)>>18) + band))
    {
        new_exposure = ((((((1<<10)-1)>>1)*724*484)>>18)*current_exposure)/image_mean;
        printf("current=%d new exposure=%d\n",current_exposure,new_exposure);
        Te = new_exposure/G;
        if (Te < 2)
        {
   Te = 2;
            G = new_exposure/Te;
        }
    } else {
             if (image_mean < (unsigned int)((((((1<<10)-1)>>1)*724*484)>>18) - band))
             {
                new_exposure = ((((((1<<10)-1)>>1)*724*484)>>18)*current_exposure)/image_mean;
                Te = new_exposure/G;
                if (Te > 100)
                {
       Te = 100;
                   G = new_exposure/Te;
                }
             }
    }
 if (G > 16)
  G = 16;
 if (G < 1)
  G = 1;
    *Texp = Te; *Gain = G;
}

variable_types:
rsum
unsigned int

variable_types:
gsum
unsigned int

variable_types:
bsum
unsigned int

variable_types:
Gain
unsigned short *

variable_types:
Texp
unsigned short *

variable_types:
Te
unsigned short

variable_types:
G
unsigned short

variable_types:
band
unsigned int


decompiled_code:
__int16 test_pattern_generator()
{
LSFR_0 = ((unsigned int)LSFR_0 >> 1) ^ -(LSFR_0 & 1) & 0xD0000001;
return LSFR_0 & 0x3FF;
}

canonical_decompiled_code:
__int16 func0()
{
LSFR_0 = ((unsigned int)LSFR_0 >> 1) ^ -(LSFR_0 & 1) & 0xD0000001;
return LSFR_0 & 0x3FF;
}

original_code:
uint16_t test_pattern_generator(void)
{
    uint16_t pixel;
    static unsigned int LSFR = 1u;
    LSFR = (LSFR >>1) ^ ((-(LSFR & 1u)) & 0xD0000001u);
    pixel = (LSFR & ((1<<10)-1));
    return pixel;
}

canonical_original_code:
unsigned short test_pattern_generator()
{
    unsigned short pixel;
    static unsigned int LSFR = 1u;
    LSFR = (LSFR >>1) ^ ((-(LSFR & 1u)) & 0xD0000001u);
    pixel = (LSFR & ((1<<10)-1));
    return pixel;
}

variable_types:
pixel
unsigned short

variable_types:
LSFR
unsigned int

return_type: unsigned short


panic

repo: sharow/libconcurrent

decompiled_code:
void __noreturn panic()
{
abort();
}

canonical_decompiled_code:
void __noreturn func1()
{
abort();
}

original_code:
_Noreturn static void
panic(void)
{
    abort();
}

canonical_original_code:
static void panic()
{
    abort();
}


main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
size_t v3; // rax
void *v4; // r12
void *v5; // rbp
float v6; // xmm0_4
__int64 v7; // rax
__int64 *v9; // [rsp+0h] [rbp-68h] BYREF
int v10; // [rsp+8h] [rbp-60h]
__int64 v11[11]; // [rsp+10h] [rbp-58h] BYREF

v11[0] = 0xD0000000CLL;
v11[1] = 0xF0000000ELL;
v11[2] = 0x90000000ALL;
v11[3] = 0x100000007LL;
v11[4] = 0xB00000002LL;
v11[5] = 0x400000003LL;
v11[6] = 0x600000008LL;
v9 = v11;
v11[7] = 5LL;
v10 = 16;
concurrent_init(argc, argv, envp);
v3 = concurrent_sizeof();
v4 = malloc(v3);
g_context = v4;
v5 = malloc(0x1000uLL);
concurrent_construct(v4, v5, 4096LL, coro, &v9);
while ( !(unsigned __int8)concurrent_is_done(g_context) )
{
v7 = concurrent_get_stack_used(g_context);
if ( v7 >= 0 )
v6 = (float)(int)v7;
else
v6 = (float)(v7 & 1 | (unsigned int)((unsigned __int64)v7 >> 1))
+ (float)(v7 & 1 | (unsigned int)((unsigned __int64)v7 >> 1));
printf("stack used:%3zdbytes(%2.0f%%); data={ ", v7, (float)((float)(v6 * 0.00024414062) * 100.0));
print_datas(&v9);
puts("}");
concurrent_resume(g_context);
}
concurrent_destruct(g_context);
free(v5);
free(g_context);
concurrent_fin();
return 0;
}

original_code:
int main(void)
{
    uint8_t *stack;
    const int stack_size = 1024 * 4;
    int data[] = { 12, 13, 14, 15, 10, 9, 7, 1, 2, 11, 3, 4, 8, 6, 5, 0 };
    struct sort_ctx sort_arg;
    sort_arg.data = data;
    sort_arg.num_data = sizeof(data) / sizeof(data[0]);
    concurrent_init();
    g_context = malloc(concurrent_sizeof());
    stack = malloc(sizeof(*stack) * stack_size);
    concurrent_construct(g_context, stack, stack_size, coro, (void *)&sort_arg);
    while (!concurrent_is_done(g_context)) {
        size_t stack_size_used = concurrent_get_stack_used(g_context);
        printf("stack used:%3zdbytes(%2.0f%%); data={ ",
               stack_size_used, ((float)stack_size_used / stack_size) * 100.0f);
        print_datas(&sort_arg);
        printf("}\n");
        concurrent_resume(g_context);
    }
    concurrent_destruct(g_context);
    free(stack);
    free(g_context);
    concurrent_fin();
    return 0;
}

canonical_original_code:
int main()
{
    unsigned char *stack;
    int stack_size = 1024 * 4;
    int data[] = { 12, 13, 14, 15, 10, 9, 7, 1, 2, 11, 3, 4, 8, 6, 5, 0 };
    struct sort_ctx sort_arg;
    sort_arg.data = data;
    sort_arg.num_data = sizeof(data) / sizeof(data[0]);
    concurrent_init();
    g_context = malloc(concurrent_sizeof());
    stack = malloc(sizeof(*stack) * stack_size);
    concurrent_construct(g_context, stack, stack_size, coro, (void *)&sort_arg);
    while (!concurrent_is_done(g_context)) {
        unsigned long stack_size_used = concurrent_get_stack_used(g_context);
        printf("stack used:%3zdbytes(%2.0f%%); data={ ",
               stack_size_used, ((float)stack_size_used / stack_size) * 100.0f);
        print_datas(&sort_arg);
        printf("}\n");
        concurrent_resume(g_context);
    }
    concurrent_destruct(g_context);
    free(stack);
    free(g_context);
    concurrent_fin();
    return 0;
}

variable_types:
stack
unsigned char *

variable_types:
data
int []

variable_types: struct sort_ctx { int *data; int num_data; }


comp

decompiled_code:
__int64 __fastcall comp(const void *a1, const void *a2)
{
int v2; // ebp
int v3; // ebx

v2 = *(_DWORD *)a1;
v3 = *(_DWORD *)a2;
concurrent_yield(g_context);
if ( v2 > v3 )
return 1LL;
if ( v2 < v3 )
return 0xFFFFFFFFLL;
if ( v2 != v3 )
__assert_fail("!\"not reached\"", "concurrent_sort1.c", 0x26u, "comp");
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func12(const void *a1, const void *a2)
{
int v2; // ebp
int v3; // ebx

v2 = *(_DWORD *)a1;
v3 = *(_DWORD *)a2;
func25(g_context);
if ( v2 > v3 )
return 1LL;
if ( v2 < v3 )
return 0xFFFFFFFFLL;
if ( v2 != v3 )
__assert_fail("!\"not reached\"", "concurrent_sort1.c", 0x26u, "comp");
return 0LL;
}

original_code:
int comp(const void *value0, const void *value1)
{
    int a = *(const int *)value0;
    int b = *(const int *)value1;
    concurrent_yield(g_context);
    if (a > b) {
        return 1;
    } else if (a < b) {
        return -1;
    } else if (a == b) {
        return 0;
    }
    ((!"not reached") ? (void) (0) : __assert_fail ("!\"not reached\"", "concurrent_sort1.c", 38, __extension__ __PRETTY_FUNCTION__));
    return 0;
}

canonical_original_code:
int comp(void *value0, void *value1)
{
    int a = *(const int *)value0;
    int b = *(const int *)value1;
    concurrent_yield(g_context);
    if (a > b) {
        return 1;
    } else if (a < b) {
        return -1;
    } else if (a == b) {
        return 0;
    }
    ((!"not reached") ? (void) (0) : __assert_fail ("!\"not reached\"", "concurrent_sort1.c", 38, __extension__ __PRETTY_FUNCTION__));
    return 0;
}

variable_types: a int

variable_types: b int


decompiled_code:
int __fastcall print_datas(__int64 a1)
{
int result; // eax
__int64 v2; // rbx
__int64 v3; // rsi

result = *(_DWORD *)(a1 + 8);
if ( result > 0 )
{
v2 = 0LL;
do
{
v3 = *(unsigned int *)(*(_QWORD *)a1 + 4 * v2++);
result = printf("%d ", v3);
}
while ( *(_DWORD *)(a1 + 8) > (int)v2 );
}
return result;
}

canonical_decompiled_code:
int __fastcall func14(__int64 a1)
{
int result; // eax
__int64 v2; // rbx
__int64 v3; // rsi

result = *(_DWORD *)(a1 + 8);
if ( result > 0 )
{
v2 = 0LL;
do
{
v3 = *(unsigned int *)(*(_QWORD *)a1 + 4 * v2++);
result = printf("%d ", v3);
}
while ( *(_DWORD *)(a1 + 8) > (int)v2 );
}
return result;
}

original_code:
void print_datas(struct sort_ctx *sort_ctx)
{
    int i;
    for (i = 0; i < sort_ctx->num_data; i++) {
        printf("%d ", sort_ctx->data[i]);
    }
}

variable_types: struct sort_ctx { int *data; int num_data; } *

variable_types: i int


decompiled_code:
__int64 __fastcall concurrent_setup_execution_context(__int64 a1)
{
__int64 result; // rax
_QWORD v2[12]; // [rsp-60h] [rbp-60h] BYREF
void *retaddr; // [rsp+0h] [rbp+0h] BYREF

*(_QWORD *)(a1 + 40) = *(_QWORD *)(a1 + 32);
_InterlockedExchange64((volatile __int64 *)(a1 + concurrent_offsetof_stack_ptr), (__int64)&retaddr);
v2[11] = a1;
v2[10] = a1;
v2[9] = concurrent_arch_return_at_procedure;
v2[8] = *(_QWORD *)(a1 + concurrent_offsetof_procedure);
v2[7] = 0LL;
v2[6] = 0LL;
v2[5] = a1;
v2[4] = 0LL;
v2[3] = 0LL;
v2[2] = 0LL;
v2[1] = 0LL;
v2[0] = 0LL;
result = concurrent_offsetof_stack_ptr;
_InterlockedExchange64((volatile __int64 *)(a1 + concurrent_offsetof_stack_ptr), (__int64)v2);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func15(__int64 a1)
{
__int64 result; // rax
_QWORD v2[12]; // [rsp-60h] [rbp-60h] BYREF
void *retaddr; // [rsp+0h] [rbp+0h] BYREF

*(_QWORD *)(a1 + 40) = *(_QWORD *)(a1 + 32);
_InterlockedExchange64((volatile __int64 *)(a1 + concurrent_offsetof_stack_ptr), (__int64)&retaddr);
v2[11] = a1;
v2[10] = a1;
v2[9] = concurrent_arch_return_at_procedure;
v2[8] = *(_QWORD *)(a1 + concurrent_offsetof_procedure);
v2[7] = 0LL;
v2[6] = 0LL;
v2[5] = a1;
v2[4] = 0LL;
v2[3] = 0LL;
v2[2] = 0LL;
v2[1] = 0LL;
v2[0] = 0LL;
result = concurrent_offsetof_stack_ptr;
_InterlockedExchange64((volatile __int64 *)(a1 + concurrent_offsetof_stack_ptr), (__int64)v2);
return result;
}

original_code:
static void
concurrent_setup_execution_context(struct concurrent_ctx *ctx)
{
    ctx->stack_ptr = ctx->stack_base;
    concurrent_arch_setup_execution_context(ctx);
}

variable_types: struct concurrent_ctx { void (*proc)(struct concurrent_ctx *); void *user_ptr; void *stack_orig; unsigned long stack_size; unsigned long stack_base; unsigned long stack_ptr; enum concurrent_state { CONCURRENT_STATE_SETUP=0, CONCURRENT_STATE_EXECUTE=1, CONCURRENT_STATE_YIELD=2, CONCURRENT_STATE_DONE=3 } state; void *caller_return_addr; void *yield_value; void *resume_value; } *

user_defined_types: struct concurrent_ctx { void (*proc)(struct concurrent_ctx *); void *user_ptr; void *stack_orig; unsigned long stack_size; unsigned long stack_base; unsigned long stack_ptr; enum concurrent_state state; void *caller_return_addr; void *yield_value; void *resume_value; }


decompiled_code:
void concurrent_fin()
{
;
}

canonical_decompiled_code:
void func17()
{
;
}

original_code:
void
concurrent_fin(void)
{
}

canonical_original_code:
void concurrent_fin()
{
}


decompiled_code:
__int64 concurrent_sizeof()
{
return 80LL;
}

canonical_decompiled_code:
__int64 func18()
{
return 80LL;
}

original_code:
size_t
concurrent_sizeof(void)
{
    return sizeof(struct concurrent_ctx);
}

canonical_original_code:
unsigned long concurrent_sizeof()
{
    return sizeof(struct concurrent_ctx);
}

user_defined_types: enum concurrent_state { CONCURRENT_STATE_SETUP=0, CONCURRENT_STATE_EXECUTE=1, CONCURRENT_STATE_YIELD=2, CONCURRENT_STATE_DONE=3 }


decompiled_code:
__int64 __fastcall concurrent_construct(__int64 a1, unsigned __int64 a2, unsigned __int64 a3, __int64 a4, __int64 a5)
{
unsigned __int64 v5; // rax
unsigned __int64 v6; // rsi
unsigned __int64 v7; // rsi
__int64 result; // rax

if ( a4 == 0 || a2 == 0 || !a1 )
return 1LL;
if ( a3 <= 0x3FF )
return 2LL;
v5 = (a2 + 15) & 0xFFFFFFFFFFFFFFF0LL;
if ( a2 > v5 )
__assert_fail(
"(uintptr_t)aligned_stack_buffer >= (uintptr_t)stack_buffer",
"src/concurrent.c",
0x5Eu,
"concurrent_construct");
*(_QWORD *)(a1 + 16) = a2;
*(_QWORD *)a1 = a4;
v6 = (a3 + a2 - v5) & 0xFFFFFFFFFFFFFFF0LL;
*(_QWORD *)(a1 + 8) = a5;
*(_QWORD *)(a1 + 24) = v6;
v7 = v5 + v6;
result = 0LL;
*(_QWORD *)(a1 + 32) = v7;
*(_QWORD *)(a1 + 40) = 0LL;
*(_DWORD *)(a1 + 48) = 0;
*(_QWORD *)(a1 + 56) = 0LL;
*(_QWORD *)(a1 + 64) = 0LL;
*(_QWORD *)(a1 + 72) = 0LL;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func19(__int64 a1, unsigned __int64 a2, unsigned __int64 a3, __int64 a4, __int64 a5)
{
unsigned __int64 v5; // rax
unsigned __int64 v6; // rsi
unsigned __int64 v7; // rsi
__int64 result; // rax

if ( a4 == 0 || a2 == 0 || !a1 )
return 1LL;
if ( a3 <= 0x3FF )
return 2LL;
v5 = (a2 + 15) & 0xFFFFFFFFFFFFFFF0LL;
if ( a2 > v5 )
__assert_fail(
"(uintptr_t)aligned_stack_buffer >= (uintptr_t)stack_buffer",
"src/concurrent.c",
0x5Eu,
"concurrent_construct");
*(_QWORD *)(a1 + 16) = a2;
*(_QWORD *)a1 = a4;
v6 = (a3 + a2 - v5) & 0xFFFFFFFFFFFFFFF0LL;
*(_QWORD *)(a1 + 8) = a5;
*(_QWORD *)(a1 + 24) = v6;
v7 = v5 + v6;
result = 0LL;
*(_QWORD *)(a1 + 32) = v7;
*(_QWORD *)(a1 + 40) = 0LL;
*(_DWORD *)(a1 + 48) = 0;
*(_QWORD *)(a1 + 56) = 0LL;
*(_QWORD *)(a1 + 64) = 0LL;
*(_QWORD *)(a1 + 72) = 0LL;
return result;
}

original_code:
concurrent_status
concurrent_construct(struct concurrent_ctx *ctx,
                     void *stack_buffer,
                     size_t stack_size,
                     concurrent_proc proc,
                     void *user_ptr)
{
    const uintptr_t align = 16 - 1;
    uintptr_t aligned_stack_buffer;
    if (ctx && stack_buffer && proc) {
    } else {
        return CONCURRENT_E_INVALID_ARGUMENT;
    }
    if (stack_size < (1024)) {
        return CONCURRENT_E_STACKSIZE_TOO_SMALL;
    }
    aligned_stack_buffer = ((uintptr_t)stack_buffer + align) & ~align;
    (((uintptr_t)aligned_stack_buffer >= (uintptr_t)stack_buffer) ? (void) (0) : __assert_fail ("(uintptr_t)aligned_stack_buffer >= (uintptr_t)stack_buffer", "src/concurrent.c", 94, __extension__ __PRETTY_FUNCTION__));
    ctx->proc = proc;
    ctx->user_ptr = user_ptr;
    ctx->stack_orig = stack_buffer;
    ctx->stack_size = (stack_size - (size_t)(aligned_stack_buffer - (uintptr_t)stack_buffer)) & ~(size_t)align;
    ctx->stack_base = aligned_stack_buffer + ctx->stack_size;
    ctx->stack_ptr = 0;
    ctx->state = CONCURRENT_STATE_SETUP;
    ctx->caller_return_addr = ((void *)0);
    ctx->yield_value = ((void *)0);
    ctx->resume_value = ((void *)0);
    return CONCURRENT_SUCCESS;
}

canonical_original_code:
enum concurrent_status concurrent_construct(struct concurrent_ctx *ctx, void *stack_buffer, unsigned long stack_size, void (*proc)(struct concurrent_ctx *), void *user_ptr)
{
    unsigned long align = 16 - 1;
    unsigned long aligned_stack_buffer;
    if (ctx && stack_buffer && proc) {
    } else {
        return CONCURRENT_E_INVALID_ARGUMENT;
    }
    if (stack_size < (1024)) {
        return CONCURRENT_E_STACKSIZE_TOO_SMALL;
    }
    aligned_stack_buffer = ((unsigned long)stack_buffer + align) & ~align;
    (((unsigned long)aligned_stack_buffer >= (unsigned long)stack_buffer) ? (void) (0) : __assert_fail ("(uintptr_t)aligned_stack_buffer >= (uintptr_t)stack_buffer", "src/concurrent.c", 94, __extension__ __PRETTY_FUNCTION__));
    ctx->proc = proc;
    ctx->user_ptr = user_ptr;
    ctx->stack_orig = stack_buffer;
    ctx->stack_size = (stack_size - (unsigned long)(aligned_stack_buffer - (unsigned long)stack_buffer)) & ~(unsigned long)align;
    ctx->stack_base = aligned_stack_buffer + ctx->stack_size;
    ctx->stack_ptr = 0;
    ctx->state = CONCURRENT_STATE_SETUP;
    ctx->caller_return_addr = ((void *)0);
    ctx->yield_value = ((void *)0);
    ctx->resume_value = ((void *)0);
    return CONCURRENT_SUCCESS;
}

variable_types:
proc
void (*)(struct concurrent_ctx *)

variable_types:
align
unsigned long

return_type: enum concurrent_status { CONCURRENT_SUCCESS=0, CONCURRENT_E_INVALID_ARGUMENT=1, CONCURRENT_E_STACKSIZE_TOO_SMALL=2 }


original_code:
void
concurrent_destruct(struct concurrent_ctx *ctx)
{
    ctx->proc = ((void *)0);
    ctx->user_ptr = ((void *)0);
    ctx->stack_orig = ((void *)0);
    ctx->stack_size = 0;
    ctx->stack_base = 0;
    ctx->stack_ptr = 0;
    ctx->state = CONCURRENT_STATE_DONE;
    ctx->caller_return_addr = ((void *)0);
    ctx->yield_value = ((void *)0);
    ctx->resume_value = ((void *)0);
}


decompiled_code:
__int64 __fastcall concurrent_resume_with_value(__int64 a1, __int64 a2)
{
int v2; // eax

v2 = *(_DWORD *)(a1 + 48);
if ( v2 )
{
if ( v2 != 2 )
concurrent_resume_with_value_cold();
}
else
{
concurrent_setup_execution_context(a1);
}
*(_DWORD *)(a1 + 48) = 1;
*(_QWORD *)(a1 + 64) = 0LL;
*(_QWORD *)(a1 + 72) = a2;
concurrent_arch_trampoline_to_procedure(a1);
if ( *(_DWORD *)(a1 + 48) != 1 )
return *(_QWORD *)(a1 + 64);
*(_DWORD *)(a1 + 48) = 3;
return 0LL;
}

original_code:
void *
concurrent_resume_with_value(struct concurrent_ctx *ctx, void *value)
{
    switch (ctx->state) {
    case CONCURRENT_STATE_SETUP:
        concurrent_setup_execution_context(ctx);
    case CONCURRENT_STATE_YIELD:
        ctx->state = CONCURRENT_STATE_EXECUTE;
        ctx->yield_value = ((void *)0);
        ctx->resume_value = value;
        concurrent_arch_trampoline_to_procedure(ctx);
        if (ctx->state == CONCURRENT_STATE_EXECUTE) {
            ctx->state = CONCURRENT_STATE_DONE;
            return ((void *)0);
        } else {
            return ctx->yield_value;
        }
    case CONCURRENT_STATE_EXECUTE:
    case CONCURRENT_STATE_DONE:
    default:
        panic();
    }
    return ((void *)0);
}

canonical_original_code:
void *concurrent_resume_with_value(struct concurrent_ctx *ctx, void *value)
{
    switch (ctx->state) {
    case CONCURRENT_STATE_SETUP:
        concurrent_setup_execution_context(ctx);
    case CONCURRENT_STATE_YIELD:
        ctx->state = CONCURRENT_STATE_EXECUTE;
        ctx->yield_value = ((void *)0);
        ctx->resume_value = value;
        concurrent_arch_trampoline_to_procedure(ctx);
        if (ctx->state == CONCURRENT_STATE_EXECUTE) {
            ctx->state = CONCURRENT_STATE_DONE;
            return ((void *)0);
        } else {
            return ctx->yield_value;
        }
    case CONCURRENT_STATE_EXECUTE:
    case CONCURRENT_STATE_DONE:
    default:
        panic();
    }
    return ((void *)0);
}

variable_types:
value
void *


decompiled_code:
__int64 __fastcall concurrent_resume(__int64 a1)
{
return concurrent_resume_with_value(a1, 0LL);
}

canonical_decompiled_code:
__int64 __fastcall func22(__int64 a1)
{
return func21(a1, 0LL);
}

original_code:
void *
concurrent_resume(struct concurrent_ctx *ctx)
{
    return concurrent_resume_with_value(ctx, ((void *)0));
}

canonical_original_code:
void *concurrent_resume(struct concurrent_ctx *ctx)
{
    return concurrent_resume_with_value(ctx, ((void *)0));
}


decompiled_code:
__int64 __fastcall concurrent_get_resume_value(__int64 a1)
{
return *(_QWORD *)(a1 + 72);
}

canonical_decompiled_code:
__int64 __fastcall func23(__int64 a1)
{
return *(_QWORD *)(a1 + 72);
}

original_code:
void *
concurrent_get_resume_value(struct concurrent_ctx *ctx)
{
    return ctx->resume_value;
}

canonical_original_code:
void *concurrent_get_resume_value(struct concurrent_ctx *ctx)
{
    return ctx->resume_value;
}


decompiled_code:
__int64 __fastcall concurrent_yield_with_value(__int64 a1, __int64 a2)
{
if ( *(_DWORD *)(a1 + 48) != 1 )
concurrent_yield_with_value_cold();
*(_QWORD *)(a1 + 64) = a2;
*(_DWORD *)(a1 + 48) = 2;
concurrent_arch_trampoline_to_caller();
return *(_QWORD *)(a1 + 72);
}

original_code:
void *
concurrent_yield_with_value(struct concurrent_ctx *ctx, void *value)
{
    if (ctx->state != CONCURRENT_STATE_EXECUTE) {
        panic();
    }
    ctx->yield_value = value;
    ctx->state = CONCURRENT_STATE_YIELD;
    concurrent_arch_trampoline_to_caller(ctx);
    return ctx->resume_value;
}

canonical_original_code:
void *concurrent_yield_with_value(struct concurrent_ctx *ctx, void *value)
{
    if (ctx->state != CONCURRENT_STATE_EXECUTE) {
        panic();
    }
    ctx->yield_value = value;
    ctx->state = CONCURRENT_STATE_YIELD;
    concurrent_arch_trampoline_to_caller(ctx);
    return ctx->resume_value;
}


decompiled_code:
__int64 __fastcall concurrent_yield(__int64 a1)
{
return concurrent_yield_with_value(a1, 0LL);
}

canonical_decompiled_code:
__int64 __fastcall func25(__int64 a1)
{
return func24(a1, 0LL);
}

original_code:
void *
concurrent_yield(struct concurrent_ctx *ctx)
{
    return concurrent_yield_with_value(ctx, ((void *)0));
}

canonical_original_code:
void *concurrent_yield(struct concurrent_ctx *ctx)
{
    return concurrent_yield_with_value(ctx, ((void *)0));
}


decompiled_code:
__int64 __fastcall concurrent_get_yield_value(__int64 a1)
{
return *(_QWORD *)(a1 + 64);
}

canonical_decompiled_code:
__int64 __fastcall func26(__int64 a1)
{
return *(_QWORD *)(a1 + 64);
}

original_code:
void *
concurrent_get_yield_value(struct concurrent_ctx *ctx)
{
    return ctx->yield_value;
}

canonical_original_code:
void *concurrent_get_yield_value(struct concurrent_ctx *ctx)
{
    return ctx->yield_value;
}


decompiled_code:
void __fastcall concurrent_reset(__int64 a1)
{
if ( *(_DWORD *)(a1 + 48) == 1 )
concurrent_reset_cold();
*(_DWORD *)(a1 + 48) = 0;
}

original_code:
void
concurrent_reset(struct concurrent_ctx *ctx)
{
    if (ctx->state == CONCURRENT_STATE_EXECUTE) {
        panic();
    }
    ctx->state = CONCURRENT_STATE_SETUP;
}


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

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

original_code:
void *
concurrent_get_user_ptr(struct concurrent_ctx *ctx)
{
    return ctx->user_ptr;
}

canonical_original_code:
void *concurrent_get_user_ptr(struct concurrent_ctx *ctx)
{
    return ctx->user_ptr;
}


decompiled_code:
bool __fastcall concurrent_is_done(__int64 a1)
{
return *(_DWORD *)(a1 + 48) == 3;
}

canonical_decompiled_code:
bool __fastcall func29(__int64 a1)
{
return *(_DWORD *)(a1 + 48) == 3;
}

original_code:
_Bool
concurrent_is_done(struct concurrent_ctx *ctx)
{
    return (ctx->state == CONCURRENT_STATE_DONE) ? 1 : 0;
}


decompiled_code:
__int64 __fastcall concurrent_get_stack_used(__int64 a1)
{
int v1; // eax

v1 = *(_DWORD *)(a1 + 48);
if ( !v1 )
return 0LL;
if ( v1 == 1 )
concurrent_get_stack_used_cold();
return *(_QWORD *)(a1 + 32) - *(_QWORD *)(a1 + 40);
}

original_code:
size_t
concurrent_get_stack_used(struct concurrent_ctx *ctx)
{
    if (ctx->state == CONCURRENT_STATE_SETUP) {
        return 0;
    }
    if (ctx->state == CONCURRENT_STATE_EXECUTE) {
        panic();
    }
    return (size_t)(ctx->stack_base - ctx->stack_ptr);
}

canonical_original_code:
unsigned long concurrent_get_stack_used(struct concurrent_ctx *ctx)
{
    if (ctx->state == CONCURRENT_STATE_SETUP) {
        return 0;
    }
    if (ctx->state == CONCURRENT_STATE_EXECUTE) {
        panic();
    }
    return (unsigned long)(ctx->stack_base - ctx->stack_ptr);
}


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

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

original_code:
void *
concurrent_get_stack(struct concurrent_ctx *ctx)
{
    return ctx->stack_orig;
}

canonical_original_code:
void *concurrent_get_stack(struct concurrent_ctx *ctx)
{
    return ctx->stack_orig;
}


panic

decompiled_code:
void __noreturn panic()
{
abort();
}

original_code:
_Noreturn static void
panic(void)
{
    abort();
}


main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // er12
time_t v4; // rdi
int v5; // ebx
int v6; // ebp
size_t v7; // rax
size_t v8; // rdi
void *v9; // r13
char *v10; // r14
bool v11; // cf
bool v12; // zf
__int64 v13; // rax
const char *v14; // rdi
__int64 v15; // rcx
const char *v16; // rsi

v3 = 1000;
v4 = time(0LL);
srand(v4);
concurrent_init(v4, argv);
do
{
v5 = rand() % 16;
v6 = rand() % 16;
v7 = concurrent_sizeof();
v8 = v5 + 1040;
v9 = malloc(v7);
v10 = (char *)malloc(v8);
if ( (unsigned int)concurrent_construct(v9, &v10[v6], v8 - v6, test_generator, 0LL) )
__assert_fail("status == CONCURRENT_SUCCESS", "stack_torture1.c", 0x25u, "main");
v13 = concurrent_resume(v9);
v14 = "pong";
v15 = 5LL;
v16 = (const char *)v13;
do
{
if ( !v15 )
break;
v11 = *v16 < (unsigned int)*v14;
v12 = *v16++ == *v14++;
--v15;
}
while ( v12 );
if ( (!v11 && !v12) != v11 )
__assert_fail("strcmp(resume(ctx), \"pong\") == 0", "stack_torture1.c", 0x26u, "main");
concurrent_destruct(v9, v16);
free(v10);
free(v9);
--v3;
}
while ( v3 );
concurrent_fin();
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // er12
time_t v4; // rdi
int v5; // ebx
int v6; // ebp
size_t v7; // rax
size_t v8; // rdi
void *v9; // r13
char *v10; // r14
bool v11; // cf
bool v12; // zf
__int64 v13; // rax
const char *v14; // rdi
__int64 v15; // rcx
const char *v16; // rsi

v3 = 1000;
v4 = time(0LL);
srand(v4);
func14(v4, argv);
do
{
v5 = rand() % 16;
v6 = rand() % 16;
v7 = func16();
v8 = v5 + 1040;
v9 = malloc(v7);
v10 = (char *)malloc(v8);
if ( (unsigned int)func17(v9, &v10[v6], v8 - v6, test_generator, 0LL) )
__assert_fail("status == CONCURRENT_SUCCESS", "stack_torture1.c", 0x25u, "main");
v13 = func20(v9);
v14 = "pong";
v15 = 5LL;
v16 = (const char *)v13;
do
{
if ( !v15 )
break;
v11 = *v16 < (unsigned int)*v14;
v12 = *v16++ == *v14++;
--v15;
}
while ( v12 );
if ( (!v11 && !v12) != v11 )
__assert_fail("strcmp(resume(ctx), \"pong\") == 0", "stack_torture1.c", 0x26u, "main");
func18(v9, v16);
free(v10);
free(v9);
--v3;
}
while ( v3 );
func15();
return 0;
}

original_code:
int main(void)
{
    uint8_t *stack;
    const int stack_size = 1024 * 4;
    int data[] = { 12, 13, 14, 15, 10, 9, 7, 1, 2, 11, 3, 4, 8, 6, 5, 0 };
    struct sort_ctx sort_arg;
    sort_arg.data = data;
    sort_arg.num_data = sizeof(data) / sizeof(data[0]);
    concurrent_init();
    g_context = malloc(concurrent_sizeof());
    stack = malloc(sizeof(*stack) * stack_size);
    concurrent_construct(g_context, stack, stack_size, coro, (void *)&sort_arg);
    while (!concurrent_is_done(g_context)) {
        size_t stack_size_used = concurrent_get_stack_used(g_context);
        printf("stack used:%3zdbytes(%2.0f%%); data={ ",
               stack_size_used, ((float)stack_size_used / stack_size) * 100.0f);
        print_datas(&sort_arg);
        printf("}\n");
        concurrent_resume(g_context);
    }
    concurrent_destruct(g_context);
    free(stack);
    free(g_context);
    concurrent_fin();
    return 0;
}

user_defined_types: struct sort_ctx { int *data; int num_data; }


decompiled_code:
__int64 __fastcall concurrent_setup_execution_context(__int64 a1)
{
__int64 result; // rax
_QWORD v2[12]; // [rsp-60h] [rbp-60h] BYREF
void *retaddr; // [rsp+0h] [rbp+0h] BYREF

*(_QWORD *)(a1 + 40) = *(_QWORD *)(a1 + 32);
_InterlockedExchange64((volatile __int64 *)(a1 + concurrent_offsetof_stack_ptr), (__int64)&retaddr);
v2[11] = a1;
v2[10] = a1;
v2[9] = concurrent_arch_return_at_procedure;
v2[8] = *(_QWORD *)(a1 + concurrent_offsetof_procedure);
v2[7] = 0LL;
v2[6] = 0LL;
v2[5] = a1;
v2[4] = 0LL;
v2[3] = 0LL;
v2[2] = 0LL;
v2[1] = 0LL;
v2[0] = 0LL;
result = concurrent_offsetof_stack_ptr;
_InterlockedExchange64((volatile __int64 *)(a1 + concurrent_offsetof_stack_ptr), (__int64)v2);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func13(__int64 a1)
{
__int64 result; // rax
_QWORD v2[12]; // [rsp-60h] [rbp-60h] BYREF
void *retaddr; // [rsp+0h] [rbp+0h] BYREF

*(_QWORD *)(a1 + 40) = *(_QWORD *)(a1 + 32);
_InterlockedExchange64((volatile __int64 *)(a1 + concurrent_offsetof_stack_ptr), (__int64)&retaddr);
v2[11] = a1;
v2[10] = a1;
v2[9] = concurrent_arch_return_at_procedure;
v2[8] = *(_QWORD *)(a1 + concurrent_offsetof_procedure);
v2[7] = 0LL;
v2[6] = 0LL;
v2[5] = a1;
v2[4] = 0LL;
v2[3] = 0LL;
v2[2] = 0LL;
v2[1] = 0LL;
v2[0] = 0LL;
result = concurrent_offsetof_stack_ptr;
_InterlockedExchange64((volatile __int64 *)(a1 + concurrent_offsetof_stack_ptr), (__int64)v2);
return result;
}

original_code:
static void
concurrent_setup_execution_context(struct concurrent_ctx *ctx)
{
    ctx->stack_ptr = ctx->stack_base;
    concurrent_arch_setup_execution_context(ctx);
}


decompiled_code:
void concurrent_fin()
{
;
}

canonical_decompiled_code:
void func15()
{
;
}

original_code:
void
concurrent_fin(void)
{
}


decompiled_code:
__int64 concurrent_sizeof()
{
return 80LL;
}

canonical_decompiled_code:
__int64 func16()
{
return 80LL;
}

original_code:
size_t
concurrent_sizeof(void)
{
    return sizeof(struct concurrent_ctx);
}


decompiled_code:
__int64 __fastcall concurrent_construct(__int64 a1, unsigned __int64 a2, unsigned __int64 a3, __int64 a4, __int64 a5)
{
unsigned __int64 v5; // rax
unsigned __int64 v6; // rsi
unsigned __int64 v7; // rsi
__int64 result; // rax

if ( a4 == 0 || a2 == 0 || !a1 )
return 1LL;
if ( a3 <= 0x3FF )
return 2LL;
v5 = (a2 + 15) & 0xFFFFFFFFFFFFFFF0LL;
if ( a2 > v5 )
__assert_fail(
"(uintptr_t)aligned_stack_buffer >= (uintptr_t)stack_buffer",
"src/concurrent.c",
0x5Eu,
"concurrent_construct");
*(_QWORD *)(a1 + 16) = a2;
*(_QWORD *)a1 = a4;
v6 = (a3 + a2 - v5) & 0xFFFFFFFFFFFFFFF0LL;
*(_QWORD *)(a1 + 8) = a5;
*(_QWORD *)(a1 + 24) = v6;
v7 = v5 + v6;
result = 0LL;
*(_QWORD *)(a1 + 32) = v7;
*(_QWORD *)(a1 + 40) = 0LL;
*(_DWORD *)(a1 + 48) = 0;
*(_QWORD *)(a1 + 56) = 0LL;
*(_QWORD *)(a1 + 64) = 0LL;
*(_QWORD *)(a1 + 72) = 0LL;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func17(__int64 a1, unsigned __int64 a2, unsigned __int64 a3, __int64 a4, __int64 a5)
{
unsigned __int64 v5; // rax
unsigned __int64 v6; // rsi
unsigned __int64 v7; // rsi
__int64 result; // rax

if ( a4 == 0 || a2 == 0 || !a1 )
return 1LL;
if ( a3 <= 0x3FF )
return 2LL;
v5 = (a2 + 15) & 0xFFFFFFFFFFFFFFF0LL;
if ( a2 > v5 )
__assert_fail(
"(uintptr_t)aligned_stack_buffer >= (uintptr_t)stack_buffer",
"src/concurrent.c",
0x5Eu,
"concurrent_construct");
*(_QWORD *)(a1 + 16) = a2;
*(_QWORD *)a1 = a4;
v6 = (a3 + a2 - v5) & 0xFFFFFFFFFFFFFFF0LL;
*(_QWORD *)(a1 + 8) = a5;
*(_QWORD *)(a1 + 24) = v6;
v7 = v5 + v6;
result = 0LL;
*(_QWORD *)(a1 + 32) = v7;
*(_QWORD *)(a1 + 40) = 0LL;
*(_DWORD *)(a1 + 48) = 0;
*(_QWORD *)(a1 + 56) = 0LL;
*(_QWORD *)(a1 + 64) = 0LL;
*(_QWORD *)(a1 + 72) = 0LL;
return result;
}

original_code:
concurrent_status
concurrent_construct(struct concurrent_ctx *ctx,
                     void *stack_buffer,
                     size_t stack_size,
                     concurrent_proc proc,
                     void *user_ptr)
{
    const uintptr_t align = 16 - 1;
    uintptr_t aligned_stack_buffer;
    if (ctx && stack_buffer && proc) {
    } else {
        return CONCURRENT_E_INVALID_ARGUMENT;
    }
    if (stack_size < (1024)) {
        return CONCURRENT_E_STACKSIZE_TOO_SMALL;
    }
    aligned_stack_buffer = ((uintptr_t)stack_buffer + align) & ~align;
    (((uintptr_t)aligned_stack_buffer >= (uintptr_t)stack_buffer) ? (void) (0) : __assert_fail ("(uintptr_t)aligned_stack_buffer >= (uintptr_t)stack_buffer", "src/concurrent.c", 94, __extension__ __PRETTY_FUNCTION__));
    ctx->proc = proc;
    ctx->user_ptr = user_ptr;
    ctx->stack_orig = stack_buffer;
    ctx->stack_size = (stack_size - (size_t)(aligned_stack_buffer - (uintptr_t)stack_buffer)) & ~(size_t)align;
    ctx->stack_base = aligned_stack_buffer + ctx->stack_size;
    ctx->stack_ptr = 0;
    ctx->state = CONCURRENT_STATE_SETUP;
    ctx->caller_return_addr = ((void *)0);
    ctx->yield_value = ((void *)0);
    ctx->resume_value = ((void *)0);
    return CONCURRENT_SUCCESS;
}

user_defined_types: enum concurrent_status { CONCURRENT_SUCCESS=0, CONCURRENT_E_INVALID_ARGUMENT=1, CONCURRENT_E_STACKSIZE_TOO_SMALL=2 }


original_code:
void
concurrent_destruct(struct concurrent_ctx *ctx)
{
    ctx->proc = ((void *)0);
    ctx->user_ptr = ((void *)0);
    ctx->stack_orig = ((void *)0);
    ctx->stack_size = 0;
    ctx->stack_base = 0;
    ctx->stack_ptr = 0;
    ctx->state = CONCURRENT_STATE_DONE;
    ctx->caller_return_addr = ((void *)0);
    ctx->yield_value = ((void *)0);
    ctx->resume_value = ((void *)0);
}


decompiled_code:
__int64 __fastcall concurrent_resume_with_value(__int64 a1, __int64 a2)
{
int v2; // eax

v2 = *(_DWORD *)(a1 + 48);
if ( v2 )
{
if ( v2 != 2 )
concurrent_resume_with_value_cold();
}
else
{
concurrent_setup_execution_context(a1);
}
*(_DWORD *)(a1 + 48) = 1;
*(_QWORD *)(a1 + 64) = 0LL;
*(_QWORD *)(a1 + 72) = a2;
concurrent_arch_trampoline_to_procedure(a1);
if ( *(_DWORD *)(a1 + 48) != 1 )
return *(_QWORD *)(a1 + 64);
*(_DWORD *)(a1 + 48) = 3;
return 0LL;
}

original_code:
void *
concurrent_resume_with_value(struct concurrent_ctx *ctx, void *value)
{
    switch (ctx->state) {
    case CONCURRENT_STATE_SETUP:
        concurrent_setup_execution_context(ctx);
    case CONCURRENT_STATE_YIELD:
        ctx->state = CONCURRENT_STATE_EXECUTE;
        ctx->yield_value = ((void *)0);
        ctx->resume_value = value;
        concurrent_arch_trampoline_to_procedure(ctx);
        if (ctx->state == CONCURRENT_STATE_EXECUTE) {
            ctx->state = CONCURRENT_STATE_DONE;
            return ((void *)0);
        } else {
            return ctx->yield_value;
        }
    case CONCURRENT_STATE_EXECUTE:
    case CONCURRENT_STATE_DONE:
    default:
        panic();
    }
    return ((void *)0);
}


decompiled_code:
__int64 __fastcall concurrent_resume(__int64 a1)
{
return concurrent_resume_with_value(a1, 0LL);
}

canonical_decompiled_code:
__int64 __fastcall func20(__int64 a1)
{
return func19(a1, 0LL);
}

original_code:
void *
concurrent_resume(struct concurrent_ctx *ctx)
{
    return concurrent_resume_with_value(ctx, ((void *)0));
}


decompiled_code:
__int64 __fastcall concurrent_get_resume_value(__int64 a1)
{
return *(_QWORD *)(a1 + 72);
}

canonical_decompiled_code:
__int64 __fastcall func21(__int64 a1)
{
return *(_QWORD *)(a1 + 72);
}

original_code:
void *
concurrent_get_resume_value(struct concurrent_ctx *ctx)
{
    return ctx->resume_value;
}


decompiled_code:
__int64 __fastcall concurrent_yield_with_value(__int64 a1, __int64 a2)
{
if ( *(_DWORD *)(a1 + 48) != 1 )
concurrent_yield_with_value_cold();
*(_QWORD *)(a1 + 64) = a2;
*(_DWORD *)(a1 + 48) = 2;
concurrent_arch_trampoline_to_caller();
return *(_QWORD *)(a1 + 72);
}

original_code:
void *
concurrent_yield_with_value(struct concurrent_ctx *ctx, void *value)
{
    if (ctx->state != CONCURRENT_STATE_EXECUTE) {
        panic();
    }
    ctx->yield_value = value;
    ctx->state = CONCURRENT_STATE_YIELD;
    concurrent_arch_trampoline_to_caller(ctx);
    return ctx->resume_value;
}


decompiled_code:
__int64 __fastcall concurrent_yield(__int64 a1)
{
return concurrent_yield_with_value(a1, 0LL);
}

canonical_decompiled_code:
__int64 __fastcall func23(__int64 a1)
{
return func22(a1, 0LL);
}

original_code:
void *
concurrent_yield(struct concurrent_ctx *ctx)
{
    return concurrent_yield_with_value(ctx, ((void *)0));
}


decompiled_code:
__int64 __fastcall concurrent_get_yield_value(__int64 a1)
{
return *(_QWORD *)(a1 + 64);
}

canonical_decompiled_code:
__int64 __fastcall func24(__int64 a1)
{
return *(_QWORD *)(a1 + 64);
}

original_code:
void *
concurrent_get_yield_value(struct concurrent_ctx *ctx)
{
    return ctx->yield_value;
}


decompiled_code:
void __fastcall concurrent_reset(__int64 a1)
{
if ( *(_DWORD *)(a1 + 48) == 1 )
concurrent_reset_cold();
*(_DWORD *)(a1 + 48) = 0;
}

original_code:
void
concurrent_reset(struct concurrent_ctx *ctx)
{
    if (ctx->state == CONCURRENT_STATE_EXECUTE) {
        panic();
    }
    ctx->state = CONCURRENT_STATE_SETUP;
}


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

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

original_code:
void *
concurrent_get_user_ptr(struct concurrent_ctx *ctx)
{
    return ctx->user_ptr;
}


decompiled_code:
bool __fastcall concurrent_is_done(__int64 a1)
{
return *(_DWORD *)(a1 + 48) == 3;
}

canonical_decompiled_code:
bool __fastcall func27(__int64 a1)
{
return *(_DWORD *)(a1 + 48) == 3;
}

original_code:
_Bool
concurrent_is_done(struct concurrent_ctx *ctx)
{
    return (ctx->state == CONCURRENT_STATE_DONE) ? 1 : 0;
}


decompiled_code:
__int64 __fastcall concurrent_get_stack_used(__int64 a1)
{
int v1; // eax

v1 = *(_DWORD *)(a1 + 48);
if ( !v1 )
return 0LL;
if ( v1 == 1 )
concurrent_get_stack_used_cold();
return *(_QWORD *)(a1 + 32) - *(_QWORD *)(a1 + 40);
}

original_code:
size_t
concurrent_get_stack_used(struct concurrent_ctx *ctx)
{
    if (ctx->state == CONCURRENT_STATE_SETUP) {
        return 0;
    }
    if (ctx->state == CONCURRENT_STATE_EXECUTE) {
        panic();
    }
    return (size_t)(ctx->stack_base - ctx->stack_ptr);
}


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

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

original_code:
void *
concurrent_get_stack(struct concurrent_ctx *ctx)
{
    return ctx->stack_orig;
}


panic

decompiled_code:
void __noreturn panic()
{
abort();
}

canonical_decompiled_code:
void __noreturn func1()
{
abort();
}

original_code:
_Noreturn static void
panic(void)
{
    abort();
}