decompiled_code:
__int64 __fastcall ttest_results_get_statistics(int a1, __int64 a2, __int64 a3)
{
__int64 i; // rax

if ( a1 > 0 )
{
for ( i = 0LL; i != a1; ++i )
*(_QWORD *)(a3 + 8 * i) = **(_QWORD **)(a2 + 8 * i);
}
return a3;
}

original_code:
double* ttest_results_get_statistics(int num_rows, ttest_result_t** ttest_results, double* statistics) {
    for (int i = 0; i < num_rows; i++) {
        statistics[i] = ttest_results[i]->statistic;
    }
    return statistics;
}

canonical_original_code:
double *ttest_results_get_statistics(int num_rows, struct ttest_result **ttest_results, double *statistics) {
    for (int i = 0; i < num_rows; i++) {
        statistics[i] = ttest_results[i]->statistic;
    }
    return statistics;
}


repo: opencb-hpg/math

decompiled_code:
__int64 __fastcall ttest_results_get_p_values(int a1, __int64 a2, __int64 a3)
{
__int64 i; // rax

if ( a1 > 0 )
{
for ( i = 0LL; i != a1; ++i )
*(_QWORD *)(a3 + 8 * i) = *(_QWORD *)(*(_QWORD *)(a2 + 8 * i) + 16LL);
}
return a3;
}

original_code:
double* ttest_results_get_p_values(int num_rows, ttest_result_t** ttest_results, double* p_values) {
    for (int i = 0; i < num_rows; i++) {
        p_values[i] = ttest_results[i]->p_value;
    }
    return p_values;
}

canonical_original_code:
double *ttest_results_get_p_values(int num_rows, struct ttest_result **ttest_results, double *p_values) {
    for (int i = 0; i < num_rows; i++) {
        p_values[i] = ttest_results[i]->p_value;
    }
    return p_values;
}

variable_types: struct ttest_result { double statistic; double degrees_of_freedom; double p_value; } **

variable_types: i int

return_type: double *


decompiled_code:
// attributes: thunk
__int64 linear_regression()
{
return gsl_fit_linear();
}

canonical_decompiled_code:
__int64 func0()
{
return gsl_fit_linear();
}

original_code:
int linear_regression(const double *x, const size_t xstride, const double *y, const size_t ystride, const size_t n,
                      double *c0, double *c1, double *cov00, double *cov01, double *cov11, double *sumsq) {
    return gsl_fit_linear(x, xstride, y, ystride, n, c0, c1, cov00, cov01, cov11, sumsq);
}

canonical_original_code:
int linear_regression(double *x, unsigned long xstride, double *y, unsigned long ystride, unsigned long n, double *c0, double *c1, double *cov00, double *cov01, double *cov11, double *sumsq) {
    return gsl_fit_linear(x, xstride, y, ystride, n, c0, c1, cov00, cov01, cov11, sumsq);
}

variable_types:
x
double *

variable_types:
xstride
unsigned long

variable_types:
y
double *

variable_types:
ystride
unsigned long

variable_types:
n
unsigned long

variable_types:
sumsq
double *

return_type: int


