// File: /workspace/github_c_makefile_star2_O0/agraf[P]kvmbench/ht.c
// Function: main
int main(int argc, char **argv)
{
    int num_cores = sysconf(_SC_NPROCESSORS_ONLN);
    int i;
    char thread_spawned[num_cores];
    pthread_t thread[num_cores];
    uint64_t result = 0;
    char thread_siblings[1024];
    char *tsp;
    int is_store = 0;

    for (i = 1; i < argc; i++) {
        if (!strcmp(argv[i], "-P")) {
            opt_pinned = 0;
        } else if (!strcmp(argv[i], "-c")) {
            opt_optimal = 0;
        } else if (!strcmp(argv[i], "-s")) {
            opt_only_store = 1;
            is_store = 1;
            opt_optimal = 0;
        } else if (!strcmp(argv[i], "-m")) {
            opt_only_mul = 1;
            opt_optimal = 0;
        } else {
            printf("Syntax: %s\n\n", argv[0]);
            printf("  -c    Pin the threads to collide\n");
            printf("  -P    Don't pin the threads\n");
            printf("  -s    Run store test on all threads\n");
            printf("  -m    Run mul test on all threads\n");
            printf("\n");
            exit(0);
        }
    }

    results = malloc(num_cores * sizeof(*results));
    memset((void*)results, 0, num_cores * sizeof(*results));
    memset(thread_spawned, 0, num_cores);

    for (i = 0; i < num_cores; i++) {
        char path[512];
        int fd;
        int offset = 0;

        if (thread_spawned[i]) continue;

        snprintf(path, sizeof(path), "/sys/devices/system/cpu/cpu%d/topology/thread_siblings", i);

        memset(thread_siblings, 0, sizeof(thread_siblings));
        fd = open(path, O_RDONLY);
        if (fd < 0) {
            printf("Error opening %s\n", path);
            return 1;
        }
        read(fd, thread_siblings, sizeof(thread_siblings));
        /* Just hope we read everything */
        close(fd);

        if (strlen(thread_siblings) < 9) {
            uint32_t cur_siblings;

            sscanf(thread_siblings, "%x", &cur_siblings);
            sprintf(thread_siblings, "%08x\n", cur_siblings);
        }

        tsp = thread_siblings + strlen(thread_siblings) - 9;
        while (1) {
            uint32_t cur_siblings;
            int j;

            if (sscanf(tsp, "%08x", &cur_siblings) != 1) {
                printf("Error reading siblings from %s\n", tsp);
                exit(1);
            }

            for (j = 0; j < 32; j++) {
                if (cur_siblings & (1U << j)) {
                    int cpu = j + offset;
                    spawn_thread(&thread[cpu], &thread_spawned[cpu], is_store, cpu);
                    if (opt_optimal) {
                        is_store = (is_store + 1) & 1;
                    }
                }
            }

            if (tsp == thread_siblings) {
                break;
            }

            tsp -= 9;
            offset += 32;
            if ((uintptr_t)tsp < (uintptr_t)thread_siblings) {
                tsp = thread_siblings;
            }
        }

        if (opt_only_store) {
            is_store = 1;
        } else if (opt_only_mul) {
            is_store = 0;
        } else if (!opt_optimal) {
            is_store = (is_store + 1) & 1;
        }
    }

    if (opt_pinned) {
        printf("Running  MUL  test on CPUs ");
        for (i = 0; i < num_cores; i++) {
            if (!results[i].is_store) {
                printf("%d ", i);
            }
        }
        printf("\n");

        printf("Running STORE test on CPUs ");
        for (i = 0; i < num_cores; i++) {
            if (results[i].is_store) {
                printf("%d ", i);
            }
        }
        printf("\n");
    } else {
        printf("Running STORE and MUL tests without pinning ...\n");
    }

    running = 1;
    sleep(5);

    result = 0;
    for (i = 0; i < num_cores; i++) {
        if (!results[i].is_store) {
            result += results[i].result;
        }
    }
    printf("Total MMuls: %ld\n", result / 1000000 / 5);

    result = 0;
    for (i = 0; i < num_cores; i++) {
        if (results[i].is_store) {
            result += results[i].result;
        }
    }
    printf("Total MStore: %ld\n", result / 1000000 / 5);

    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x690, %rsp            # imm = 0x690
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl $0x54, %edi
callq 0x10f0
movl %eax, -0x14(%rbp)
movl -0x14(%rbp), %eax
movq %rsp, %rcx
movq %rcx, -0x20(%rbp)
movq %rax, %rdx
addq $0xf, %rdx
andq $-0x10, %rdx
movq %rsp, %rcx
subq %rdx, %rcx
movq %rcx, -0x680(%rbp)
movq %rcx, %rsp
movq %rax, -0x28(%rbp)
movl -0x14(%rbp), %eax
leaq 0xf(,%rax,8), %rdx
andq $-0x10, %rdx
movq %rsp, %rcx
subq %rdx, %rcx
movq %rcx, -0x678(%rbp)
movq %rcx, %rsp
movq %rax, -0x30(%rbp)
movq $0x0, -0x38(%rbp)
movl $0x0, -0x44c(%rbp)
movl $0x1, -0x18(%rbp)
movl -0x18(%rbp), %eax
cmpl -0x8(%rbp), %eax
jge 0x14ca
movq -0x10(%rbp), %rax
movslq -0x18(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
leaq 0xc6a(%rip), %rsi       # 0x2004
callq 0x10a0
cmpl $0x0, %eax
jne 0x13b3
movl $0x0, 0x2cfa(%rip)      # 0x40a8
jmp 0x14ba
movq -0x10(%rbp), %rax
movslq -0x18(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
leaq 0xc41(%rip), %rsi       # 0x2007
callq 0x10a0
cmpl $0x0, %eax
jne 0x13df
movl $0x0, 0x2cd2(%rip)      # 0x40ac
jmp 0x14b8
movq -0x10(%rbp), %rax
movslq -0x18(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
leaq 0xc18(%rip), %rsi       # 0x200a
callq 0x10a0
cmpl $0x0, %eax
jne 0x141f
movl $0x1, 0x2cb6(%rip)      # 0x40bc
movl $0x1, -0x44c(%rbp)
movl $0x0, 0x2c92(%rip)      # 0x40ac
jmp 0x14b6
movq -0x10(%rbp), %rax
movslq -0x18(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
leaq 0xbdb(%rip), %rsi       # 0x200d
callq 0x10a0
cmpl $0x0, %eax
jne 0x1452
movl $0x1, 0x2c7a(%rip)      # 0x40c0
movl $0x0, 0x2c5c(%rip)      # 0x40ac
jmp 0x14b4
movq -0x10(%rbp), %rax
movq (%rax), %rsi
leaq 0xbb0(%rip), %rdi       # 0x2010
movb $0x0, %al
callq 0x1050
leaq 0xbaf(%rip), %rdi       # 0x201d
movb $0x0, %al
callq 0x1050
leaq 0xbc5(%rip), %rdi       # 0x2041
movb $0x0, %al
callq 0x1050
leaq 0xbd6(%rip), %rdi       # 0x2060
movb $0x0, %al
callq 0x1050
leaq 0xbef(%rip), %rdi       # 0x2087
movb $0x0, %al
callq 0x1050
leaq 0xb75(%rip), %rdi       # 0x201b
movb $0x0, %al
callq 0x1050
xorl %edi, %edi
callq 0x1110
jmp 0x14b6
jmp 0x14b8
jmp 0x14ba
jmp 0x14bc
movl -0x18(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18(%rbp)
jmp 0x137b
movslq -0x14(%rbp), %rdi
shlq $0x4, %rdi
callq 0x10b0
movq %rax, 0x2bea(%rip)      # 0x40c8
movq 0x2be3(%rip), %rdi      # 0x40c8
movslq -0x14(%rbp), %rdx
shlq $0x4, %rdx
xorl %esi, %esi
callq 0x1070
movq -0x680(%rbp), %rdi
movslq -0x14(%rbp), %rdx
xorl %esi, %esi
callq 0x1070
movl $0x0, -0x18(%rbp)
movl -0x18(%rbp), %eax
cmpl -0x14(%rbp), %eax
jge 0x17f7
movq -0x680(%rbp), %rax
movl $0x0, -0x658(%rbp)
movslq -0x18(%rbp), %rcx
cmpb $0x0, (%rax,%rcx)
je 0x1539
jmp 0x17e9
leaq -0x650(%rbp), %rdi
movl -0x18(%rbp), %ecx
movl $0x200, %esi            # imm = 0x200
leaq 0xb5d(%rip), %rdx       # 0x20ac
movb $0x0, %al
callq 0x1060
leaq -0x440(%rbp), %rdi
xorl %esi, %esi
movl $0x400, %edx            # imm = 0x400
callq 0x1070
leaq -0x650(%rbp), %rdi
xorl %esi, %esi
movb $0x0, %al
callq 0x10e0
movl %eax, -0x654(%rbp)
cmpl $0x0, -0x654(%rbp)
jge 0x15b3
leaq -0x650(%rbp), %rsi
leaq 0xb4d(%rip), %rdi       # 0x20e3
movb $0x0, %al
callq 0x1050
movl $0x1, -0x4(%rbp)
movl $0x1, -0x65c(%rbp)
jmp 0x1a07
movl -0x654(%rbp), %edi
leaq -0x440(%rbp), %rsi
movl $0x400, %edx            # imm = 0x400
callq 0x1090
movl -0x654(%rbp), %edi
callq 0x1080
leaq -0x440(%rbp), %rdi
callq 0x1040
cmpq $0x9, %rax
jae 0x161e
leaq -0x440(%rbp), %rdi
leaq 0xb00(%rip), %rsi       # 0x20f5
leaq -0x660(%rbp), %rdx
movb $0x0, %al
callq 0x10c0
leaq -0x440(%rbp), %rdi
movl -0x660(%rbp), %edx
leaq 0xae1(%rip), %rsi       # 0x20f8
movb $0x0, %al
callq 0x1100
leaq -0x440(%rbp), %rax
movq %rax, -0x688(%rbp)
leaq -0x440(%rbp), %rdi
callq 0x1040
movq %rax, %rcx
movq -0x688(%rbp), %rax
addq %rcx, %rax
addq $-0x9, %rax
movq %rax, -0x448(%rbp)
jmp 0x1652
movq -0x448(%rbp), %rdi
leaq 0xa9e(%rip), %rsi       # 0x20fe
leaq -0x664(%rbp), %rdx
movb $0x0, %al
callq 0x10c0
cmpl $0x1, %eax
je 0x1692
movq -0x448(%rbp), %rsi
leaq 0xa82(%rip), %rdi       # 0x2103
movb $0x0, %al
callq 0x1050
movl $0x1, %edi
callq 0x1110
movl $0x0, -0x668(%rbp)
cmpl $0x20, -0x668(%rbp)
jge 0x1742
movl -0x664(%rbp), %eax
movl -0x668(%rbp), %ecx
movl $0x1, %edx
shll %cl, %edx
movl %edx, %ecx
andl %ecx, %eax
cmpl $0x0, %eax
je 0x172c
movq -0x680(%rbp), %rsi
movq -0x678(%rbp), %rdi
movl -0x668(%rbp), %eax
addl -0x658(%rbp), %eax
movl %eax, -0x66c(%rbp)
movslq -0x66c(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rdi
movslq -0x66c(%rbp), %rax
addq %rax, %rsi
movl -0x44c(%rbp), %edx
movslq -0x66c(%rbp), %rcx
callq 0x1a20
cmpl $0x0, 0x2996(%rip)      # 0x40ac
je 0x172a
movl -0x44c(%rbp), %eax
addl $0x1, %eax
andl $0x1, %eax
movl %eax, -0x44c(%rbp)
jmp 0x172c
jmp 0x172e
movl -0x668(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x668(%rbp)
jmp 0x169c
movq -0x448(%rbp), %rax
leaq -0x440(%rbp), %rcx
cmpq %rcx, %rax
jne 0x1757
jmp 0x179e
movq -0x448(%rbp), %rax
addq $-0x9, %rax
movq %rax, -0x448(%rbp)
movl -0x658(%rbp), %eax
addl $0x20, %eax
movl %eax, -0x658(%rbp)
movq -0x448(%rbp), %rax
leaq -0x440(%rbp), %rcx
cmpq %rcx, %rax
jae 0x1799
leaq -0x440(%rbp), %rax
movq %rax, -0x448(%rbp)
jmp 0x1650
cmpl $0x0, 0x2917(%rip)      # 0x40bc
je 0x17b3
movl $0x1, -0x44c(%rbp)
jmp 0x17e7
cmpl $0x0, 0x2906(%rip)      # 0x40c0
je 0x17c8
movl $0x0, -0x44c(%rbp)
jmp 0x17e5
cmpl $0x0, 0x28dd(%rip)      # 0x40ac
jne 0x17e3
movl -0x44c(%rbp), %eax
addl $0x1, %eax
andl $0x1, %eax
movl %eax, -0x44c(%rbp)
jmp 0x17e5
jmp 0x17e7
jmp 0x17e9
movl -0x18(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18(%rbp)
jmp 0x150d
cmpl $0x0, 0x28aa(%rip)      # 0x40a8
je 0x18cc
leaq 0x918(%rip), %rdi       # 0x2123
movb $0x0, %al
callq 0x1050
movl $0x0, -0x18(%rbp)
movl -0x18(%rbp), %eax
cmpl -0x14(%rbp), %eax
jge 0x1859
movq 0x28a0(%rip), %rax      # 0x40c8
movslq -0x18(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movl 0x8(%rax), %eax
cmpl $0x0, %eax
jne 0x184c
movl -0x18(%rbp), %esi
leaq 0x8fa(%rip), %rdi       # 0x213f
movb $0x0, %al
callq 0x1050
jmp 0x184e
movl -0x18(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18(%rbp)
jmp 0x1819
leaq 0x7bb(%rip), %rdi       # 0x201b
movb $0x0, %al
callq 0x1050
leaq 0x8d5(%rip), %rdi       # 0x2143
movb $0x0, %al
callq 0x1050
movl $0x0, -0x18(%rbp)
movl -0x18(%rbp), %eax
cmpl -0x14(%rbp), %eax
jge 0x18bc
movq 0x283d(%rip), %rax      # 0x40c8
movslq -0x18(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movl 0x8(%rax), %eax
cmpl $0x0, %eax
je 0x18af
movl -0x18(%rbp), %esi
leaq 0x897(%rip), %rdi       # 0x213f
movb $0x0, %al
callq 0x1050
jmp 0x18b1
movl -0x18(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18(%rbp)
jmp 0x187c
leaq 0x758(%rip), %rdi       # 0x201b
movb $0x0, %al
callq 0x1050
jmp 0x18da
leaq 0x88c(%rip), %rdi       # 0x215f
movb $0x0, %al
callq 0x1050
movl $0x1, 0x27d4(%rip)      # 0x40b8
movl $0x5, %edi
callq 0x1120
movq $0x0, -0x38(%rbp)
movl $0x0, -0x18(%rbp)
movl -0x18(%rbp), %eax
cmpl -0x14(%rbp), %eax
jge 0x1949
movq 0x27bc(%rip), %rax      # 0x40c8
movslq -0x18(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movl 0x8(%rax), %eax
cmpl $0x0, %eax
jne 0x193c
movq 0x27a2(%rip), %rax      # 0x40c8
movslq -0x18(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq (%rax), %rax
addq -0x38(%rbp), %rax
movq %rax, -0x38(%rbp)
jmp 0x193e
movl -0x18(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18(%rbp)
jmp 0x18fd
movq -0x38(%rbp), %rax
movl $0xf4240, %ecx          # imm = 0xF4240
xorl %edx, %edx
divq %rcx
movl $0x5, %ecx
xorl %edx, %edx
divq %rcx
movq %rax, %rsi
leaq 0x825(%rip), %rdi       # 0x2190
movb $0x0, %al
callq 0x1050
movq $0x0, -0x38(%rbp)
movl $0x0, -0x18(%rbp)
movl -0x18(%rbp), %eax
cmpl -0x14(%rbp), %eax
jge 0x19cd
movq 0x2738(%rip), %rax      # 0x40c8
movslq -0x18(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movl 0x8(%rax), %eax
cmpl $0x0, %eax
je 0x19c0
movq 0x271e(%rip), %rax      # 0x40c8
movslq -0x18(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq (%rax), %rax
addq -0x38(%rbp), %rax
movq %rax, -0x38(%rbp)
jmp 0x19c2
movl -0x18(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18(%rbp)
jmp 0x1981
movq -0x38(%rbp), %rax
movl $0xf4240, %ecx          # imm = 0xF4240
xorl %edx, %edx
divq %rcx
movl $0x5, %ecx
xorl %edx, %edx
divq %rcx
movq %rax, %rsi
leaq 0x7b3(%rip), %rdi       # 0x21a2
movb $0x0, %al
callq 0x1050
movl $0x0, -0x4(%rbp)
movl $0x1, -0x65c(%rbp)
movq -0x20(%rbp), %rax
movq %rax, %rsp
movl -0x4(%rbp), %eax
movq %rbp, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)