decompiled_code:
__int64 __fastcall anova_test(int a1, int a2, __int64 a3, double a4, double a5)
{
double v6; // xmm0_8
__int64 result; // rax

*(_DWORD *)(a3 + 8) = a1;
*(_DWORD *)(a3 + 12) = a2;
*(double *)a3 = a4 / a5;
*(double *)(a3 + 16) = gsl_ran_fdist_pdf();
v6 = gsl_cdf_fdist_P(*(double *)a3, (double)a1, (double)a2);
result = a3;
*(double *)(a3 + 16) = 1.0 - v6;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(int a1, int a2, __int64 a3, double a4, double a5)
{
double v6; // xmm0_8
__int64 result; // rax

*(_DWORD *)(a3 + 8) = a1;
*(_DWORD *)(a3 + 12) = a2;
*(double *)a3 = a4 / a5;
*(double *)(a3 + 16) = gsl_ran_fdist_pdf();
v6 = gsl_cdf_fdist_P(*(double *)a3, (double)a1, (double)a2);
result = a3;
*(double *)(a3 + 16) = 1.0 - v6;
return result;
}

original_code:
anova_result_t* anova_test(double msbg, double mswg, int dfbg, int dfwg, anova_result_t* anova_result) {
    anova_result->statistic = msbg / mswg;
    anova_result->dfbg = dfbg;
    anova_result->dfwg = dfwg;
    anova_result->p_value = gsl_ran_fdist_pdf(anova_result->statistic, dfbg, dfwg);
    anova_result->p_value = 1 - gsl_cdf_fdist_P(anova_result->statistic, dfbg, dfwg);
    return anova_result;
}

canonical_original_code:
struct anova_result *anova_test(double msbg, double mswg, int dfbg, int dfwg, struct anova_result *anova_result) {
    anova_result->statistic = msbg / mswg;
    anova_result->dfbg = dfbg;
    anova_result->dfwg = dfwg;
    anova_result->p_value = gsl_ran_fdist_pdf(anova_result->statistic, dfbg, dfwg);
    anova_result->p_value = 1 - gsl_cdf_fdist_P(anova_result->statistic, dfbg, dfwg);
    return anova_result;
}

variable_types: msbg double

variable_types: mswg double

variable_types: dfbg int

variable_types: dfwg int

return_type: struct anova_result { double statistic; int dfbg; int dfwg; double p_value; } *


repo: opendaylight/opendove

decompiled_code:
size_t __fastcall reply_cb(void *src, __int64 a2, __int64 a3, __int64 a4)
{
size_t v5; // r12
char *v6; // rax
_BYTE *v7; // rdx
size_t v8; // rax

v5 = a3 * a2;
v6 = (char *)realloc(*(void **)a4, a3 * a2 + *(_QWORD *)(a4 + 8) + 1);
*(_QWORD *)a4 = v6;
if ( v6 )
{
memcpy(&v6[*(_QWORD *)(a4 + 8)], src, v5);
v7 = *(_BYTE **)a4;
v8 = v5 + *(_QWORD *)(a4 + 8);
*(_QWORD *)(a4 + 8) = v8;
v7[v8] = 0;
}
else
{
v5 = 0LL;
fwrite("not enough memory (realloc returned NULL)\n", 1uLL, 0x2AuLL, stderr);
}
return v5;
}

canonical_decompiled_code:
size_t __fastcall func2(void *src, __int64 a2, __int64 a3, __int64 a4)
{
size_t v5; // r12
char *v6; // rax
_BYTE *v7; // rdx
size_t v8; // rax

v5 = a3 * a2;
v6 = (char *)realloc(*(void **)a4, a3 * a2 + *(_QWORD *)(a4 + 8) + 1);
*(_QWORD *)a4 = v6;
if ( v6 )
{
memcpy(&v6[*(_QWORD *)(a4 + 8)], src, v5);
v7 = *(_BYTE **)a4;
v8 = v5 + *(_QWORD *)(a4 + 8);
*(_QWORD *)(a4 + 8) = v8;
v7[v8] = 0;
}
else
{
v5 = 0LL;
fwrite("not enough memory (realloc returned NULL)\n", 1uLL, 0x2AuLL, stderr);
}
return v5;
}

original_code:
static size_t
reply_cb(void *contents, size_t size, size_t nmemb, void *userp)
{
  size_t realsize = size * nmemb;
  struct reply_buffer *buf = (struct reply_buffer *)userp;
  buf->memory = realloc(buf->memory, buf->size + realsize + 1);
  if(buf->memory == ((void *)0)) {
    fprintf(stderr, "not enough memory (realloc returned NULL)\n");
    return 0;
  }
  memcpy(&(buf->memory[buf->size]), contents, realsize);
  buf->size += realsize;
  buf->memory[buf->size] = 0;
  return realsize;
}

canonical_original_code:
static unsigned long reply_cb(void *contents, unsigned long size, unsigned long nmemb, void *userp)
{
  unsigned long realsize = size * nmemb;
  struct reply_buffer *buf = (struct reply_buffer *)userp;
  buf->memory = realloc(buf->memory, buf->size + realsize + 1);
  if(buf->memory == ((void *)0)) {
    fprintf(stderr, "not enough memory (realloc returned NULL)\n");
    return 0;
  }
  memcpy(&(buf->memory[buf->size]), contents, realsize);
  buf->size += realsize;
  buf->memory[buf->size] = 0;
  return realsize;
}

variable_types:
contents
void *

variable_types:
size
unsigned long

variable_types:
nmemb
unsigned long

variable_types:
userp
void *

variable_types:
realsize
unsigned long

variable_types: struct reply_buffer { char *memory; unsigned long size; } *

return_type: unsigned long


decompiled_code:
__int64 __fastcall dove_dmc_client_init(const char *a1, __int64 a2)
{
__int64 v2; // rax
__int64 v3; // rbp
__int64 v4; // rax
__int64 v5; // rsi
unsigned int v6; // er12
void *ptr; // [rsp+8h] [rbp-B0h] BYREF
char s[168]; // [rsp+10h] [rbp-A8h] BYREF

ptr = 0LL;
curl_global_init(3LL);
v2 = curl_easy_init();
if ( v2 )
{
v3 = v2;
read_uuid_from_file();
sprintf(s, "http://%s/controller/sb/v2/opendove/odmc/switch", a1);
v4 = json_pack("{s:s, s:s, s:s, s:s}", "id", "null", "name", a2, "tunnelip", a2, "managementip", a2);
v5 = send_rest_req((__int64)s, 2, v4, &ptr);
v6 = parse_switch_reg((__int64)ptr, v5);
if ( ptr )
free(ptr);
curl_easy_cleanup(v3);
curl_global_cleanup();
}
else
{
v6 = 1;
fwrite("failed to initialize curl handle, exiting\n", 1uLL, 0x2AuLL, stderr);
}
return v6;
}

canonical_decompiled_code:
__int64 __fastcall func7(const char *a1, __int64 a2)
{
__int64 v2; // rax
__int64 v3; // rbp
__int64 v4; // rax
__int64 v5; // rsi
unsigned int v6; // er12
void *ptr; // [rsp+8h] [rbp-B0h] BYREF
char s[168]; // [rsp+10h] [rbp-A8h] BYREF

ptr = 0LL;
curl_global_init(3LL);
v2 = curl_easy_init();
if ( v2 )
{
v3 = v2;
func0();
sprintf(s, "http://%s/controller/sb/v2/opendove/odmc/switch", a1);
v4 = json_pack("{s:s, s:s, s:s, s:s}", "id", "null", "name", a2, "tunnelip", a2, "managementip", a2);
v5 = func1((__int64)s, 2, v4, &ptr);
v6 = func4((__int64)ptr, v5);
if ( ptr )
free(ptr);
curl_easy_cleanup(v3);
curl_global_cleanup();
}
else
{
v6 = 1;
fwrite("failed to initialize curl handle, exiting\n", 1uLL, 0x2AuLL, stderr);
}
return v6;
}

original_code:
int dove_dmc_client_init(const char *dmcIP, char *switchIP)
{
  char url[128];
  CURL *curl;
  json_t *js_root = ((void *)0);
  char *data = ((void *)0);
  long http_status;
  int ret;
  curl_global_init(((1<<0)|(1<<1)));
  curl = curl_easy_init();
  if(!curl) {
    fprintf(stderr, "failed to initialize curl handle, exiting\n");
    return 1;
  }
  read_uuid_from_file();
  sprintf(url, "http://%s/controller/sb/v2/opendove/odmc/switch", dmcIP);
  js_root = json_pack("{s:s, s:s, s:s, s:s}",
        "id", "null",
        "name", switchIP,
        "tunnelip", switchIP,
        "managementip", switchIP);
  http_status = send_rest_req(url, POST, js_root, &data);
  ret = parse_switch_reg(data, http_status);
  if(data) {
    free(data);
  }
  curl_easy_cleanup(curl);
  curl_global_cleanup();
  return ret;
}

canonical_original_code:
int dove_dmc_client_init(char *dmcIP, char *switchIP)
{
  char url[128];
  void *curl;
  struct json_t *js_root = ((void *)0);
  char *data = ((void *)0);
  long http_status;
  int ret;
  curl_global_init(((1<<0)|(1<<1)));
  curl = curl_easy_init();
  if(!curl) {
    fprintf(stderr, "failed to initialize curl handle, exiting\n");
    return 1;
  }
  read_uuid_from_file();
  sprintf(url, "http://%s/controller/sb/v2/opendove/odmc/switch", dmcIP);
  js_root = json_pack("{s:s, s:s, s:s, s:s}",
        "id", "null",
        "name", switchIP,
        "tunnelip", switchIP,
        "managementip", switchIP);
  http_status = send_rest_req(url, POST, js_root, &data);
  ret = parse_switch_reg(data, http_status);
  if(data) {
    free(data);
  }
  curl_easy_cleanup(curl);
  curl_global_cleanup();
  return ret;
}

variable_types:
dmcIP
char *

variable_types:
switchIP
char *

variable_types:
url
char [128]

variable_types:
curl
void *

variable_types: struct json_t { enum json_type { JSON_OBJECT=0, JSON_ARRAY=1, JSON_STRING=2, JSON_INTEGER=3, JSON_REAL=4, JSON_TRUE=5, JSON_FALSE=6, JSON_NULL=7 } type; unsigned long refcount; } *

variable_types:
data
char *

variable_types: ret int

user_defined_types: struct json_t { enum json_type type; unsigned long refcount; }


decompiled_code:
void dove_dmc_client_cleanup()
{
;
}

canonical_decompiled_code:
void func8()
{
;
}

original_code:
void dove_dmc_client_cleanup()
{
}

canonical_original_code:
void dove_dmc_client_cleanup()
{
}

return_type: void


decompiled_code:
__int64 __fastcall dove_dmc_get_leader(const char *a1, in_addr_t *a2, __int16 *a3)
{
__int64 v5; // rax
__int64 v6; // rbp
__int64 v7; // rsi
unsigned int v8; // er12
void *ptr; // [rsp+8h] [rbp-B0h] BYREF
char s[168]; // [rsp+10h] [rbp-A8h] BYREF

ptr = 0LL;
curl_global_init(3LL);
v5 = curl_easy_init();
if ( v5 )
{
v6 = v5;
sprintf(s, "http://%s/controller/sb/v2/opendove/odmc/odcs/leader", a1);
v7 = send_rest_req((__int64)s, 0, 0LL, &ptr);
v8 = parse_get_leader((const char *)ptr, v7, a2, a3);
if ( ptr )
free(ptr);
curl_easy_cleanup(v6);
curl_global_cleanup();
}
else
{
v8 = 1;
fwrite("failed to initialize curl handle, exiting\n", 1uLL, 0x2AuLL, stderr);
}
return v8;
}

canonical_decompiled_code:
__int64 __fastcall func9(const char *a1, in_addr_t *a2, __int16 *a3)
{
__int64 v5; // rax
__int64 v6; // rbp
__int64 v7; // rsi
unsigned int v8; // er12
void *ptr; // [rsp+8h] [rbp-B0h] BYREF
char s[168]; // [rsp+10h] [rbp-A8h] BYREF

ptr = 0LL;
curl_global_init(3LL);
v5 = curl_easy_init();
if ( v5 )
{
v6 = v5;
sprintf(s, "http://%s/controller/sb/v2/opendove/odmc/odcs/leader", a1);
v7 = func1((__int64)s, 0, 0LL, &ptr);
v8 = func6((const char *)ptr, v7, a2, a3);
if ( ptr )
free(ptr);
curl_easy_cleanup(v6);
curl_global_cleanup();
}
else
{
v8 = 1;
fwrite("failed to initialize curl handle, exiting\n", 1uLL, 0x2AuLL, stderr);
}
return v8;
}

original_code:
int dove_dmc_get_leader(const char *dmcIP, struct in_addr *dcs_ip, short *dcs_port)
{
  char url[128];
  CURL *curl;
  char *data = ((void *)0);
  long http_status;
  int ret = -1;
  curl_global_init(((1<<0)|(1<<1)));
  curl = curl_easy_init();
  if(!curl) {
    fprintf(stderr, "failed to initialize curl handle, exiting\n");
    return 1;
  }
  sprintf(url, "http://%s/controller/sb/v2/opendove/odmc/odcs/leader", dmcIP);
  http_status = send_rest_req(url, GET, ((void *)0), &data);
  ret = parse_get_leader(data, http_status, dcs_ip, dcs_port);
  if(data) {
    free(data);
  }
  curl_easy_cleanup(curl);
  curl_global_cleanup();
  return ret;
}

canonical_original_code:
int dove_dmc_get_leader(char *dmcIP, struct in_addr *dcs_ip, short *dcs_port)
{
  char url[128];
  void *curl;
  char *data = ((void *)0);
  long http_status;
  int ret = -1;
  curl_global_init(((1<<0)|(1<<1)));
  curl = curl_easy_init();
  if(!curl) {
    fprintf(stderr, "failed to initialize curl handle, exiting\n");
    return 1;
  }
  sprintf(url, "http://%s/controller/sb/v2/opendove/odmc/odcs/leader", dmcIP);
  http_status = send_rest_req(url, GET, ((void *)0), &data);
  ret = parse_get_leader(data, http_status, dcs_ip, dcs_port);
  if(data) {
    free(data);
  }
  curl_easy_cleanup(curl);
  curl_global_cleanup();
  return ret;
}

variable_types: struct in_addr { unsigned int s_addr; } *


decompiled_code:
__int64 __fastcall dove_dmc_send_hb(const char *a1)
{
__int64 result; // rax
__int64 v2; // rbp
__int64 v3; // rax
__int64 v4; // rax
void *ptr; // [rsp+0h] [rbp-A0h] BYREF
char s[152]; // [rsp+8h] [rbp-98h] BYREF

result = 0LL;
if ( switch_uuid[0] )
{
curl_global_init(3LL);
v2 = curl_easy_init();
if ( v2 )
{
sprintf(s, "http://%s/controller/sb/v2/opendove/odmc/switch/%s", a1, switch_uuid);
v3 = json_pack(
"{s:s, s:s, s:s, s:s}",
"id",
switch_uuid,
"name",
switch_name,
"tunnelip",
switch_name,
"managementip",
switch_name);
v4 = send_rest_req((__int64)s, 1, v3, &ptr);
printf("DMC HB response status: %ld\n", v4);
if ( ptr )
free(ptr);
curl_easy_cleanup(v2);
curl_global_cleanup();
result = 0xFFFFFFFFLL;
}
else
{
fwrite("failed to initialize curl handle, exiting\n", 1uLL, 0x2AuLL, stderr);
result = 1LL;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func10(const char *a1)
{
__int64 result; // rax
__int64 v2; // rbp
__int64 v3; // rax
__int64 v4; // rax
void *ptr; // [rsp+0h] [rbp-A0h] BYREF
char s[152]; // [rsp+8h] [rbp-98h] BYREF

result = 0LL;
if ( switch_uuid[0] )
{
curl_global_init(3LL);
v2 = curl_easy_init();
if ( v2 )
{
sprintf(s, "http://%s/controller/sb/v2/opendove/odmc/switch/%s", a1, switch_uuid);
v3 = json_pack(
"{s:s, s:s, s:s, s:s}",
"id",
switch_uuid,
"name",
switch_name,
"tunnelip",
switch_name,
"managementip",
switch_name);
v4 = func1((__int64)s, 1, v3, &ptr);
printf("DMC HB response status: %ld\n", v4);
if ( ptr )
free(ptr);
curl_easy_cleanup(v2);
curl_global_cleanup();
result = 0xFFFFFFFFLL;
}
else
{
fwrite("failed to initialize curl handle, exiting\n", 1uLL, 0x2AuLL, stderr);
result = 1LL;
}
}
return result;
}

original_code:
int dove_dmc_send_hb(const char *dmcIP)
{
  char url[128];
  CURL *curl;
  long http_status;
  int ret = -1;
  json_t *js_root = ((void *)0);
  char *data;
  if(strlen(switch_uuid) == 0) {
    return 0;
  }
  curl_global_init(((1<<0)|(1<<1)));
  curl = curl_easy_init();
  if(!curl) {
    fprintf(stderr, "failed to initialize curl handle, exiting\n");
    return 1;
  }
  sprintf(url, "http://%s/controller/sb/v2/opendove/odmc/switch/%s", dmcIP, switch_uuid);
  js_root = json_pack("{s:s, s:s, s:s, s:s}",
        "id", switch_uuid,
        "name", switch_name,
        "tunnelip", switch_name,
        "managementip", switch_name);
  http_status = send_rest_req(url, PUT, js_root, &data);
  printf("DMC HB response status: %ld\n", http_status);
  if(data) {
    free(data);
  }
  curl_easy_cleanup(curl);
  curl_global_cleanup();
  return ret;
}

canonical_original_code:
int dove_dmc_send_hb(char *dmcIP)
{
  char url[128];
  void *curl;
  long http_status;
  int ret = -1;
  struct json_t *js_root = ((void *)0);
  char *data;
  if(strlen(switch_uuid) == 0) {
    return 0;
  }
  curl_global_init(((1<<0)|(1<<1)));
  curl = curl_easy_init();
  if(!curl) {
    fprintf(stderr, "failed to initialize curl handle, exiting\n");
    return 1;
  }
  sprintf(url, "http://%s/controller/sb/v2/opendove/odmc/switch/%s", dmcIP, switch_uuid);
  js_root = json_pack("{s:s, s:s, s:s, s:s}",
        "id", switch_uuid,
        "name", switch_name,
        "tunnelip", switch_name,
        "managementip", switch_name);
  http_status = send_rest_req(url, PUT, js_root, &data);
  printf("DMC HB response status: %ld\n", http_status);
  if(data) {
    free(data);
  }
  curl_easy_cleanup(curl);
  curl_global_cleanup();
  return ret;
}

user_defined_types: enum json_type { JSON_OBJECT=0, JSON_ARRAY=1, JSON_STRING=2, JSON_INTEGER=3, JSON_REAL=4, JSON_TRUE=5, JSON_FALSE=6, JSON_NULL=7 }


decompiled_code:
void __fastcall dps_info(int pri, char *format, __gnuc_va_list arg)
{
char v3[552]; // [rsp+0h] [rbp-228h] BYREF

memset(v3, 0, 0x200uLL);
vsnprintf(v3, 0x200uLL, format, arg);
syslog(pri, "%s", v3);
}

canonical_decompiled_code:
void __fastcall func0(int pri, char *format, __gnuc_va_list arg)
{
char v3[552]; // [rsp+0h] [rbp-228h] BYREF

memset(v3, 0, 0x200uLL);
vsnprintf(v3, 0x200uLL, format, arg);
syslog(pri, "%s", v3);
}

original_code:
void dps_info(int level, const char *fmt, va_list ap)
{
 char buf[512 + 1];
 memset(buf, 0, 512);
 vsnprintf(buf, 512, fmt, ap);
 syslog(level, "%s", buf);
 return;
}

canonical_original_code:
void dps_info(int level, char *fmt, __builtin_va_list ap)
{
 char buf[-1];
 memset(buf, 0, 512);
 vsnprintf(buf, 512, fmt, ap);
 syslog(level, "%s", buf);
 return;
}

variable_types: level int

variable_types:
fmt
char *

variable_types:
buf
char [-1]


decompiled_code:
void __noreturn dps_die(char *format, ...)
{
gcc_va_list arg; // [rsp+8h] [rbp-D0h] BYREF

va_start(arg, format);
dps_info(3, format, arg);
exit(-1);
}

canonical_decompiled_code:
void __noreturn func1(char *format, ...)
{
gcc_va_list arg; // [rsp+8h] [rbp-D0h] BYREF

va_start(arg, format);
func0(3, format, arg);
exit(-1);
}

original_code:
void dps_die(const char *fmt, ...)
{
 va_list ap;
 __builtin_va_start(ap,fmt);
 dps_info(3, fmt, ap);
 __builtin_va_end(ap);
 exit(-1);
}

canonical_original_code:
void dps_die(char *fmt, ...)
{
 __builtin_va_list ap;
 __builtin_va_start(ap,fmt);
 dps_info(3, fmt, ap);
 __builtin_va_end(ap);
 exit(-1);
}


decompiled_code:
__int64 __fastcall create_timer(const char *a1, int a2, void (__fastcall *a3)(unsigned __int64), __int64 a4, __int64 *a5)
{
_QWORD *v9; // [rsp+30h] [rbp-10h]
__int64 v10; // [rsp+38h] [rbp-8h]

v10 = 0LL;
if ( !a1 && !a3 )
return 0xFFFFFFFFLL;
if ( !a3 )
{
v10 = search_task(a1);
if ( !v10 )
return 0xFFFFFFFFLL;
}
v9 = malloc(0x38uLL);
if ( !v9 )
return 0xFFFFFFFFLL;
hlist_node_init(v9);
v9[3] = v10;
*((_DWORD *)v9 + 8) = a2;
v9[5] = a3;
v9[6] = a4;
*a5 = (__int64)v9;
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func0(const char *a1, int a2, void (__fastcall *a3)(unsigned __int64), __int64 a4, __int64 *a5)
{
_QWORD *v9; // [rsp+30h] [rbp-10h]
__int64 v10; // [rsp+38h] [rbp-8h]

v10 = 0LL;
if ( !a1 && !a3 )
return 0xFFFFFFFFLL;
if ( !a3 )
{
v10 = search_task(a1);
if ( !v10 )
return 0xFFFFFFFFLL;
}
v9 = malloc(0x38uLL);
if ( !v9 )
return 0xFFFFFFFFLL;
hlist_node_init(v9);
v9[3] = v10;
*((_DWORD *)v9 + 8) = a2;
v9[5] = a3;
v9[6] = a4;
*a5 = (__int64)v9;
return 0LL;
}

original_code:
int create_timer(const char *task_name, unsigned int event,
                 void(*callback)(unsigned long), unsigned long data,
                 long *timer_id)
{
    timer_list *timer = ((void *)0);
    long tid = 0;
    if ((task_name == ((void *)0)) && (callback == ((void *)0)))
        return -1;
    if (!callback)
        if ((tid = search_task(task_name)) == 0)
            return -1;
    timer = (timer_list *)malloc(sizeof(timer_list));
    if (timer == ((void *)0))
        return -1;
    hlist_node_init(&timer->entry);
    timer->tid = tid;
    timer->event = event;
    timer->callback = callback;
    timer->data = data;
    *timer_id = (long)timer;
    return 0;
}

canonical_original_code:
int create_timer(char *task_name, unsigned int event, void (*callback)(unsigned long), unsigned long data, long *timer_id)
{
    struct _timer_list *timer = ((void *)0);
    long tid = 0;
    if ((task_name == ((void *)0)) && (callback == ((void *)0)))
        return -1;
    if (!callback)
        if ((tid = search_task(task_name)) == 0)
            return -1;
    timer = (struct _timer_list *)malloc(sizeof(timer_list));
    if (timer == ((void *)0))
        return -1;
    hlist_node_init(&timer->entry);
    timer->tid = tid;
    timer->event = event;
    timer->callback = callback;
    timer->data = data;
    *timer_id = (long)timer;
    return 0;
}

variable_types:
event
unsigned int

variable_types:
callback
void (*)(unsigned long)

variable_types:
data
unsigned long

variable_types: struct _timer_list { struct _hlist_node { struct _hlist_node *next; struct _hlist_node **pprevious; } entry; unsigned long expires; long tid; unsigned int event; void (*callback)(unsigned long); unsigned long data; } *

variable_types: tid long

user_defined_types: struct _timer_list { struct _hlist_node entry; unsigned long expires; long tid; unsigned int event; void (*callback)(unsigned long); unsigned long data; }


decompiled_code:
__int64 __fastcall del_timer(void *a1)
{
if ( !a1 )
return 0xFFFFFFFFLL;
free(a1);
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func1(void *a1)
{
if ( !a1 )
return 0xFFFFFFFFLL;
free(a1);
return 0LL;
}

original_code:
int del_timer(long timer_id)
{
    timer_list *timer = (timer_list *)timer_id;
    if (timer == ((void *)0))
        return -1;
    free(timer);
    return 0;
}

canonical_original_code:
int del_timer(long timer_id)
{
    struct _timer_list *timer = (timer_list *)timer_id;
    if (timer == ((void *)0))
        return -1;
    free(timer);
    return 0;
}

user_defined_types: struct _hlist_node { struct _hlist_node *next; struct _hlist_node **pprevious; }


decompiled_code:
int __fastcall start_timer_internal(__int64 *a1, __int64 a2)
{
pthread_mutex_lock(tvbase);
a1[2] = a2 + tvbase[1].__align;
add_timer(a1);
return pthread_mutex_unlock(tvbase);
}

canonical_decompiled_code:
int __fastcall func2(__int64 *a1, __int64 a2)
{
pthread_mutex_lock(tvbase);
a1[2] = a2 + tvbase[1].__align;
add_timer(a1);
return pthread_mutex_unlock(tvbase);
}

original_code:
void start_timer_internal(long timer_id, unsigned long expires)
{
    timer_list *timer = (timer_list *)timer_id;
    pthread_mutex_lock(&tvbase->lock);
    timer->expires = expires + tvbase->ticks;
    add_timer(timer);
    pthread_mutex_unlock(&tvbase->lock);
    return;
}

canonical_original_code:
void start_timer_internal(long timer_id, unsigned long expires)
{
    struct _timer_list *timer = (timer_list *)timer_id;
    pthread_mutex_lock(&tvbase->lock);
    timer->expires = expires + tvbase->ticks;
    add_timer(timer);
    pthread_mutex_unlock(&tvbase->lock);
    return;
}

variable_types:
expires
unsigned long


decompiled_code:
int __fastcall stop_timer(_QWORD *a1)
{
pthread_mutex_lock(tvbase);
if ( a1 && a1[1] && *a1 != 3134263569LL && a1[1] != 3134333474LL )
hlist_node_remove(a1);
return pthread_mutex_unlock(tvbase);
}

canonical_decompiled_code:
int __fastcall func4(_QWORD *a1)
{
pthread_mutex_lock(tvbase);
if ( a1 && a1[1] && *a1 != 3134263569LL && a1[1] != 3134333474LL )
hlist_node_remove(a1);
return pthread_mutex_unlock(tvbase);
}

original_code:
void stop_timer(long timer_id)
{
    timer_list *timer = (timer_list *)timer_id;
    pthread_mutex_lock(&tvbase->lock);
    if (timer &&
        timer->entry.pprevious &&
        timer->entry.next != ((void *) 0xbad11111) &&
        timer->entry.pprevious != ((void *) 0xbad22222))
        hlist_node_remove(&timer->entry);
    pthread_mutex_unlock(&tvbase->lock);
    return;
}

canonical_original_code:
void stop_timer(long timer_id)
{
    struct _timer_list *timer = (timer_list *)timer_id;
    pthread_mutex_lock(&tvbase->lock);
    if (timer &&
        timer->entry.pprevious &&
        timer->entry.next != ((void *) 0xbad11111) &&
        timer->entry.pprevious != ((void *) 0xbad22222))
        hlist_node_remove(&timer->entry);
    pthread_mutex_unlock(&tvbase->lock);
    return;
}


decompiled_code:
void __fastcall __noreturn timer_main(void *a1)
{
struct timeval i; // [rsp+10h] [rbp-70h]
struct timeval tv; // [rsp+20h] [rbp-60h] BYREF
struct timespec requested_time; // [rsp+30h] [rbp-50h] BYREF
unsigned __int64 v4; // [rsp+48h] [rbp-38h]
__time_t v5; // [rsp+50h] [rbp-30h]
unsigned __int64 v6; // [rsp+58h] [rbp-28h]
unsigned __int64 v7; // [rsp+60h] [rbp-20h]
__int64 v8; // [rsp+68h] [rbp-18h]
unsigned __int64 v9; // [rsp+70h] [rbp-10h]
unsigned __int64 v10; // [rsp+78h] [rbp-8h]

v10 = 0LL;
v8 = 0LL;
v6 = 0LL;
requested_time.tv_sec = 0LL;
requested_time.tv_nsec = 100000000LL;
for ( i = (struct timeval)0LL; ; i = tv )
{
gettimeofday(&tv, 0LL);
if ( i == 0uLL )
i = tv;
v5 = tv.tv_sec - i.tv_sec;
v7 = tv.tv_usec - i.tv_usec;
if ( tv.tv_sec - i.tv_sec == 2 )
{
v7 += 1000000LL;
}
else
{
if ( v5 > 2 )
goto LABEL_8;
if ( !v5 )
goto LABEL_11;
if ( v5 != 1 )
{
LABEL_8:
v7 += 1000000 * v5;
goto LABEL_11;
}
}
v7 += 1000000LL;
LABEL_11:
v4 = v7;
v9 = v7 / 0x186A0;
v10 += v7;
v6 = v10 / 0x186A0;
v8 += v7 / 0x186A0;
if ( v10 / 0x186A0 != v8 )
{
v9 += v6 - v8;
v8 = 0LL;
v6 = 0LL;
v10 = 0LL;
}
while ( v9 )
{
process_tick();
--v9;
}
nanosleep(&requested_time, 0LL);
}
}

canonical_decompiled_code:
void __fastcall __noreturn func6(void *a1)
{
struct timeval i; // [rsp+10h] [rbp-70h]
struct timeval tv; // [rsp+20h] [rbp-60h] BYREF
struct timespec requested_time; // [rsp+30h] [rbp-50h] BYREF
unsigned __int64 v4; // [rsp+48h] [rbp-38h]
__time_t v5; // [rsp+50h] [rbp-30h]
unsigned __int64 v6; // [rsp+58h] [rbp-28h]
unsigned __int64 v7; // [rsp+60h] [rbp-20h]
__int64 v8; // [rsp+68h] [rbp-18h]
unsigned __int64 v9; // [rsp+70h] [rbp-10h]
unsigned __int64 v10; // [rsp+78h] [rbp-8h]

v10 = 0LL;
v8 = 0LL;
v6 = 0LL;
requested_time.tv_sec = 0LL;
requested_time.tv_nsec = 100000000LL;
for ( i = (struct timeval)0LL; ; i = tv )
{
gettimeofday(&tv, 0LL);
if ( i == 0uLL )
i = tv;
v5 = tv.tv_sec - i.tv_sec;
v7 = tv.tv_usec - i.tv_usec;
if ( tv.tv_sec - i.tv_sec == 2 )
{
v7 += 1000000LL;
}
else
{
if ( v5 > 2 )
goto LABEL_8;
if ( !v5 )
goto LABEL_11;
if ( v5 != 1 )
{
LABEL_8:
v7 += 1000000 * v5;
goto LABEL_11;
}
}
v7 += 1000000LL;
LABEL_11:
v4 = v7;
v9 = v7 / 0x186A0;
v10 += v7;
v6 = v10 / 0x186A0;
v8 += v7 / 0x186A0;
if ( v10 / 0x186A0 != v8 )
{
v9 += v6 - v8;
v8 = 0LL;
v6 = 0LL;
v10 = 0LL;
}
while ( v9 )
{
func5();
--v9;
}
nanosleep(&requested_time, 0LL);
}
}

original_code:
static void timer_main(void *arg)
{
    struct timespec req;
    struct timeval cur;
    struct timeval last;
    unsigned long elapsed_usec, total_elapsed_usec = 0;
    unsigned long ticks, total_ticks = 0, real_total_ticks = 0;
    (void)arg;
    req.tv_sec = 100/1000;
    req.tv_nsec = 100*1000000;
    last.tv_sec = 0;
    last.tv_usec = 0;
    while (1)
    {
        gettimeofday(&cur, ((void *)0));
        if ((last.tv_sec == 0) && (last.tv_usec == 0))
            last = cur;
        elapsed_usec = ({ long long __delta_sec = (cur).tv_sec - (last).tv_sec; long long __delta_usec = (cur).tv_usec - (last).tv_usec; switch (__delta_sec) { default: __delta_usec = __delta_sec * 1000000 + __delta_usec; break; case 2: __delta_usec += 1000000; case 1: __delta_usec += 1000000; case 0: ; } __delta_usec; });
        ticks = elapsed_usec/(1000*100);
        total_elapsed_usec += elapsed_usec;
        real_total_ticks = total_elapsed_usec/(1000*100);
        total_ticks += ticks;
        if (real_total_ticks != total_ticks)
        {
            ticks += (real_total_ticks - total_ticks);
            total_elapsed_usec = real_total_ticks = total_ticks = 0;
        }
        while (ticks)
        {
            process_tick();
            ticks--;
        }
        nanosleep(&req, ((void *)0));
        last = cur;
    }
    return;
}

canonical_original_code:
static void timer_main(void *arg)
{
    struct timespec req;
    struct timeval cur;
    struct timeval last;
    unsigned long elapsed_usec; unsigned long total_elapsed_usec = 0;
    unsigned long ticks; unsigned long total_ticks = 0; unsigned long real_total_ticks = 0;
    (void)arg;
    req.tv_sec = 100/1000;
    req.tv_nsec = 100*1000000;
    last.tv_sec = 0;
    last.tv_usec = 0;
    while (1)
    {
        gettimeofday(&cur, ((void *)0));
        if ((last.tv_sec == 0) && (last.tv_usec == 0))
            last = cur;
        elapsed_usec = ({ long long __delta_sec = (cur).tv_sec - (last).tv_sec; long long __delta_usec = (cur).tv_usec - (last).tv_usec; switch (__delta_sec) { default: __delta_usec = __delta_sec * 1000000 + __delta_usec; break; case 2: __delta_usec += 1000000; case 1: __delta_usec += 1000000; case 0: ; } __delta_usec; });
        ticks = elapsed_usec/(1000*100);
        total_elapsed_usec += elapsed_usec;
        real_total_ticks = total_elapsed_usec/(1000*100);
        total_ticks += ticks;
        if (real_total_ticks != total_ticks)
        {
            ticks += (real_total_ticks - total_ticks);
            total_elapsed_usec = real_total_ticks = total_ticks = 0;
        }
        while (ticks)
        {
            process_tick();
            ticks--;
        }
        nanosleep(&req, ((void *)0));
        last = cur;
    }
    return;
}

variable_types:
arg
void *

variable_types: struct timespec { long tv_sec; long tv_nsec; }

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

variable_types:
ticks
unsigned long


decompiled_code:
__int64 timer_base_init(void)
{
__int64 result; // rax
pthread_mutexattr_t attr; // [rsp+Ch] [rbp-4h] BYREF

tvbase = (pthread_mutex_t *)malloc(0x438uLL);
if ( tvbase )
{
memset(tvbase, 0, 0x438uLL);
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, 1);
pthread_mutex_init(tvbase, &attr);
if ( (unsigned int)create_task(
"Timer",
0,
0x100000uLL,
(void (__fastcall *)(void *))timer_main,
0LL,
(__int64 *)&tvbase[26].__list.__next) )
{
puts("Fail to create timer thread!\r");
result = 0xFFFFFFFFLL;
}
else
{
result = 0LL;
}
}
else
{
puts("Fail to memory allocation!\r");
result = 0xFFFFFFFFLL;
}
return result;
}

canonical_decompiled_code:
__int64 func7(void)
{
__int64 result; // rax
pthread_mutexattr_t attr; // [rsp+Ch] [rbp-4h] BYREF

tvbase = (pthread_mutex_t *)malloc(0x438uLL);
if ( tvbase )
{
memset(tvbase, 0, 0x438uLL);
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, 1);
pthread_mutex_init(tvbase, &attr);
if ( (unsigned int)create_task(
"Timer",
0,
0x100000uLL,
(void (__fastcall *)(void *))timer_main,
0LL,
(__int64 *)&tvbase[26].__list.__next) )
{
puts("Fail to create timer thread!\r");
result = 0xFFFFFFFFLL;
}
else
{
result = 0LL;
}
}
else
{
puts("Fail to memory allocation!\r");
result = 0xFFFFFFFFLL;
}
return result;
}

original_code:
int timer_base_init(void)
{
    pthread_mutexattr_t lockattr;
    tvbase = (tvec_base *)malloc(sizeof(tvec_base));
    if (tvbase == ((void *)0))
    {
        printf("Fail to memory allocation!\r\n");
        return -1;
    }
    memset(tvbase, 0, sizeof(tvec_base));
    pthread_mutexattr_init(&lockattr);
    pthread_mutexattr_settype(&lockattr, PTHREAD_MUTEX_RECURSIVE);
    pthread_mutex_init(&(tvbase->lock), &lockattr);
    if (create_task("Timer", 0, 0x100000, timer_main, 0, &tvbase->tid))
    {
        printf("Fail to create timer thread!\r\n");
        return -1;
    }
    return 0;
}

canonical_original_code:
int timer_base_init()
{
    union pthread_mutexattr_t lockattr;
    tvbase = (struct _tvec_base *)malloc(sizeof(tvec_base));
    if (tvbase == ((void *)0))
    {
        printf("Fail to memory allocation!\r\n");
        return -1;
    }
    memset(tvbase, 0, sizeof(tvec_base));
    pthread_mutexattr_init(&lockattr);
    pthread_mutexattr_settype(&lockattr, PTHREAD_MUTEX_RECURSIVE);
    pthread_mutex_init(&(tvbase->lock), &lockattr);
    if (create_task("Timer", 0, 0x100000, timer_main, 0, &tvbase->tid))
    {
        printf("Fail to create timer thread!\r\n");
        return -1;
    }
    return 0;
}

variable_types: union pthread_mutexattr_t { char __size[4]; int __align; }

user_defined_types: struct _tvec_base { union pthread_mutex_t lock; unsigned long ticks; struct _hlist_head tv1[-1]; struct _hlist_head tv2[-1]; struct _hlist_head tv3[-1]; struct _hlist_head tv4[-1]; struct _hlist_head tv5[-1]; long tid; }

user_defined_types: union pthread_mutex_t { struct __pthread_mutex_s __data; char __size[40]; 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; }

user_defined_types: struct _hlist_head { struct _hlist_node *first; }

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


decompiled_code:
int __fastcall start_timer(__int64 *a1, int a2, int a3)
{
return start_timer_internal(a1, (1000 * a2 + a3) / 0x64u);
}

canonical_decompiled_code:
int __fastcall func3(__int64 *a1, int a2, int a3)
{
return func2(a1, (1000 * a2 + a3) / 0x64u);
}

original_code:
void start_timer(long timer_id, unsigned int sec, unsigned int msec)
{
    unsigned long expires;
    expires = (sec*1000 + msec)/100;
    return start_timer_internal(timer_id, expires);
}

variable_types:
sec
unsigned int

variable_types:
msec
unsigned int


decompiled_code:
pthread_mutex_t *process_tick(void)
{
pthread_mutex_t *result; // rax
int v1; // [rsp+Ch] [rbp-4h]
int v2; // [rsp+Ch] [rbp-4h]
int v3; // [rsp+Ch] [rbp-4h]
int v4; // [rsp+Ch] [rbp-4h]

pthread_mutex_lock(tvbase);
v1 = tvbase[1].__align & 0x3F;
process_tvec((__int64 **)&tvbase[1].__size[8 * v1 + 8]);
if ( !v1 )
{
v2 = ((unsigned __int64)tvbase[1].__align >> 6) & 0xF;
process_tvec((__int64 **)&tvbase[14] + v2);
if ( !v2 )
{
v3 = ((unsigned __int64)tvbase[1].__align >> 10) & 0xF;
process_tvec((__int64 **)&tvbase[17].__size[8 * v3 + 8]);
if ( !v3 )
{
v4 = ((unsigned __int64)tvbase[1].__align >> 14) & 0xF;
process_tvec((__int64 **)&tvbase[20].__size[8 * v4 + 16]);
if ( !v4 )
process_tvec((__int64 **)&tvbase[23].__list.__prev + (((unsigned __int64)tvbase[1].__align >> 18) & 0xF));
}
}
}
pthread_mutex_unlock(tvbase);
result = tvbase;
++tvbase[1].__align;
return result;
}

canonical_decompiled_code:
pthread_mutex_t *func5(void)
{
pthread_mutex_t *result; // rax
int v1; // [rsp+Ch] [rbp-4h]
int v2; // [rsp+Ch] [rbp-4h]
int v3; // [rsp+Ch] [rbp-4h]
int v4; // [rsp+Ch] [rbp-4h]

pthread_mutex_lock(tvbase);
v1 = tvbase[1].__align & 0x3F;
process_tvec((__int64 **)&tvbase[1].__size[8 * v1 + 8]);
if ( !v1 )
{
v2 = ((unsigned __int64)tvbase[1].__align >> 6) & 0xF;
process_tvec((__int64 **)&tvbase[14] + v2);
if ( !v2 )
{
v3 = ((unsigned __int64)tvbase[1].__align >> 10) & 0xF;
process_tvec((__int64 **)&tvbase[17].__size[8 * v3 + 8]);
if ( !v3 )
{
v4 = ((unsigned __int64)tvbase[1].__align >> 14) & 0xF;
process_tvec((__int64 **)&tvbase[20].__size[8 * v4 + 16]);
if ( !v4 )
process_tvec((__int64 **)&tvbase[23].__list.__prev + (((unsigned __int64)tvbase[1].__align >> 18) & 0xF));
}
}
}
pthread_mutex_unlock(tvbase);
result = tvbase;
++tvbase[1].__align;
return result;
}

original_code:
static void process_tick(void)
{
    int index;
    pthread_mutex_lock(&tvbase->lock);
    index = tvbase->ticks % (1<<6);
    process_tvec(&tvbase->tv1[index]);
    if (!index)
    {
        index = (tvbase->ticks/(1<<(6))) % (1<<4);
        process_tvec(&tvbase->tv2[index]);
        if (!index)
        {
            index = (tvbase->ticks/(1<<(6 +4))) % (1<<4);
            process_tvec(&tvbase->tv3[index]);
            if (!index)
            {
                index = (tvbase->ticks/(1<<(6 +4 +4))) % (1<<4);
                process_tvec(&tvbase->tv4[index]);
                if (!index)
                {
                    index = (tvbase->ticks/(1<<(6 +4 +4 +4))) % (1<<4);
                    process_tvec(&tvbase->tv5[index]);
                }
            }
        }
    }
    pthread_mutex_unlock(&tvbase->lock);
    ++tvbase->ticks;
}

canonical_original_code:
static void process_tick()
{
    int index;
    pthread_mutex_lock(&tvbase->lock);
    index = tvbase->ticks % (1<<6);
    process_tvec(&tvbase->tv1[index]);
    if (!index)
    {
        index = (tvbase->ticks/(1<<(6))) % (1<<4);
        process_tvec(&tvbase->tv2[index]);
        if (!index)
        {
            index = (tvbase->ticks/(1<<(6 +4))) % (1<<4);
            process_tvec(&tvbase->tv3[index]);
            if (!index)
            {
                index = (tvbase->ticks/(1<<(6 +4 +4))) % (1<<4);
                process_tvec(&tvbase->tv4[index]);
                if (!index)
                {
                    index = (tvbase->ticks/(1<<(6 +4 +4 +4))) % (1<<4);
                    process_tvec(&tvbase->tv5[index]);
                }
            }
        }
    }
    pthread_mutex_unlock(&tvbase->lock);
    ++tvbase->ticks;
}

variable_types: index int


decompiled_code:
void __noreturn timer_main()
{
__suseconds_t v0; // r13
__int64 v1; // r12
unsigned __int64 v2; // rbp
__time_t v3; // rbx
unsigned __int64 v4; // rdx
unsigned __int64 v5; // rbx
__time_t v6; // rax
unsigned __int64 v7; // rcx
struct timespec v8; // [rsp+0h] [rbp-58h] BYREF
struct timeval tv; // [rsp+10h] [rbp-48h] BYREF

v0 = 0LL;
v1 = 0LL;
v2 = 0LL;
v3 = 0LL;
v8.tv_sec = 0LL;
v8.tv_nsec = 100000000LL;
while ( 1 )
{
gettimeofday(&tv, 0LL);
if ( !v3 && !v0 )
{
v4 = v2 / 0x186A0;
if ( v1 == v2 / 0x186A0 )
goto LABEL_7;
LABEL_4:
v2 = 0LL;
v5 = v4 - v1;
v1 = 0LL;
goto LABEL_5;
}
v6 = tv.tv_sec - v3;
v7 = tv.tv_usec - v0;
if ( tv.tv_sec - v3 == 2 )
break;
if ( tv.tv_sec - v3 <= 2 )
{
if ( !v6 )
goto LABEL_14;
if ( v6 == 1 )
goto LABEL_13;
}
v7 += 1000000 * v6;
LABEL_14:
v2 += v7;
v5 = v7 / 0x186A0;
v4 = v2 / 0x186A0;
if ( v2 / 0x186A0 != v1 + v7 / 0x186A0 )
goto LABEL_4;
v1 = v2 / 0x186A0;
LABEL_5:
while ( v5 )
{
process_tick();
--v5;
}
LABEL_7:
nanosleep(&v8, 0LL);
v3 = tv.tv_sec;
v0 = tv.tv_usec;
}
v7 += 1000000LL;
LABEL_13:
v7 += 1000000LL;
goto LABEL_14;
}

canonical_decompiled_code:
void __noreturn func6()
{
__suseconds_t v0; // r13
__int64 v1; // r12
unsigned __int64 v2; // rbp
__time_t v3; // rbx
unsigned __int64 v4; // rdx
unsigned __int64 v5; // rbx
__time_t v6; // rax
unsigned __int64 v7; // rcx
struct timespec v8; // [rsp+0h] [rbp-58h] BYREF
struct timeval tv; // [rsp+10h] [rbp-48h] BYREF

v0 = 0LL;
v1 = 0LL;
v2 = 0LL;
v3 = 0LL;
v8.tv_sec = 0LL;
v8.tv_nsec = 100000000LL;
while ( 1 )
{
gettimeofday(&tv, 0LL);
if ( !v3 && !v0 )
{
v4 = v2 / 0x186A0;
if ( v1 == v2 / 0x186A0 )
goto LABEL_7;
LABEL_4:
v2 = 0LL;
v5 = v4 - v1;
v1 = 0LL;
goto LABEL_5;
}
v6 = tv.tv_sec - v3;
v7 = tv.tv_usec - v0;
if ( tv.tv_sec - v3 == 2 )
break;
if ( tv.tv_sec - v3 <= 2 )
{
if ( !v6 )
goto LABEL_14;
if ( v6 == 1 )
goto LABEL_13;
}
v7 += 1000000 * v6;
LABEL_14:
v2 += v7;
v5 = v7 / 0x186A0;
v4 = v2 / 0x186A0;
if ( v2 / 0x186A0 != v1 + v7 / 0x186A0 )
goto LABEL_4;
v1 = v2 / 0x186A0;
LABEL_5:
while ( v5 )
{
func5();
--v5;
}
LABEL_7:
nanosleep(&v8, 0LL);
v3 = tv.tv_sec;
v0 = tv.tv_usec;
}
v7 += 1000000LL;
LABEL_13:
v7 += 1000000LL;
goto LABEL_14;
}

user_defined_types: struct timespec { long tv_sec; long tv_nsec; }

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


decompiled_code:
__int64 __fastcall create_timer(__int64 a1, int a2, __int64 a3, __int64 a4, _QWORD *a5)
{
__int64 v5; // r14
_QWORD *v9; // rax
__int64 v10; // rax

if ( !(a3 | a1) )
return 0xFFFFFFFFLL;
v5 = 0LL;
if ( !a3 )
{
v5 = search_task();
if ( !v5 )
return 0xFFFFFFFFLL;
}
v9 = malloc(0x38uLL);
if ( !v9 )
return 0xFFFFFFFFLL;
hlist_node_init(v9);
*(_QWORD *)(v10 + 24) = v5;
*(_DWORD *)(v10 + 32) = a2;
*(_QWORD *)(v10 + 40) = a3;
*(_QWORD *)(v10 + 48) = a4;
*a5 = v10;
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func7(__int64 a1, int a2, __int64 a3, __int64 a4, _QWORD *a5)
{
__int64 v5; // r14
_QWORD *v9; // rax
__int64 v10; // rax

if ( !(a3 | a1) )
return 0xFFFFFFFFLL;
v5 = 0LL;
if ( !a3 )
{
v5 = search_task();
if ( !v5 )
return 0xFFFFFFFFLL;
}
v9 = malloc(0x38uLL);
if ( !v9 )
return 0xFFFFFFFFLL;
func0(v9);
*(_QWORD *)(v10 + 24) = v5;
*(_DWORD *)(v10 + 32) = a2;
*(_QWORD *)(v10 + 40) = a3;
*(_QWORD *)(v10 + 48) = a4;
*a5 = v10;
return 0LL;
}


canonical_decompiled_code:
__int64 __fastcall func8(void *a1)
{
if ( !a1 )
return 0xFFFFFFFFLL;
free(a1);
return 0LL;
}


decompiled_code:
int __fastcall start_timer_internal(__int64 *a1, __int64 a2)
{
pthread_mutex_lock(tvbase);
a1[2] = tvbase[1].__align + a2;
add_timer(a1);
return pthread_mutex_unlock(tvbase);
}

canonical_decompiled_code:
int __fastcall func9(__int64 *a1, __int64 a2)
{
pthread_mutex_lock(tvbase);
a1[2] = tvbase[1].__align + a2;
func3(a1);
return pthread_mutex_unlock(tvbase);
}


decompiled_code:
int __fastcall stop_timer(__int64 *a1)
{
__int64 v1; // rax

pthread_mutex_lock(tvbase);
if ( a1 )
{
v1 = a1[1];
if ( v1 )
{
if ( *a1 != 3134263569LL && v1 != 3134333474LL )
hlist_node_remove(a1);
}
}
return pthread_mutex_unlock(tvbase);
}

canonical_decompiled_code:
int __fastcall func11(__int64 *a1)
{
__int64 v1; // rax

pthread_mutex_lock(tvbase);
if ( a1 )
{
v1 = a1[1];
if ( v1 )
{
if ( *a1 != 3134263569LL && v1 != 3134333474LL )
func2(a1);
}
}
return pthread_mutex_unlock(tvbase);
}


decompiled_code:
__int64 timer_base_init()
{
__int64 result; // rax
pthread_mutexattr_t attr; // [rsp+Ch] [rbp-1Ch] BYREF

tvbase = (pthread_mutex_t *)calloc(0x438uLL, 1uLL);
if ( tvbase )
{
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, 1);
pthread_mutex_init(tvbase, &attr);
result = create_task("Timer", 0LL, 0x100000LL, timer_main, 0LL, &tvbase[26].__align + 4);
if ( (_DWORD)result )
{
puts("Fail to create timer thread!\r");
result = 0xFFFFFFFFLL;
}
}
else
{
puts("Fail to memory allocation!\r");
result = 0xFFFFFFFFLL;
}
return result;
}

canonical_decompiled_code:
__int64 func12()
{
__int64 result; // rax
pthread_mutexattr_t attr; // [rsp+Ch] [rbp-1Ch] BYREF

tvbase = (pthread_mutex_t *)calloc(0x438uLL, 1uLL);
if ( tvbase )
{
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, 1);
pthread_mutex_init(tvbase, &attr);
result = create_task("Timer", 0LL, 0x100000LL, timer_main, 0LL, &tvbase[26].__align + 4);
if ( (_DWORD)result )
{
puts("Fail to create timer thread!\r");
result = 0xFFFFFFFFLL;
}
}
else
{
puts("Fail to memory allocation!\r");
result = 0xFFFFFFFFLL;
}
return result;
}

user_defined_types: union pthread_mutexattr_t { char __size[4]; int __align; }


decompiled_code:
pthread_mutex_t *process_tick()
{
int v0; // ebp
pthread_mutex_t *result; // rax
__int64 v2; // rbp
__int64 v3; // rbp
__int64 v4; // rbp

pthread_mutex_lock(tvbase);
v0 = tvbase[1].__lock & 0x3F;
process_tvec_isra_0(*(__int64 **)&tvbase[1].__size[8 * v0 + 8]);
if ( !v0 )
{
v2 = ((unsigned __int64)tvbase[1].__align >> 6) & 0xF;
process_tvec_isra_0(*(__int64 **)&tvbase[14].__size[8 * (int)v2]);
if ( !(_DWORD)v2 )
{
v3 = ((unsigned __int64)tvbase[1].__align >> 10) & 0xF;
process_tvec_isra_0(*(__int64 **)&tvbase[17].__size[8 * (int)v3 + 8]);
if ( !(_DWORD)v3 )
{
v4 = ((unsigned __int64)tvbase[1].__align >> 14) & 0xF;
process_tvec_isra_0(*(__int64 **)&tvbase[20].__size[8 * (int)v4 + 16]);
if ( !(_DWORD)v4 )
process_tvec_isra_0(*(__int64 **)&tvbase->__size[8
* (int)((((unsigned __int64)tvbase[1].__align >> 18) & 0xF)
+ 118)]);
}
}
}
pthread_mutex_unlock(tvbase);
result = tvbase;
++tvbase[1].__align;
return result;
}

canonical_decompiled_code:
pthread_mutex_t *func5()
{
int v0; // ebp
pthread_mutex_t *result; // rax
__int64 v2; // rbp
__int64 v3; // rbp
__int64 v4; // rbp

pthread_mutex_lock(tvbase);
v0 = tvbase[1].__lock & 0x3F;
func4(*(__int64 **)&tvbase[1].__size[8 * v0 + 8]);
if ( !v0 )
{
v2 = ((unsigned __int64)tvbase[1].__align >> 6) & 0xF;
func4(*(__int64 **)&tvbase[14].__size[8 * (int)v2]);
if ( !(_DWORD)v2 )
{
v3 = ((unsigned __int64)tvbase[1].__align >> 10) & 0xF;
func4(*(__int64 **)&tvbase[17].__size[8 * (int)v3 + 8]);
if ( !(_DWORD)v3 )
{
v4 = ((unsigned __int64)tvbase[1].__align >> 14) & 0xF;
func4(*(__int64 **)&tvbase[20].__size[8 * (int)v4 + 16]);
if ( !(_DWORD)v4 )
func4(*(__int64 **)&tvbase->__size[8
* (int)((((unsigned __int64)tvbase[1].__align >> 18) & 0xF)
+ 118)]);
}
}
}
pthread_mutex_unlock(tvbase);
result = tvbase;
++tvbase[1].__align;
return result;
}


decompiled_code:
int __fastcall start_timer(__int64 *a1, int a2, int a3)
{
return start_timer_internal(a1, (unsigned int)(a3 + 1000 * a2) / 0x64uLL);
}

canonical_decompiled_code:
int __fastcall func10(__int64 *a1, int a2, int a3)
{
return func9(a1, (unsigned int)(a3 + 1000 * a2) / 0x64uLL);
}

canonical_original_code:
void start_timer(long timer_id, unsigned int sec, unsigned int msec)
{
    unsigned long expires;
    expires = (sec*1000 + msec)/100;
    return start_timer_internal(timer_id, expires);
}


decompiled_code:
__int64 __fastcall search_task(char *s2)
{
pthread_mutex_t *v1; // rbx
__int64 v2; // rbx
__int64 result; // rax

v1 = tsbase;
pthread_mutex_lock(tsbase);
v2 = v1[1].__align;
if ( v2 )
{
while ( strcmp((const char *)(v2 + 148), s2) )
{
v2 = *(_QWORD *)v2;
if ( !v2 )
goto LABEL_6;
}
pthread_mutex_unlock(tsbase);
result = v2;
}
else
{
LABEL_6:
pthread_mutex_unlock(tsbase);
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func3(char *s2)
{
pthread_mutex_t *v1; // rbx
__int64 v2; // rbx
__int64 result; // rax

v1 = tsbase;
pthread_mutex_lock(tsbase);
v2 = v1[1].__align;
if ( v2 )
{
while ( strcmp((const char *)(v2 + 148), s2) )
{
v2 = *(_QWORD *)v2;
if ( !v2 )
goto LABEL_6;
}
pthread_mutex_unlock(tsbase);
result = v2;
}
else
{
LABEL_6:
pthread_mutex_unlock(tsbase);
result = 0LL;
}
return result;
}

original_code:
long search_task(const char *name)
{
    hlist_head *hhead = &tsbase->task_list;
    hlist_node *hnode = ((void *)0);
    task_info *ti = ((void *)0);
    pthread_mutex_lock(&tsbase->lock);
    for (hnode = (hhead)->first; hnode && ({ ti = ((task_info *) ((char *) (hnode) - ((long) &((task_info *)0)->entry))); 1;}); hnode = hnode->next)
    {
        if (!strcmp(ti->name, name))
        {
            pthread_mutex_unlock(&tsbase->lock);
            return (long)ti;
        }
    }
    pthread_mutex_unlock(&tsbase->lock);
    return 0;
}

canonical_original_code:
long search_task(char *name)
{
    struct _hlist_head *hhead = &tsbase->task_list;
    struct _hlist_node *hnode = ((void *)0);
    struct _task_info *ti = ((void *)0);
    pthread_mutex_lock(&tsbase->lock);
    for (hnode = (hhead)->first; hnode && ({ ti = ((struct _task_info *) ((char *) (hnode) - ((long) &((struct _task_info *)0)->entry))); 1;}); hnode = hnode->next)
    {
        if (!strcmp(ti->name, name))
        {
            pthread_mutex_unlock(&tsbase->lock);
            return (long)ti;
        }
    }
    pthread_mutex_unlock(&tsbase->lock);
    return 0;
}

variable_types:
name
char *

variable_types: struct _hlist_head { struct _hlist_node { struct _hlist_node *next; struct _hlist_node **pprevious; } *first; } *

variable_types: struct _task_info { struct _hlist_node { struct _hlist_node *next; struct _hlist_node **pprevious; } entry; unsigned long id; unsigned int priority; unsigned long stack_size; void (*fn)(void *); void *arg; 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; } event_cond; 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; } event_lock; unsigned int events; char name[-1]; } *

return_type: long

user_defined_types: struct _task_info { struct _hlist_node entry; unsigned long id; unsigned int priority; unsigned long stack_size; void (*fn)(void *); void *arg; union pthread_cond_t event_cond; union pthread_mutex_t event_lock; unsigned int events; char name[-1]; }

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


decompiled_code:
__int64 __fastcall create_task(char *a1, __int64 a2, size_t a3, __int64 a4, __int64 a5, _QWORD *a6)
{
_QWORD *v10; // rax
_QWORD *v11; // rbp
__int64 v12; // rax
size_t v13; // rdx
void *(*v14)(void *); // rdx
void *v15; // rcx
unsigned int v16; // er12
struct sched_param param; // [rsp+Ch] [rbp-7Ch] BYREF
pthread_attr_t attr; // [rsp+10h] [rbp-78h] BYREF

if ( search_task(a1) )
{
v16 = -1;
printf("Task %s already exists!\r\n", a1);
}
else
{
v10 = calloc(0xA8uLL, 1uLL);
v11 = v10;
if ( v10 )
{
*a6 = v10;
hlist_node_init(v10);
strncpy((char *)(v12 + 148), a1, v13);
v11[5] = a4;
v11[6] = a5;
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, a3);
v11[4] = a3;
pthread_attr_setinheritsched(&attr, 1);
pthread_attr_setschedpolicy(&attr, 0);
param.__sched_priority = 0;
pthread_attr_setschedparam(&attr, &param);
pthread_cond_init((pthread_cond_t *)(v11 + 7), 0LL);
pthread_mutex_init((pthread_mutex_t *)(v11 + 13), 0LL);
pthread_mutex_lock(tsbase);
hlist_head_add(&tsbase[1].__align, v11);
v16 = pthread_create(v11 + 2, &attr, v14, v15);
if ( v16 )
{
v16 = -1;
hlist_node_remove(v11);
pthread_mutex_unlock(tsbase);
pthread_mutex_destroy((pthread_mutex_t *)(v11 + 13));
pthread_cond_destroy((pthread_cond_t *)(v11 + 7));
free(v11);
}
else
{
pthread_mutex_unlock(tsbase);
}
}
else
{
v16 = -1;
puts("No suffient memory to create a task!\r");
}
}
return v16;
}

canonical_decompiled_code:
__int64 __fastcall func4(char *a1, __int64 a2, size_t a3, __int64 a4, __int64 a5, _QWORD *a6)
{
_QWORD *v10; // rax
_QWORD *v11; // rbp
__int64 v12; // rax
size_t v13; // rdx
void *(*v14)(void *); // rdx
void *v15; // rcx
unsigned int v16; // er12
struct sched_param param; // [rsp+Ch] [rbp-7Ch] BYREF
pthread_attr_t attr; // [rsp+10h] [rbp-78h] BYREF

if ( func3(a1) )
{
v16 = -1;
printf("Task %s already exists!\r\n", a1);
}
else
{
v10 = calloc(0xA8uLL, 1uLL);
v11 = v10;
if ( v10 )
{
*a6 = v10;
func0(v10);
strncpy((char *)(v12 + 148), a1, v13);
v11[5] = a4;
v11[6] = a5;
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, a3);
v11[4] = a3;
pthread_attr_setinheritsched(&attr, 1);
pthread_attr_setschedpolicy(&attr, 0);
param.__sched_priority = 0;
pthread_attr_setschedparam(&attr, &param);
pthread_cond_init((pthread_cond_t *)(v11 + 7), 0LL);
pthread_mutex_init((pthread_mutex_t *)(v11 + 13), 0LL);
pthread_mutex_lock(tsbase);
func1(&tsbase[1].__align, v11);
v16 = pthread_create(v11 + 2, &attr, v14, v15);
if ( v16 )
{
v16 = -1;
func2(v11);
pthread_mutex_unlock(tsbase);
pthread_mutex_destroy((pthread_mutex_t *)(v11 + 13));
pthread_cond_destroy((pthread_cond_t *)(v11 + 7));
free(v11);
}
else
{
pthread_mutex_unlock(tsbase);
}
}
else
{
v16 = -1;
puts("No suffient memory to create a task!\r");
}
}
return v16;
}

original_code:
int create_task(const char *name, unsigned int priority, size_t ssize,
                void (*fn)(void *), void *arg, long *tid)
{
    pthread_attr_t attr;
    struct sched_param param;
    task_info *ti;
    if (search_task(name))
    {
        printf("Task %s already exists!\r\n", name);
        return -1;
    }
    ti = (task_info *)malloc(sizeof(task_info));
    if (ti == ((void *)0))
    {
        printf("No suffient memory to create a task!\r\n");
        return -1;
    }
    memset(ti, 0, sizeof(task_info));
    *tid = (long)ti;
    hlist_node_init(&ti->entry);
    strncpy(ti->name, name, 16);
    ti->fn = fn;
    ti->arg = arg;
    pthread_attr_init(&attr);
    pthread_attr_setstacksize(&attr, ssize);
    ti->stack_size = ssize;
    (void)priority;
    pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
    pthread_attr_setschedpolicy(&attr, 0);
    param.sched_priority = 0;
    pthread_attr_setschedparam(&attr, &param);
    pthread_cond_init(&ti->event_cond, ((void *)0));
    pthread_mutex_init(&ti->event_lock, ((void *)0));
    pthread_mutex_lock(&tsbase->lock);
    hlist_head_add(&tsbase->task_list, &ti->entry);
    if (pthread_create(&ti->id, &attr, wrapper, (void *)ti))
    {
        hlist_node_remove(&ti->entry);
        pthread_mutex_unlock(&tsbase->lock);
        pthread_mutex_destroy(&ti->event_lock);
        pthread_cond_destroy(&ti->event_cond);
        free(ti);
        return -1;
    }
    pthread_mutex_unlock(&tsbase->lock);
    return 0;
}

canonical_original_code:
int create_task(char *name, unsigned int priority, unsigned long ssize, void (*fn)(void *), void *arg, long *tid)
{
    union pthread_attr_t attr;
    struct sched_param param;
    struct _task_info *ti;
    if (search_task(name))
    {
        printf("Task %s already exists!\r\n", name);
        return -1;
    }
    ti = (struct _task_info *)malloc(sizeof(task_info));
    if (ti == ((void *)0))
    {
        printf("No suffient memory to create a task!\r\n");
        return -1;
    }
    memset(ti, 0, sizeof(task_info));
    *tid = (long)ti;
    hlist_node_init(&ti->entry);
    strncpy(ti->name, name, 16);
    ti->fn = fn;
    ti->arg = arg;
    pthread_attr_init(&attr);
    pthread_attr_setstacksize(&attr, ssize);
    ti->stack_size = ssize;
    (void)priority;
    pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
    pthread_attr_setschedpolicy(&attr, 0);
    param.sched_priority = 0;
    pthread_attr_setschedparam(&attr, &param);
    pthread_cond_init(&ti->event_cond, ((void *)0));
    pthread_mutex_init(&ti->event_lock, ((void *)0));
    pthread_mutex_lock(&tsbase->lock);
    hlist_head_add(&tsbase->task_list, &ti->entry);
    if (pthread_create(&ti->id, &attr, wrapper, (void *)ti))
    {
        hlist_node_remove(&ti->entry);
        pthread_mutex_unlock(&tsbase->lock);
        pthread_mutex_destroy(&ti->event_lock);
        pthread_cond_destroy(&ti->event_cond);
        free(ti);
        return -1;
    }
    pthread_mutex_unlock(&tsbase->lock);
    return 0;
}

variable_types:
priority
unsigned int

variable_types:
ssize
unsigned long

variable_types:
fn
void (*)(void *)

variable_types:
tid
long *

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

variable_types: struct sched_param { int sched_priority; }

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]; }


decompiled_code:
void __fastcall del_task(void *ptr)
{
pthread_t v2; // rax
pthread_t v3; // rdi

pthread_mutex_lock(tsbase);
hlist_node_remove((__int64 *)ptr);
pthread_mutex_unlock(tsbase);
pthread_mutex_destroy((pthread_mutex_t *)((char *)ptr + 104));
pthread_cond_destroy((pthread_cond_t *)((char *)ptr + 56));
v2 = pthread_self();
v3 = *((_QWORD *)ptr + 2);
if ( v2 == v3 )
{
pthread_detach(v2);
free(ptr);
pthread_exit(0LL);
}
pthread_cancel(v3);
pthread_join(*((_QWORD *)ptr + 2), 0LL);
free(ptr);
}

canonical_decompiled_code:
void __fastcall func5(void *ptr)
{
pthread_t v2; // rax
pthread_t v3; // rdi

pthread_mutex_lock(tsbase);
func2((__int64 *)ptr);
pthread_mutex_unlock(tsbase);
pthread_mutex_destroy((pthread_mutex_t *)((char *)ptr + 104));
pthread_cond_destroy((pthread_cond_t *)((char *)ptr + 56));
v2 = pthread_self();
v3 = *((_QWORD *)ptr + 2);
if ( v2 == v3 )
{
pthread_detach(v2);
free(ptr);
pthread_exit(0LL);
}
pthread_cancel(v3);
pthread_join(*((_QWORD *)ptr + 2), 0LL);
free(ptr);
}

original_code:
void del_task(long tid)
{
    task_info *ti = (task_info *)tid;
    pthread_mutex_lock(&tsbase->lock);
    hlist_node_remove(&ti->entry);
    pthread_mutex_unlock(&tsbase->lock);
    pthread_mutex_destroy(&ti->event_lock);
    pthread_cond_destroy(&ti->event_cond);
    if (pthread_self() == ti->id)
    {
        pthread_detach(ti->id);
        free(ti);
        pthread_exit(((void *)0));
    }
    else
    {
        pthread_cancel(ti->id);
        pthread_join(ti->id, ((void *)0));
        free(ti);
    }
    return;
}

canonical_original_code:
void del_task(long tid)
{
    struct _task_info *ti = (task_info *)tid;
    pthread_mutex_lock(&tsbase->lock);
    hlist_node_remove(&ti->entry);
    pthread_mutex_unlock(&tsbase->lock);
    pthread_mutex_destroy(&ti->event_lock);
    pthread_cond_destroy(&ti->event_cond);
    if (pthread_self() == ti->id)
    {
        pthread_detach(ti->id);
        free(ti);
        pthread_exit(((void *)0));
    }
    else
    {
        pthread_cancel(ti->id);
        pthread_join(ti->id, ((void *)0));
        free(ti);
    }
    return;
}

variable_types: tid long


wrapper

decompiled_code:
__int64 __fastcall wrapper(void *ptr)
{
(*((void (__fastcall **)(_QWORD))ptr + 5))(*((_QWORD *)ptr + 6));
del_task(ptr);
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func6(void *ptr)
{
(*((void (__fastcall **)(_QWORD))ptr + 5))(*((_QWORD *)ptr + 6));
func5(ptr);
return 0LL;
}

original_code:
static void *wrapper(void *arg)
{
    task_info *ti = (task_info *)arg;
    ti->fn(ti->arg);
    del_task((long)ti);
    return ((void *)0);
}

canonical_original_code:
static void *wrapper(void *arg)
{
    struct _task_info *ti = (task_info *)arg;
    ti->fn(ti->arg);
    del_task((long)ti);
    return ((void *)0);
}

variable_types:
arg
void *

return_type: void *


decompiled_code:
__int64 __fastcall send_event(__int64 a1, int a2)
{
pthread_mutex_lock((pthread_mutex_t *)(a1 + 104));
*(_DWORD *)(a1 + 144) |= a2;
pthread_cond_signal((pthread_cond_t *)(a1 + 56));
pthread_mutex_unlock((pthread_mutex_t *)(a1 + 104));
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func7(__int64 a1, int a2)
{
pthread_mutex_lock((pthread_mutex_t *)(a1 + 104));
*(_DWORD *)(a1 + 144) |= a2;
pthread_cond_signal((pthread_cond_t *)(a1 + 56));
pthread_mutex_unlock((pthread_mutex_t *)(a1 + 104));
return 0LL;
}

original_code:
int send_event(long tid, unsigned int event)
{
    task_info *ti = (task_info *)tid;
    pthread_mutex_lock(&ti->event_lock);
    ti->events |= event;
    pthread_cond_signal(&ti->event_cond);
    pthread_mutex_unlock(&ti->event_lock);
    return 0;
}

canonical_original_code:
int send_event(long tid, unsigned int event)
{
    struct _task_info *ti = (task_info *)tid;
    pthread_mutex_lock(&ti->event_lock);
    ti->events |= event;
    pthread_cond_signal(&ti->event_cond);
    pthread_mutex_unlock(&ti->event_lock);
    return 0;
}

variable_types:
event
unsigned int


decompiled_code:
__int64 __fastcall recv_event(__int64 a1, int a2, int a3, int *a4)
{
pthread_mutex_t *i; // r15
int v7; // eax
unsigned int v8; // er12

for ( i = (pthread_mutex_t *)(a1 + 104); ; pthread_mutex_unlock(i) )
{
pthread_mutex_lock(i);
v7 = a2 & *(_DWORD *)(a1 + 144);
*a4 = v7;
*(_DWORD *)(a1 + 144) &= ~v7;
if ( *a4 )
{
v8 = 0;
goto LABEL_6;
}
if ( !a3 )
break;
pthread_cond_wait((pthread_cond_t *)(a1 + 56), i);
}
v8 = -1;
LABEL_6:
pthread_mutex_unlock(i);
return v8;
}

canonical_decompiled_code:
__int64 __fastcall func8(__int64 a1, int a2, int a3, int *a4)
{
pthread_mutex_t *i; // r15
int v7; // eax
unsigned int v8; // er12

for ( i = (pthread_mutex_t *)(a1 + 104); ; pthread_mutex_unlock(i) )
{
pthread_mutex_lock(i);
v7 = a2 & *(_DWORD *)(a1 + 144);
*a4 = v7;
*(_DWORD *)(a1 + 144) &= ~v7;
if ( *a4 )
{
v8 = 0;
goto LABEL_6;
}
if ( !a3 )
break;
pthread_cond_wait((pthread_cond_t *)(a1 + 56), i);
}
v8 = -1;
LABEL_6:
pthread_mutex_unlock(i);
return v8;
}

original_code:
int recv_event(long tid, unsigned int interest_events, unsigned int flag, unsigned int *recv_events)
{
    task_info *ti = (task_info *)tid;
    int ret = 0;
    do
    {
        pthread_mutex_lock(&ti->event_lock);
        *recv_events = ti->events & interest_events;
        ti->events &= ~(*recv_events);
        if (*recv_events)
            break;
        if (flag == 0)
        {
            ret = -1;
            break;
        }
        pthread_cond_wait(&ti->event_cond, &ti->event_lock);
        pthread_mutex_unlock(&ti->event_lock);
    } while(1);
    pthread_mutex_unlock(&ti->event_lock);
    return ret;
}

canonical_original_code:
int recv_event(long tid, unsigned int interest_events, unsigned int flag, unsigned int *recv_events)
{
    struct _task_info *ti = (task_info *)tid;
    int ret = 0;
    do
    {
        pthread_mutex_lock(&ti->event_lock);
        *recv_events = ti->events & interest_events;
        ti->events &= ~(*recv_events);
        if (*recv_events)
            break;
        if (flag == 0)
        {
            ret = -1;
            break;
        }
        pthread_cond_wait(&ti->event_cond, &ti->event_lock);
        pthread_mutex_unlock(&ti->event_lock);
    } while(1);
    pthread_mutex_unlock(&ti->event_lock);
    return ret;
}

variable_types:
flag
unsigned int

variable_types: ret int


decompiled_code:
__int64 task_base_init()
{
pthread_mutex_t *v0; // rax
__int64 result; // rax

v0 = (pthread_mutex_t *)calloc(0x30uLL, 1uLL);
tsbase = v0;
if ( v0 )
{
pthread_mutex_init(v0, 0LL);
tsbase[1].__align = 0LL;
result = 0LL;
}
else
{
puts("Fail to memory allocation!\r");
result = 0xFFFFFFFFLL;
}
return result;
}

canonical_decompiled_code:
__int64 func9()
{
pthread_mutex_t *v0; // rax
__int64 result; // rax

v0 = (pthread_mutex_t *)calloc(0x30uLL, 1uLL);
tsbase = v0;
if ( v0 )
{
pthread_mutex_init(v0, 0LL);
tsbase[1].__align = 0LL;
result = 0LL;
}
else
{
puts("Fail to memory allocation!\r");
result = 0xFFFFFFFFLL;
}
return result;
}

original_code:
int task_base_init(void)
{
    tsbase = (task_base *)malloc(sizeof(task_base));
    if (tsbase == ((void *)0))
    {
        printf("Fail to memory allocation!\r\n");
        return -1;
    }
    memset(tsbase, 0, sizeof(task_base));
    pthread_mutex_init(&tsbase->lock, ((void *)0));
    ((&tsbase->task_list)->first = ((void *)0));
    return 0;
}

canonical_original_code:
int task_base_init()
{
    tsbase = (struct _task_base *)malloc(sizeof(task_base));
    if (tsbase == ((void *)0))
    {
        printf("Fail to memory allocation!\r\n");
        return -1;
    }
    memset(tsbase, 0, sizeof(task_base));
    pthread_mutex_init(&tsbase->lock, ((void *)0));
    ((&tsbase->task_list)->first = ((void *)0));
    return 0;
}

user_defined_types: struct _task_base { union pthread_mutex_t lock; struct _hlist_head task_list; }


decompiled_code:
const char *__fastcall search_task(const char *a1)
{
char v1; // al
const char **v3; // [rsp+18h] [rbp-18h]
const char *v4; // [rsp+20h] [rbp-10h]
const char *i; // [rsp+28h] [rbp-8h]

v3 = (const char **)&tsbase[1];
v4 = 0LL;
pthread_mutex_lock(tsbase);
for ( i = *v3; ; i = *(const char **)i )
{
if ( i )
{
v4 = i;
v1 = 1;
}
else
{
v1 = 0;
}
if ( !v1 )
break;
if ( !strcmp(v4 + 148, a1) )
{
pthread_mutex_unlock(tsbase);
return v4;
}
}
pthread_mutex_unlock(tsbase);
return 0LL;
}

canonical_decompiled_code:
const char *__fastcall func0(const char *a1)
{
char v1; // al
const char **v3; // [rsp+18h] [rbp-18h]
const char *v4; // [rsp+20h] [rbp-10h]
const char *i; // [rsp+28h] [rbp-8h]

v3 = (const char **)&tsbase[1];
v4 = 0LL;
pthread_mutex_lock(tsbase);
for ( i = *v3; ; i = *(const char **)i )
{
if ( i )
{
v4 = i;
v1 = 1;
}
else
{
v1 = 0;
}
if ( !v1 )
break;
if ( !strcmp(v4 + 148, a1) )
{
pthread_mutex_unlock(tsbase);
return v4;
}
}
pthread_mutex_unlock(tsbase);
return 0LL;
}

variable_types: struct _hlist_node { struct _hlist_node *next; struct _hlist_node **pprevious; } *


decompiled_code:
void *__fastcall wrapper(void *a1)
{
(*((void (__fastcall **)(_QWORD))a1 + 5))(*((_QWORD *)a1 + 6));
del_task((__int64)a1);
return 0LL;
}

canonical_decompiled_code:
void *__fastcall func1(void *a1)
{
(*((void (__fastcall **)(_QWORD))a1 + 5))(*((_QWORD *)a1 + 6));
func3((__int64)a1);
return 0LL;
}


decompiled_code:
__int64 __fastcall create_task(const char *a1, unsigned int a2, size_t a3, void (__fastcall *a4)(void *), void *a5, __int64 *a6)
{
__int64 result; // rax
struct sched_param param; // [rsp+3Ch] [rbp-44h] BYREF
pthread_attr_t attr; // [rsp+40h] [rbp-40h] BYREF
void *s; // [rsp+78h] [rbp-8h]

if ( search_task(a1) )
{
printf("Task %s already exists!\r\n", a1);
result = 0xFFFFFFFFLL;
}
else
{
s = malloc(0xA8uLL);
if ( s )
{
memset(s, 0, 0xA8uLL);
*a6 = (__int64)s;
hlist_node_init(s);
strncpy((char *)s + 148, a1, 0x10uLL);
*((_QWORD *)s + 5) = a4;
*((_QWORD *)s + 6) = a5;
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, a3);
*((_QWORD *)s + 4) = a3;
pthread_attr_setinheritsched(&attr, 1);
pthread_attr_setschedpolicy(&attr, 0);
param.__sched_priority = 0;
pthread_attr_setschedparam(&attr, &param);
pthread_cond_init((pthread_cond_t *)((char *)s + 56), 0LL);
pthread_mutex_init((pthread_mutex_t *)((char *)s + 104), 0LL);
pthread_mutex_lock(tsbase);
hlist_head_add(&tsbase[1].__align, (__int64 *)s);
if ( pthread_create((pthread_t *)s + 2, &attr, wrapper, s) )
{
hlist_node_remove(s);
pthread_mutex_unlock(tsbase);
pthread_mutex_destroy((pthread_mutex_t *)((char *)s + 104));
pthread_cond_destroy((pthread_cond_t *)((char *)s + 56));
free(s);
result = 0xFFFFFFFFLL;
}
else
{
pthread_mutex_unlock(tsbase);
result = 0LL;
}
}
else
{
puts("No suffient memory to create a task!\r");
result = 0xFFFFFFFFLL;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(const char *a1, unsigned int a2, size_t a3, void (__fastcall *a4)(void *), void *a5, __int64 *a6)
{
__int64 result; // rax
struct sched_param param; // [rsp+3Ch] [rbp-44h] BYREF
pthread_attr_t attr; // [rsp+40h] [rbp-40h] BYREF
void *s; // [rsp+78h] [rbp-8h]

if ( func0(a1) )
{
printf("Task %s already exists!\r\n", a1);
result = 0xFFFFFFFFLL;
}
else
{
s = malloc(0xA8uLL);
if ( s )
{
memset(s, 0, 0xA8uLL);
*a6 = (__int64)s;
hlist_node_init(s);
strncpy((char *)s + 148, a1, 0x10uLL);
*((_QWORD *)s + 5) = a4;
*((_QWORD *)s + 6) = a5;
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, a3);
*((_QWORD *)s + 4) = a3;
pthread_attr_setinheritsched(&attr, 1);
pthread_attr_setschedpolicy(&attr, 0);
param.__sched_priority = 0;
pthread_attr_setschedparam(&attr, &param);
pthread_cond_init((pthread_cond_t *)((char *)s + 56), 0LL);
pthread_mutex_init((pthread_mutex_t *)((char *)s + 104), 0LL);
pthread_mutex_lock(tsbase);
hlist_head_add(&tsbase[1].__align, (__int64 *)s);
if ( pthread_create((pthread_t *)s + 2, &attr, wrapper, s) )
{
hlist_node_remove(s);
pthread_mutex_unlock(tsbase);
pthread_mutex_destroy((pthread_mutex_t *)((char *)s + 104));
pthread_cond_destroy((pthread_cond_t *)((char *)s + 56));
free(s);
result = 0xFFFFFFFFLL;
}
else
{
pthread_mutex_unlock(tsbase);
result = 0LL;
}
}
else
{
puts("No suffient memory to create a task!\r");
result = 0xFFFFFFFFLL;
}
}
return result;
}

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

user_defined_types: struct sched_param { int sched_priority; }


decompiled_code:
void __fastcall del_task(__int64 a1)
{
pthread_mutex_lock(tsbase);
hlist_node_remove((_QWORD *)a1);
pthread_mutex_unlock(tsbase);
pthread_mutex_destroy((pthread_mutex_t *)(a1 + 104));
pthread_cond_destroy((pthread_cond_t *)(a1 + 56));
if ( pthread_self() == *(_QWORD *)(a1 + 16) )
{
pthread_detach(*(_QWORD *)(a1 + 16));
free((void *)a1);
pthread_exit(0LL);
}
pthread_cancel(*(_QWORD *)(a1 + 16));
pthread_join(*(_QWORD *)(a1 + 16), 0LL);
free((void *)a1);
}

canonical_decompiled_code:
void __fastcall func3(__int64 a1)
{
pthread_mutex_lock(tsbase);
hlist_node_remove((_QWORD *)a1);
pthread_mutex_unlock(tsbase);
pthread_mutex_destroy((pthread_mutex_t *)(a1 + 104));
pthread_cond_destroy((pthread_cond_t *)(a1 + 56));
if ( pthread_self() == *(_QWORD *)(a1 + 16) )
{
pthread_detach(*(_QWORD *)(a1 + 16));
free((void *)a1);
pthread_exit(0LL);
}
pthread_cancel(*(_QWORD *)(a1 + 16));
pthread_join(*(_QWORD *)(a1 + 16), 0LL);
free((void *)a1);
}


canonical_decompiled_code:
__int64 __fastcall func4(__int64 a1, int a2)
{
pthread_mutex_lock((pthread_mutex_t *)(a1 + 104));
*(_DWORD *)(a1 + 144) |= a2;
pthread_cond_signal((pthread_cond_t *)(a1 + 56));
pthread_mutex_unlock((pthread_mutex_t *)(a1 + 104));
return 0LL;
}


decompiled_code:
__int64 __fastcall recv_event(__int64 a1, int a2, int a3, unsigned int *a4)
{
unsigned int v7; // [rsp+2Ch] [rbp-4h]

v7 = 0;
while ( 1 )
{
pthread_mutex_lock((pthread_mutex_t *)(a1 + 104));
*a4 = a2 & *(_DWORD *)(a1 + 144);
*(_DWORD *)(a1 + 144) &= ~*a4;
if ( *a4 )
break;
if ( !a3 )
{
v7 = -1;
break;
}
pthread_cond_wait((pthread_cond_t *)(a1 + 56), (pthread_mutex_t *)(a1 + 104));
pthread_mutex_unlock((pthread_mutex_t *)(a1 + 104));
}
pthread_mutex_unlock((pthread_mutex_t *)(a1 + 104));
return v7;
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1, int a2, int a3, unsigned int *a4)
{
unsigned int v7; // [rsp+2Ch] [rbp-4h]

v7 = 0;
while ( 1 )
{
pthread_mutex_lock((pthread_mutex_t *)(a1 + 104));
*a4 = a2 & *(_DWORD *)(a1 + 144);
*(_DWORD *)(a1 + 144) &= ~*a4;
if ( *a4 )
break;
if ( !a3 )
{
v7 = -1;
break;
}
pthread_cond_wait((pthread_cond_t *)(a1 + 56), (pthread_mutex_t *)(a1 + 104));
pthread_mutex_unlock((pthread_mutex_t *)(a1 + 104));
}
pthread_mutex_unlock((pthread_mutex_t *)(a1 + 104));
return v7;
}


decompiled_code:
__int64 task_base_init(void)
{
__int64 result; // rax

tsbase = (pthread_mutex_t *)malloc(0x30uLL);
if ( tsbase )
{
memset(tsbase, 0, 0x30uLL);
pthread_mutex_init(tsbase, 0LL);
tsbase[1].__align = 0LL;
result = 0LL;
}
else
{
puts("Fail to memory allocation!\r");
result = 0xFFFFFFFFLL;
}
return result;
}

canonical_decompiled_code:
__int64 func6(void)
{
__int64 result; // rax

tsbase = (pthread_mutex_t *)malloc(0x30uLL);
if ( tsbase )
{
memset(tsbase, 0, 0x30uLL);
pthread_mutex_init(tsbase, 0LL);
tsbase[1].__align = 0LL;
result = 0LL;
}
else
{
puts("Fail to memory allocation!\r");
result = 0xFFFFFFFFLL;
}
return result;
}


decompiled_code:
const char *__fastcall search_queue(const char *a1)
{
char v1; // al
const char **v3; // [rsp+18h] [rbp-18h]
const char *v4; // [rsp+20h] [rbp-10h]
const char *i; // [rsp+28h] [rbp-8h]

v3 = (const char **)&qbase[1];
v4 = 0LL;
pthread_mutex_lock(qbase);
for ( i = *v3; ; i = *(const char **)i )
{
if ( i )
{
v4 = i;
v1 = 1;
}
else
{
v1 = 0;
}
if ( !v1 )
break;
if ( !strcmp(v4 + 136, a1) )
{
pthread_mutex_unlock(qbase);
return v4;
}
}
pthread_mutex_unlock(qbase);
return 0LL;
}

canonical_decompiled_code:
const char *__fastcall func0(const char *a1)
{
char v1; // al
const char **v3; // [rsp+18h] [rbp-18h]
const char *v4; // [rsp+20h] [rbp-10h]
const char *i; // [rsp+28h] [rbp-8h]

v3 = (const char **)&qbase[1];
v4 = 0LL;
pthread_mutex_lock(qbase);
for ( i = *v3; ; i = *(const char **)i )
{
if ( i )
{
v4 = i;
v1 = 1;
}
else
{
v1 = 0;
}
if ( !v1 )
break;
if ( !strcmp(v4 + 136, a1) )
{
pthread_mutex_unlock(qbase);
return v4;
}
}
pthread_mutex_unlock(qbase);
return 0LL;
}

original_code:
static long search_queue(const char *name)
{
    hlist_head *hhead = &qbase->queue_list;
    hlist_node *hnode = ((void *)0);
    queue_info *qi = ((void *)0);
    pthread_mutex_lock(&qbase->lock);
    for (hnode = (hhead)->first; hnode && ({ qi = ((queue_info *) ((char *) (hnode) - ((long) &((queue_info *)0)->entry))); 1;}); hnode = hnode->next)
    {
        if (!strcmp(qi->name, name))
        {
            pthread_mutex_unlock(&qbase->lock);
            return (long)qi;
        }
    }
    pthread_mutex_unlock(&qbase->lock);
    return 0;
}

canonical_original_code:
static long search_queue(char *name)
{
    struct _hlist_head *hhead = &qbase->queue_list;
    struct _hlist_node *hnode = ((void *)0);
    struct _queue_info *qi = ((void *)0);
    pthread_mutex_lock(&qbase->lock);
    for (hnode = (hhead)->first; hnode && ({ qi = ((struct _queue_info *) ((char *) (hnode) - ((long) &((struct _queue_info *)0)->entry))); 1;}); hnode = hnode->next)
    {
        if (!strcmp(qi->name, name))
        {
            pthread_mutex_unlock(&qbase->lock);
            return (long)qi;
        }
    }
    pthread_mutex_unlock(&qbase->lock);
    return 0;
}

variable_types: struct _queue_info { struct _hlist_node { struct _hlist_node *next; struct _hlist_node **pprevious; } entry; unsigned int msg_len; unsigned int msg_num; char *buffer; unsigned int write_index; unsigned int read_index; unsigned int avail_num; 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; } cond; 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; } lock; char name[-1]; } *

user_defined_types: struct _queue_info { struct _hlist_node entry; unsigned int msg_len; unsigned int msg_num; char *buffer; unsigned int write_index; unsigned int read_index; unsigned int avail_num; union pthread_cond_t cond; union pthread_mutex_t lock; char name[-1]; }


decompiled_code:
__int64 __fastcall create_queue(const char *a1, int a2, int a3, __int64 *a4)
{
__int64 result; // rax
char *s; // [rsp+28h] [rbp-8h]

if ( search_queue(a1) )
{
printf("Queue %s already exists!\r\n", a1);
result = 0xFFFFFFFFLL;
}
else
{
s = (char *)malloc(0xA0uLL);
if ( s
&& (memset(s, 0, 0xA0uLL),
*a4 = (__int64)s,
hlist_node_init(s),
strncpy(s + 136, a1, 0x10uLL),
*((_DWORD *)s + 4) = a2,
*((_DWORD *)s + 5) = a3,
(*((_QWORD *)s + 3) = malloc((unsigned int)(a3 * a2))) != 0LL) )
{
pthread_cond_init((pthread_cond_t *)s + 1, 0LL);
pthread_mutex_init((pthread_mutex_t *)(s + 96), 0LL);
pthread_mutex_lock(qbase);
hlist_head_add(&qbase[1].__align, (__int64 *)s);
pthread_mutex_unlock(qbase);
result = 0LL;
}
else
{
puts("No suffient memory to create a message queue!\r");
result = 0xFFFFFFFFLL;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(const char *a1, int a2, int a3, __int64 *a4)
{
__int64 result; // rax
char *s; // [rsp+28h] [rbp-8h]

if ( func0(a1) )
{
printf("Queue %s already exists!\r\n", a1);
result = 0xFFFFFFFFLL;
}
else
{
s = (char *)malloc(0xA0uLL);
if ( s
&& (memset(s, 0, 0xA0uLL),
*a4 = (__int64)s,
hlist_node_init(s),
strncpy(s + 136, a1, 0x10uLL),
*((_DWORD *)s + 4) = a2,
*((_DWORD *)s + 5) = a3,
(*((_QWORD *)s + 3) = malloc((unsigned int)(a3 * a2))) != 0LL) )
{
pthread_cond_init((pthread_cond_t *)s + 1, 0LL);
pthread_mutex_init((pthread_mutex_t *)(s + 96), 0LL);
pthread_mutex_lock(qbase);
hlist_head_add(&qbase[1].__align, (__int64 *)s);
pthread_mutex_unlock(qbase);
result = 0LL;
}
else
{
puts("No suffient memory to create a message queue!\r");
result = 0xFFFFFFFFLL;
}
}
return result;
}

original_code:
int create_queue(const char *name, unsigned int msg_len, unsigned int msg_num, long *qid)
{
    queue_info *qi;
    if (search_queue(name))
    {
        printf("Queue %s already exists!\r\n", name);
        return -1;
    }
    qi = (queue_info *)malloc(sizeof(queue_info));
    if (qi == ((void *)0))
    {
        printf("No suffient memory to create a message queue!\r\n");
        return -1;
    }
    memset(qi, 0, sizeof(queue_info));
    *qid = (long)qi;
    hlist_node_init(&qi->entry);
    strncpy(qi->name, name, 16);
    qi->msg_len = msg_len;
    qi->msg_num = msg_num;
    if ((qi->buffer = (char *)malloc(msg_len*msg_num)) == ((void *)0))
    {
        printf("No suffient memory to create a message queue!\r\n");
        return -1;
    }
    pthread_cond_init(&qi->cond, ((void *)0));
    pthread_mutex_init(&qi->lock, ((void *)0));
    pthread_mutex_lock(&qbase->lock);
    hlist_head_add(&qbase->queue_list, &qi->entry);
    pthread_mutex_unlock(&qbase->lock);
    return 0;
}

canonical_original_code:
int create_queue(char *name, unsigned int msg_len, unsigned int msg_num, long *qid)
{
    struct _queue_info *qi;
    if (search_queue(name))
    {
        printf("Queue %s already exists!\r\n", name);
        return -1;
    }
    qi = (struct _queue_info *)malloc(sizeof(queue_info));
    if (qi == ((void *)0))
    {
        printf("No suffient memory to create a message queue!\r\n");
        return -1;
    }
    memset(qi, 0, sizeof(queue_info));
    *qid = (long)qi;
    hlist_node_init(&qi->entry);
    strncpy(qi->name, name, 16);
    qi->msg_len = msg_len;
    qi->msg_num = msg_num;
    if ((qi->buffer = (char *)malloc(msg_len*msg_num)) == ((void *)0))
    {
        printf("No suffient memory to create a message queue!\r\n");
        return -1;
    }
    pthread_cond_init(&qi->cond, ((void *)0));
    pthread_mutex_init(&qi->lock, ((void *)0));
    pthread_mutex_lock(&qbase->lock);
    hlist_head_add(&qbase->queue_list, &qi->entry);
    pthread_mutex_unlock(&qbase->lock);
    return 0;
}

variable_types:
qid
long *


decompiled_code:
void __fastcall del_queue(__int64 a1)
{
pthread_mutex_lock(qbase);
hlist_node_remove((_QWORD *)a1);
pthread_mutex_unlock(qbase);
pthread_mutex_destroy((pthread_mutex_t *)(a1 + 96));
pthread_cond_destroy((pthread_cond_t *)(a1 + 48));
free(*(void **)(a1 + 24));
free((void *)a1);
}

canonical_decompiled_code:
void __fastcall func2(__int64 a1)
{
pthread_mutex_lock(qbase);
hlist_node_remove((_QWORD *)a1);
pthread_mutex_unlock(qbase);
pthread_mutex_destroy((pthread_mutex_t *)(a1 + 96));
pthread_cond_destroy((pthread_cond_t *)(a1 + 48));
free(*(void **)(a1 + 24));
free((void *)a1);
}

original_code:
void del_queue(long qid)
{
    queue_info *qi = (queue_info *)qid;
    pthread_mutex_lock(&qbase->lock);
    hlist_node_remove(&qi->entry);
    pthread_mutex_unlock(&qbase->lock);
    pthread_mutex_destroy(&qi->lock);
    pthread_cond_destroy(&qi->cond);
    free(qi->buffer);
    free(qi);
    return;
}

canonical_original_code:
void del_queue(long qid)
{
    struct _queue_info *qi = (queue_info *)qid;
    pthread_mutex_lock(&qbase->lock);
    hlist_node_remove(&qi->entry);
    pthread_mutex_unlock(&qbase->lock);
    pthread_mutex_destroy(&qi->lock);
    pthread_cond_destroy(&qi->cond);
    free(qi->buffer);
    free(qi);
    return;
}

variable_types: qid long


decompiled_code:
__int64 __fastcall queue_send(__int64 a1, char *a2, unsigned int a3)
{
__int64 result; // rax

if ( a3 > *(_DWORD *)(a1 + 16) )
return 0xFFFFFFFFLL;
pthread_mutex_lock((pthread_mutex_t *)(a1 + 96));
if ( *(_DWORD *)(a1 + 40) < *(_DWORD *)(a1 + 20) )
{
memcpy((void *)(*(_QWORD *)(a1 + 24) + (unsigned int)(*(_DWORD *)(a1 + 32) * *(_DWORD *)(a1 + 16))), a2, a3);
*(_DWORD *)(a1 + 32) = (unsigned int)(*(_DWORD *)(a1 + 32) + 1) % *(_DWORD *)(a1 + 20);
++*(_DWORD *)(a1 + 40);
pthread_cond_signal((pthread_cond_t *)(a1 + 48));
pthread_mutex_unlock((pthread_mutex_t *)(a1 + 96));
result = 0LL;
}
else
{
pthread_mutex_unlock((pthread_mutex_t *)(a1 + 96));
result = 0xFFFFFFFFLL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1, char *a2, unsigned int a3)
{
__int64 result; // rax

if ( a3 > *(_DWORD *)(a1 + 16) )
return 0xFFFFFFFFLL;
pthread_mutex_lock((pthread_mutex_t *)(a1 + 96));
if ( *(_DWORD *)(a1 + 40) < *(_DWORD *)(a1 + 20) )
{
memcpy((void *)(*(_QWORD *)(a1 + 24) + (unsigned int)(*(_DWORD *)(a1 + 32) * *(_DWORD *)(a1 + 16))), a2, a3);
*(_DWORD *)(a1 + 32) = (unsigned int)(*(_DWORD *)(a1 + 32) + 1) % *(_DWORD *)(a1 + 20);
++*(_DWORD *)(a1 + 40);
pthread_cond_signal((pthread_cond_t *)(a1 + 48));
pthread_mutex_unlock((pthread_mutex_t *)(a1 + 96));
result = 0LL;
}
else
{
pthread_mutex_unlock((pthread_mutex_t *)(a1 + 96));
result = 0xFFFFFFFFLL;
}
return result;
}

original_code:
int queue_send(long qid, char *msg_buf, unsigned int msg_len)
{
    queue_info *qi = (queue_info *)qid;
    char *data_ptr;
    if (msg_len > qi->msg_len)
        return -1;
    pthread_mutex_lock(&qi->lock);
    if (qi->avail_num >= qi->msg_num)
    {
        pthread_mutex_unlock(&qi->lock);
        return -1;
    }
    data_ptr = qi->buffer + qi->write_index*qi->msg_len;
    memcpy(data_ptr, msg_buf, msg_len);
    qi->write_index = (qi->write_index + 1) % qi->msg_num;
    qi->avail_num++;
    pthread_cond_signal(&qi->cond);
    pthread_mutex_unlock(&qi->lock);
    return 0;
}

canonical_original_code:
int queue_send(long qid, char *msg_buf, unsigned int msg_len)
{
    struct _queue_info *qi = (queue_info *)qid;
    char *data_ptr;
    if (msg_len > qi->msg_len)
        return -1;
    pthread_mutex_lock(&qi->lock);
    if (qi->avail_num >= qi->msg_num)
    {
        pthread_mutex_unlock(&qi->lock);
        return -1;
    }
    data_ptr = qi->buffer + qi->write_index*qi->msg_len;
    memcpy(data_ptr, msg_buf, msg_len);
    qi->write_index = (qi->write_index + 1) % qi->msg_num;
    qi->avail_num++;
    pthread_cond_signal(&qi->cond);
    pthread_mutex_unlock(&qi->lock);
    return 0;
}


decompiled_code:
__int64 __fastcall queue_receive(__int64 a1, char *a2, unsigned int a3, int a4)
{
unsigned int n; // [rsp+Ch] [rbp-54h]
struct timeval tv; // [rsp+20h] [rbp-40h] BYREF
struct timespec abstime; // [rsp+30h] [rbp-30h] BYREF
void *src; // [rsp+40h] [rbp-20h]
int v10; // [rsp+4Ch] [rbp-14h]
__int64 v11; // [rsp+50h] [rbp-10h]
unsigned int v12; // [rsp+58h] [rbp-8h]
unsigned int v13; // [rsp+5Ch] [rbp-4h]

n = a3;
v11 = a1;
v13 = 0;
v12 = 0;
if ( a3 > *(_DWORD *)(a1 + 16) )
n = *(_DWORD *)(v11 + 16);
pthread_mutex_lock((pthread_mutex_t *)(v11 + 96));
if ( a4 )
{
if ( a4 == -1 )
{
while ( !*(_DWORD *)(v11 + 40) )
pthread_cond_wait((pthread_cond_t *)(v11 + 48), (pthread_mutex_t *)(v11 + 96));
}
else if ( !*(_DWORD *)(v11 + 40) )
{
gettimeofday(&tv, 0LL);
v12 = LODWORD(tv.tv_usec) + 1000 * a4;
if ( v12 > 0xF4240 )
{
v13 = v12 / 0xF4240;
v12 %= 0xF4240u;
}
abstime.tv_sec = tv.tv_sec + v13;
abstime.tv_nsec = 1000 * v12;
v10 = pthread_cond_timedwait((pthread_cond_t *)(v11 + 48), (pthread_mutex_t *)(v11 + 96), &abstime);
if ( v10 == 110 )
{
pthread_mutex_unlock((pthread_mutex_t *)(v11 + 96));
return 0xFFFFFFFFLL;
}
}
}
else if ( !*(_DWORD *)(v11 + 40) )
{
pthread_mutex_unlock((pthread_mutex_t *)(v11 + 96));
return 0xFFFFFFFFLL;
}
src = (void *)(*(_QWORD *)(v11 + 24) + (unsigned int)(*(_DWORD *)(v11 + 36) * *(_DWORD *)(v11 + 16)));
memcpy(a2, src, n);
*(_DWORD *)(v11 + 36) = (unsigned int)(*(_DWORD *)(v11 + 36) + 1) % *(_DWORD *)(v11 + 20);
--*(_DWORD *)(v11 + 40);
pthread_mutex_unlock((pthread_mutex_t *)(v11 + 96));
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 a1, char *a2, unsigned int a3, int a4)
{
unsigned int n; // [rsp+Ch] [rbp-54h]
struct timeval tv; // [rsp+20h] [rbp-40h] BYREF
struct timespec abstime; // [rsp+30h] [rbp-30h] BYREF
void *src; // [rsp+40h] [rbp-20h]
int v10; // [rsp+4Ch] [rbp-14h]
__int64 v11; // [rsp+50h] [rbp-10h]
unsigned int v12; // [rsp+58h] [rbp-8h]
unsigned int v13; // [rsp+5Ch] [rbp-4h]

n = a3;
v11 = a1;
v13 = 0;
v12 = 0;
if ( a3 > *(_DWORD *)(a1 + 16) )
n = *(_DWORD *)(v11 + 16);
pthread_mutex_lock((pthread_mutex_t *)(v11 + 96));
if ( a4 )
{
if ( a4 == -1 )
{
while ( !*(_DWORD *)(v11 + 40) )
pthread_cond_wait((pthread_cond_t *)(v11 + 48), (pthread_mutex_t *)(v11 + 96));
}
else if ( !*(_DWORD *)(v11 + 40) )
{
gettimeofday(&tv, 0LL);
v12 = LODWORD(tv.tv_usec) + 1000 * a4;
if ( v12 > 0xF4240 )
{
v13 = v12 / 0xF4240;
v12 %= 0xF4240u;
}
abstime.tv_sec = tv.tv_sec + v13;
abstime.tv_nsec = 1000 * v12;
v10 = pthread_cond_timedwait((pthread_cond_t *)(v11 + 48), (pthread_mutex_t *)(v11 + 96), &abstime);
if ( v10 == 110 )
{
pthread_mutex_unlock((pthread_mutex_t *)(v11 + 96));
return 0xFFFFFFFFLL;
}
}
}
else if ( !*(_DWORD *)(v11 + 40) )
{
pthread_mutex_unlock((pthread_mutex_t *)(v11 + 96));
return 0xFFFFFFFFLL;
}
src = (void *)(*(_QWORD *)(v11 + 24) + (unsigned int)(*(_DWORD *)(v11 + 36) * *(_DWORD *)(v11 + 16)));
memcpy(a2, src, n);
*(_DWORD *)(v11 + 36) = (unsigned int)(*(_DWORD *)(v11 + 36) + 1) % *(_DWORD *)(v11 + 20);
--*(_DWORD *)(v11 + 40);
pthread_mutex_unlock((pthread_mutex_t *)(v11 + 96));
return 0LL;
}

original_code:
int queue_receive(long qid, char *msg_buf, unsigned int msg_len, int timeout)
{
    queue_info *qi = (queue_info *)qid;
    struct timespec ts;
    struct timeval tp;
    unsigned int sec = 0 , usec = 0;
    char *data_ptr;
    int rc;
    if (msg_len > qi->msg_len)
        msg_len = qi->msg_len;
    pthread_mutex_lock(&qi->lock);
    if (timeout == 0)
    {
        if (qi->avail_num == 0)
        {
            pthread_mutex_unlock(&qi->lock);
            return -1;
        }
    }
    else if (timeout == (int)(~0UL))
    {
        while (qi->avail_num == 0)
            pthread_cond_wait(&qi->cond, &qi->lock);
    }
    else
    {
        if (qi->avail_num == 0)
        {
            gettimeofday(&tp, ((void *)0));
            usec = tp.tv_usec + timeout * 1000;
            if (usec > 1000000)
            {
                sec = usec/1000000;
                usec = usec%1000000;
            }
            ts.tv_sec = tp.tv_sec + sec;
            ts.tv_nsec = usec * 1000;
            rc = pthread_cond_timedwait(&qi->cond, &qi->lock, &ts);
            if (rc == 110)
            {
                pthread_mutex_unlock(&qi->lock);
                return -1;
            }
        }
    }
    data_ptr = qi->buffer + qi->read_index*qi->msg_len;
    memcpy(msg_buf, data_ptr, msg_len);
    qi->read_index = (qi->read_index + 1) % qi->msg_num;
    qi->avail_num--;
    pthread_mutex_unlock(&qi->lock);
    return 0;
}

canonical_original_code:
int queue_receive(long qid, char *msg_buf, unsigned int msg_len, int timeout)
{
    struct _queue_info *qi = (queue_info *)qid;
    struct timespec ts;
    struct timeval tp;
    unsigned int sec = 0; unsigned int usec = 0;
    char *data_ptr;
    int rc;
    if (msg_len > qi->msg_len)
        msg_len = qi->msg_len;
    pthread_mutex_lock(&qi->lock);
    if (timeout == 0)
    {
        if (qi->avail_num == 0)
        {
            pthread_mutex_unlock(&qi->lock);
            return -1;
        }
    }
    else if (timeout == (int)(~0UL))
    {
        while (qi->avail_num == 0)
            pthread_cond_wait(&qi->cond, &qi->lock);
    }
    else
    {
        if (qi->avail_num == 0)
        {
            gettimeofday(&tp, ((void *)0));
            usec = tp.tv_usec + timeout * 1000;
            if (usec > 1000000)
            {
                sec = usec/1000000;
                usec = usec%1000000;
            }
            ts.tv_sec = tp.tv_sec + sec;
            ts.tv_nsec = usec * 1000;
            rc = pthread_cond_timedwait(&qi->cond, &qi->lock, &ts);
            if (rc == 110)
            {
                pthread_mutex_unlock(&qi->lock);
                return -1;
            }
        }
    }
    data_ptr = qi->buffer + qi->read_index*qi->msg_len;
    memcpy(msg_buf, data_ptr, msg_len);
    qi->read_index = (qi->read_index + 1) % qi->msg_num;
    qi->avail_num--;
    pthread_mutex_unlock(&qi->lock);
    return 0;
}

variable_types: timeout int

variable_types: struct timespec { long tv_sec; long tv_nsec; }

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

variable_types:
sec
unsigned int

variable_types:
usec
unsigned int

variable_types: rc int


decompiled_code:
__int64 queue_base_init(void)
{
__int64 result; // rax

qbase = (pthread_mutex_t *)malloc(0x30uLL);
if ( qbase )
{
memset(qbase, 0, 0x30uLL);
pthread_mutex_init(qbase, 0LL);
qbase[1].__align = 0LL;
result = 0LL;
}
else
{
puts("Fail to memory allocation!\r");
result = 0xFFFFFFFFLL;
}
return result;
}

canonical_decompiled_code:
__int64 func5(void)
{
__int64 result; // rax

qbase = (pthread_mutex_t *)malloc(0x30uLL);
if ( qbase )
{
memset(qbase, 0, 0x30uLL);
pthread_mutex_init(qbase, 0LL);
qbase[1].__align = 0LL;
result = 0LL;
}
else
{
puts("Fail to memory allocation!\r");
result = 0xFFFFFFFFLL;
}
return result;
}

original_code:
int queue_base_init(void)
{
    qbase = (queue_base *)malloc(sizeof(queue_base));
    if (qbase == ((void *)0))
    {
        printf("Fail to memory allocation!\r\n");
        return -1;
    }
    memset(qbase, 0, sizeof(queue_base));
    pthread_mutex_init(&qbase->lock, ((void *)0));
    ((&qbase->queue_list)->first = ((void *)0));
    return 0;
}

canonical_original_code:
int queue_base_init()
{
    qbase = (struct _queue_base *)malloc(sizeof(queue_base));
    if (qbase == ((void *)0))
    {
        printf("Fail to memory allocation!\r\n");
        return -1;
    }
    memset(qbase, 0, sizeof(queue_base));
    pthread_mutex_init(&qbase->lock, ((void *)0));
    ((&qbase->queue_list)->first = ((void *)0));
    return 0;
}

user_defined_types: struct _queue_base { union pthread_mutex_t lock; struct _hlist_head queue_list; }


decompiled_code:
__int64 __fastcall search_sem(char *s2)
{
pthread_mutex_t *v1; // rbx
__int64 v2; // rbx
__int64 result; // rax

v1 = sembase;
pthread_mutex_lock(sembase);
v2 = v1[1].__align;
if ( v2 )
{
while ( strcmp((const char *)(v2 + 48), s2) )
{
v2 = *(_QWORD *)v2;
if ( !v2 )
goto LABEL_6;
}
pthread_mutex_unlock(sembase);
result = v2;
}
else
{
LABEL_6:
pthread_mutex_unlock(sembase);
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func3(char *s2)
{
pthread_mutex_t *v1; // rbx
__int64 v2; // rbx
__int64 result; // rax

v1 = sembase;
pthread_mutex_lock(sembase);
v2 = v1[1].__align;
if ( v2 )
{
while ( strcmp((const char *)(v2 + 48), s2) )
{
v2 = *(_QWORD *)v2;
if ( !v2 )
goto LABEL_6;
}
pthread_mutex_unlock(sembase);
result = v2;
}
else
{
LABEL_6:
pthread_mutex_unlock(sembase);
result = 0LL;
}
return result;
}

original_code:
static long search_sem(const char *name)
{
    hlist_head *hhead = &sembase->sem_list;
    hlist_node *hnode = ((void *)0);
    sem_info *si = ((void *)0);
    pthread_mutex_lock(&sembase->lock);
    for (hnode = (hhead)->first; hnode && ({ si = ((sem_info *) ((char *) (hnode) - ((long) &((sem_info *)0)->entry))); 1;}); hnode = hnode->next)
    {
        if (!strcmp(si->name, name))
        {
            pthread_mutex_unlock(&sembase->lock);
            return (long)si;
        }
    }
    pthread_mutex_unlock(&sembase->lock);
    return 0;
}

canonical_original_code:
static long search_sem(char *name)
{
    struct _hlist_head *hhead = &sembase->sem_list;
    struct _hlist_node *hnode = ((void *)0);
    struct _sem_info *si = ((void *)0);
    pthread_mutex_lock(&sembase->lock);
    for (hnode = (hhead)->first; hnode && ({ si = ((struct _sem_info *) ((char *) (hnode) - ((long) &((struct _sem_info *)0)->entry))); 1;}); hnode = hnode->next)
    {
        if (!strcmp(si->name, name))
        {
            pthread_mutex_unlock(&sembase->lock);
            return (long)si;
        }
    }
    pthread_mutex_unlock(&sembase->lock);
    return 0;
}

variable_types:
name
char *

variable_types: struct _hlist_head { struct _hlist_node { struct _hlist_node *next; struct _hlist_node **pprevious; } *first; } *

variable_types: struct _sem_info { struct _hlist_node { struct _hlist_node *next; struct _hlist_node **pprevious; } entry; union sem_t { char __size[32]; long __align; } id; char name[-1]; } *

user_defined_types: struct _sem_info { struct _hlist_node entry; union sem_t id; char name[-1]; }


decompiled_code:
__int64 __fastcall create_sem(char *a1, __int64 a2, __int64 a3, _QWORD *a4)
{
_QWORD *v5; // rax
_QWORD *v6; // rbp
__int64 v7; // rax
size_t v8; // rdx
unsigned int v9; // edx
__int64 result; // rax

if ( search_sem(a1) )
{
printf("Semaphore %s already exists!\r\n", a1);
result = 0xFFFFFFFFLL;
}
else
{
v5 = calloc(0x48uLL, 1uLL);
v6 = v5;
if ( v5 )
{
*a4 = v5;
hlist_node_init(v5);
strncpy((char *)(v7 + 48), a1, v8);
pthread_mutex_lock(sembase);
hlist_head_add(&sembase[1].__align, v6);
if ( sem_init((sem_t *)(v6 + 2), 0, v9) < 0 )
{
hlist_node_remove(v6);
pthread_mutex_unlock(sembase);
result = 0xFFFFFFFFLL;
}
else
{
pthread_mutex_unlock(sembase);
result = 0LL;
}
}
else
{
puts("No suffient memory to create a semaphore!\r");
result = 0xFFFFFFFFLL;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func4(char *a1, __int64 a2, __int64 a3, _QWORD *a4)
{
_QWORD *v5; // rax
_QWORD *v6; // rbp
__int64 v7; // rax
size_t v8; // rdx
unsigned int v9; // edx
__int64 result; // rax

if ( func3(a1) )
{
printf("Semaphore %s already exists!\r\n", a1);
result = 0xFFFFFFFFLL;
}
else
{
v5 = calloc(0x48uLL, 1uLL);
v6 = v5;
if ( v5 )
{
*a4 = v5;
func0(v5);
strncpy((char *)(v7 + 48), a1, v8);
pthread_mutex_lock(sembase);
func1(&sembase[1].__align, v6);
if ( sem_init((sem_t *)(v6 + 2), 0, v9) < 0 )
{
func2(v6);
pthread_mutex_unlock(sembase);
result = 0xFFFFFFFFLL;
}
else
{
pthread_mutex_unlock(sembase);
result = 0LL;
}
}
else
{
puts("No suffient memory to create a semaphore!\r");
result = 0xFFFFFFFFLL;
}
}
return result;
}

original_code:
int create_sem(const char *name, unsigned int init_val, unsigned int flag, long *sid)
{
    sem_info *si;
    if (search_sem(name))
    {
        printf("Semaphore %s already exists!\r\n", name);
        return -1;
    }
    si = (sem_info *)malloc(sizeof(sem_info));
    if (si == ((void *)0))
    {
        printf("No suffient memory to create a semaphore!\r\n");
        return -1;
    }
    memset(si, 0, sizeof(sem_info));
    *sid = (long)si;
    hlist_node_init(&si->entry);
    strncpy(si->name, name, 16);
    pthread_mutex_lock(&sembase->lock);
    hlist_head_add(&sembase->sem_list, &si->entry);
    if (sem_init(&si->id, 0, init_val) < 0)
    {
        hlist_node_remove(&si->entry);
        pthread_mutex_unlock(&sembase->lock);
        return -1;
    }
    pthread_mutex_unlock(&sembase->lock);
    return 0;
}

canonical_original_code:
int create_sem(char *name, unsigned int init_val, unsigned int flag, long *sid)
{
    struct _sem_info *si;
    if (search_sem(name))
    {
        printf("Semaphore %s already exists!\r\n", name);
        return -1;
    }
    si = (struct _sem_info *)malloc(sizeof(sem_info));
    if (si == ((void *)0))
    {
        printf("No suffient memory to create a semaphore!\r\n");
        return -1;
    }
    memset(si, 0, sizeof(sem_info));
    *sid = (long)si;
    hlist_node_init(&si->entry);
    strncpy(si->name, name, 16);
    pthread_mutex_lock(&sembase->lock);
    hlist_head_add(&sembase->sem_list, &si->entry);
    if (sem_init(&si->id, 0, init_val) < 0)
    {
        hlist_node_remove(&si->entry);
        pthread_mutex_unlock(&sembase->lock);
        return -1;
    }
    pthread_mutex_unlock(&sembase->lock);
    return 0;
}

variable_types:
sid
long *

user_defined_types: struct _hlist_node { struct _hlist_node *next; struct _hlist_node **pprevious; }

user_defined_types: union sem_t { char __size[32]; long __align; }


decompiled_code:
int __fastcall del_sem(__int64 a1)
{
pthread_mutex_lock(sembase);
hlist_node_remove((__int64 *)a1);
pthread_mutex_unlock(sembase);
return sem_destroy((sem_t *)(a1 + 16));
}

canonical_decompiled_code:
int __fastcall func5(__int64 a1)
{
pthread_mutex_lock(sembase);
func2((__int64 *)a1);
pthread_mutex_unlock(sembase);
return sem_destroy((sem_t *)(a1 + 16));
}

original_code:
void del_sem(long sid)
{
    sem_info *si = (sem_info *)sid;
    pthread_mutex_lock(&sembase->lock);
    hlist_node_remove(&si->entry);
    pthread_mutex_unlock(&sembase->lock);
    sem_destroy(&si->id);
    return;
}

canonical_original_code:
void del_sem(long sid)
{
    struct _sem_info *si = (sem_info *)sid;
    pthread_mutex_lock(&sembase->lock);
    hlist_node_remove(&si->entry);
    pthread_mutex_unlock(&sembase->lock);
    sem_destroy(&si->id);
    return;
}

variable_types: sid long


decompiled_code:
__int64 __fastcall sem_take(__int64 a1)
{
return (unsigned int)(sem_wait((sem_t *)(a1 + 16)) >> 31);
}

canonical_decompiled_code:
__int64 __fastcall func6(__int64 a1)
{
return (unsigned int)(sem_wait((sem_t *)(a1 + 16)) >> 31);
}

original_code:
int sem_take(long sid)
{
    sem_info *si = (sem_info *)sid;
    if (sem_wait(&si->id) < 0)
        return -1;
    return 0;
}

canonical_original_code:
int sem_take(long sid)
{
    struct _sem_info *si = (sem_info *)sid;
    if (sem_wait(&si->id) < 0)
        return -1;
    return 0;
}


decompiled_code:
__int64 __fastcall sem_give(__int64 a1)
{
return (unsigned int)(sem_post((sem_t *)(a1 + 16)) >> 31);
}

canonical_decompiled_code:
__int64 __fastcall func7(__int64 a1)
{
return (unsigned int)(sem_post((sem_t *)(a1 + 16)) >> 31);
}

original_code:
int sem_give(long sid)
{
    sem_info *si = (sem_info *)sid;
    if (sem_post(&si->id) < 0)
        return -1;
    return 0;
}

canonical_original_code:
int sem_give(long sid)
{
    struct _sem_info *si = (sem_info *)sid;
    if (sem_post(&si->id) < 0)
        return -1;
    return 0;
}


decompiled_code:
__int64 sem_base_init()
{
pthread_mutex_t *v0; // rax
__int64 result; // rax

v0 = (pthread_mutex_t *)calloc(0x30uLL, 1uLL);
sembase = v0;
if ( v0 )
{
pthread_mutex_init(v0, 0LL);
sembase[1].__align = 0LL;
result = 0LL;
}
else
{
puts("Fail to memory allocation!\r");
result = 0xFFFFFFFFLL;
}
return result;
}

canonical_decompiled_code:
__int64 func8()
{
pthread_mutex_t *v0; // rax
__int64 result; // rax

v0 = (pthread_mutex_t *)calloc(0x30uLL, 1uLL);
sembase = v0;
if ( v0 )
{
pthread_mutex_init(v0, 0LL);
sembase[1].__align = 0LL;
result = 0LL;
}
else
{
puts("Fail to memory allocation!\r");
result = 0xFFFFFFFFLL;
}
return result;
}

original_code:
int sem_base_init(void)
{
    sembase = (sem_base *)malloc(sizeof(sem_base));
    if (sembase == ((void *)0))
    {
        printf("Fail to memory allocation!\r\n");
        return -1;
    }
    memset(sembase, 0, sizeof(sem_base));
    pthread_mutex_init(&sembase->lock, ((void *)0));
    ((&sembase->sem_list)->first = ((void *)0));
    return 0;
}

canonical_original_code:
int sem_base_init()
{
    sembase = (struct _sem_base *)malloc(sizeof(sem_base));
    if (sembase == ((void *)0))
    {
        printf("Fail to memory allocation!\r\n");
        return -1;
    }
    memset(sembase, 0, sizeof(sem_base));
    pthread_mutex_init(&sembase->lock, ((void *)0));
    ((&sembase->sem_list)->first = ((void *)0));
    return 0;
}

user_defined_types: struct _sem_base { union pthread_mutex_t lock; struct _hlist_head sem_list; }

user_defined_types: union pthread_mutex_t { struct __pthread_mutex_s __data; char __size[40]; 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; }