// File: /workspace/github_c_makefile_star2_O1/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x658, %rsp            # imm = 0x658
movq %rsi, %rbx
movl %edi, %r12d
movl $0x54, %edi
callq 0x1110
movq %rax, -0x30(%rbp)
movl %eax, %eax
movq %rsp, %rdx
leaq 0xf(%rax), %rcx
andq $-0x10, %rcx
subq %rcx, %rdx
movq %rdx, -0x48(%rbp)
movq %rdx, %rsp
movq %rsp, %rcx
leaq 0xf(,%rax,8), %rax
andq $-0x10, %rax
subq %rax, %rcx
movq %rcx, -0x68(%rbp)
movq %rcx, %rsp
xorl %r15d, %r15d
cmpl $0x2, %r12d
jl 0x13ad
movl %r12d, %r14d
xorl %r15d, %r15d
movl $0x1, %r12d
movq (%rbx,%r12,8), %r13
movq %r13, %rdi
leaq 0xcda(%rip), %rsi       # 0x2004
callq 0x10c0
testl %eax, %eax
je 0x1378
movq %r13, %rdi
leaq 0xcca(%rip), %rsi       # 0x2007
callq 0x10c0
testl %eax, %eax
je 0x1394
movq %r13, %rdi
leaq 0xcba(%rip), %rsi       # 0x200a
callq 0x10c0
testl %eax, %eax
je 0x1381
movq %r13, %rdi
leaq 0xcaa(%rip), %rsi       # 0x200d
callq 0x10c0
leaq 0x2d61(%rip), %rcx      # 0x40d0
testl %eax, %eax
je 0x138e
jmp 0x1820
leaq 0x2d39(%rip), %rax      # 0x40b8
jmp 0x139b
movl $0x1, %r15d
leaq 0x2d3e(%rip), %rcx      # 0x40cc
movl $0x1, (%rcx)
leaq 0x2d21(%rip), %rax      # 0x40bc
movl $0x0, (%rax)
incq %r12
cmpq %r12, %r14
jne 0x131c
movq -0x30(%rbp), %r14
movslq %r14d, %rbx
movq %rbx, %r12
shlq $0x4, %r12
movq %r12, %rdi
callq 0x10d0
movq %rax, 0x2d0e(%rip)      # 0x40d8
movq %rax, %rdi
xorl %esi, %esi
movq %r12, %rdx
callq 0x1090
movq -0x48(%rbp), %rdi
xorl %esi, %esi
movq %rbx, %rdx
callq 0x1090
testl %r14d, %r14d
jle 0x165d
movq -0x30(%rbp), %rax
movl %eax, %ebx
andl $0x7fffffff, %ebx       # imm = 0x7FFFFFFF
leaq -0x280(%rbp), %r14
leaq -0x680(%rbp), %r12
xorl %r8d, %r8d
movq $0x0, -0x50(%rbp)
movq %rbx, -0x58(%rbp)
movl $0x7, %eax
movq -0x48(%rbp), %rcx
cmpb $0x0, (%rcx,%r8)
jne 0x1611
movl $0x200, %esi            # imm = 0x200
movq %r14, %rdi
leaq 0xbe3(%rip), %rdx       # 0x201d
movq %r8, -0x40(%rbp)
movl %r8d, %ecx
xorl %eax, %eax
callq 0x1080
movl $0x400, %edx            # imm = 0x400
movq %r12, %rdi
xorl %esi, %esi
callq 0x1090
movq %r14, %rdi
xorl %esi, %esi
xorl %eax, %eax
callq 0x1100
testl %eax, %eax
js 0x15ee
movl %eax, %r13d
movl $0x400, %edx            # imm = 0x400
movl %eax, %edi
movq %r12, %rsi
callq 0x10b0
movl %r13d, %edi
callq 0x10a0
movq %r12, %rdi
callq 0x1060
cmpq $0x8, %rax
ja 0x14bc
movq %r12, %rdi
leaq 0xbc9(%rip), %rsi       # 0x2066
leaq -0x34(%rbp), %rdx
xorl %eax, %eax
callq 0x10e0
movl -0x34(%rbp), %edx
movq %r12, %rdi
leaq 0xbb4(%rip), %rsi       # 0x2069
xorl %eax, %eax
callq 0x1120
movq %r12, %rdi
callq 0x1060
movq %rax, %r14
leaq -0x689(%rbp), %rax
addq %rax, %r14
xorl %ebx, %ebx
movq %r14, %rdi
leaq 0xb92(%rip), %rsi       # 0x206f
leaq -0x34(%rbp), %rdx
xorl %eax, %eax
callq 0x10e0
cmpl $0x1, %eax
jne 0x1805
movq %r14, -0x70(%rbp)
movl %ebx, %eax
movq %rax, -0x60(%rbp)
movslq %eax, %rbx
movq -0x68(%rbp), %rax
leaq (%rax,%rbx,8), %r14
movq -0x48(%rbp), %rax
addq %rbx, %rax
movq %rax, -0x78(%rbp)
movq %rbx, -0x80(%rbp)
shlq $0x4, %rbx
orq $0x8, %rbx
xorl %r13d, %r13d
xorl %r12d, %r12d
movl -0x34(%rbp), %eax
btl %r12d, %eax
jae 0x1596
movq 0x2ba5(%rip), %rax      # 0x40d8
addq %rbx, %rax
movl %r15d, (%rax,%r13,2)
leaq 0x38c(%rip), %rdx       # 0x18cd
testl %r15d, %r15d
je 0x154d
leaq 0x325(%rip), %rdx       # 0x1872
movq -0x80(%rbp), %rax
leaq (%rax,%r12), %rcx
leaq (%r14,%r13), %rdi
xorl %esi, %esi
callq 0x10f0
cmpl $0x0, 0x2b51(%rip)      # 0x40b8
je 0x157a
movq (%r14,%r12,8), %rdi
movq -0x60(%rbp), %rax
leal (%rax,%r12), %esi
callq 0x124c
movq -0x78(%rbp), %rax
movb $0x1, (%rax,%r12)
movl %r15d, %eax
notl %eax
andl $0x1, %eax
cmpl $0x0, 0x2b2a(%rip)      # 0x40bc
cmovnel %eax, %r15d
incq %r12
addq $0x8, %r13
cmpq $0x20, %r12
jne 0x1523
movq -0x70(%rbp), %r14
leaq -0x9(%r14), %rax
movq -0x60(%rbp), %rcx
leal 0x20(%rcx), %ebx
leaq -0x680(%rbp), %r12
cmpq %r12, %rax
cmovbq %r12, %rax
cmpq %r12, %r14
cmovneq %rax, %r14
cmovel %ecx, %ebx
jne 0x14d3
cmpl $0x0, 0x2af5(%rip)      # 0x40cc
je 0x162c
xorl %eax, %eax
movl $0x1, %r15d
movq -0x58(%rbp), %rbx
leaq -0x280(%rbp), %r14
jmp 0x160d
leaq 0xa5f(%rip), %rdi       # 0x2054
movq %r14, %rsi
xorl %eax, %eax
callq 0x1070
movl $0x1, %eax
movl $0x1, %ecx
movq %rcx, -0x50(%rbp)
movq -0x40(%rbp), %r8
cmpl $0x7, %eax
je 0x161e
testl %eax, %eax
jne 0x17ef
incq %r8
cmpq %rbx, %r8
jne 0x1417
jmp 0x165d
xorl %eax, %eax
cmpl $0x0, 0x2a9b(%rip)      # 0x40d0
movq -0x58(%rbp), %rbx
leaq -0x280(%rbp), %r14
movq -0x40(%rbp), %r8
je 0x164b
xorl %r15d, %r15d
jmp 0x1611
cmpl $0x0, 0x2a6a(%rip)      # 0x40bc
jne 0x1611
notl %r15d
andl $0x1, %r15d
jmp 0x1611
cmpl $0x0, 0x2a54(%rip)      # 0x40b8
je 0x172c
leaq 0xa23(%rip), %rdi       # 0x2094
xorl %eax, %eax
callq 0x1070
cmpl $0x0, -0x30(%rbp)
jle 0x16c0
movq -0x30(%rbp), %r15
andl $0x7fffffff, %r15d      # imm = 0x7FFFFFFF
movl $0x8, %r12d
leaq 0xa1a(%rip), %rbx       # 0x20b0
xorl %r14d, %r14d
movq 0x2a38(%rip), %rax      # 0x40d8
cmpl $0x0, (%rax,%r12)
jne 0x16b4
movq %rbx, %rdi
movl %r14d, %esi
xorl %eax, %eax
callq 0x1070
incq %r14
addq $0x10, %r12
cmpq %r14, %r15
jne 0x1699
movl $0xa, %edi
callq 0x1030
leaq 0x9e3(%rip), %rdi       # 0x20b4
xorl %eax, %eax
callq 0x1070
cmpl $0x0, -0x30(%rbp)
jle 0x1720
movq -0x30(%rbp), %r15
andl $0x7fffffff, %r15d      # imm = 0x7FFFFFFF
movl $0x8, %r12d
leaq 0x9ba(%rip), %rbx       # 0x20b0
xorl %r14d, %r14d
movq 0x29d8(%rip), %rax      # 0x40d8
cmpl $0x0, (%rax,%r12)
je 0x1714
movq %rbx, %rdi
movl %r14d, %esi
xorl %eax, %eax
callq 0x1070
incq %r14
addq $0x10, %r12
cmpq %r14, %r15
jne 0x16f9
movl $0xa, %edi
callq 0x1030
jmp 0x1738
leaq 0x9c2(%rip), %rdi       # 0x20f5
callq 0x1050
movq -0x30(%rbp), %r14
movl $0x1, 0x2982(%rip)      # 0x40c8
movl $0x5, %edi
callq 0x1140
movabsq $-0x29406b2a1a85bd43, %rbx # imm = 0xD6BF94D5E57A42BD
testl %r14d, %r14d
jle 0x1793
movq 0x2972(%rip), %rcx      # 0x40d8
movl %r14d, %edx
andl $0x7fffffff, %edx       # imm = 0x7FFFFFFF
addq $0x8, %rcx
xorl %eax, %eax
cmpl $0x0, (%rcx)
jne 0x177e
addq -0x8(%rcx), %rax
addq $0x10, %rcx
decq %rdx
jne 0x1775
mulq %rbx
movq %rdx, %rsi
shrq $0x16, %rsi
jmp 0x1795
xorl %esi, %esi
leaq 0x934(%rip), %rdi       # 0x20d0
xorl %r15d, %r15d
xorl %eax, %eax
callq 0x1070
testl %r14d, %r14d
jle 0x17dd
movq 0x2926(%rip), %rcx      # 0x40d8
andl $0x7fffffff, %r14d      # imm = 0x7FFFFFFF
addq $0x8, %rcx
xorl %eax, %eax
cmpl $0x0, (%rcx)
je 0x17c8
addq -0x8(%rcx), %rax
addq $0x10, %rcx
decq %r14
jne 0x17bf
mulq %rbx
movq %rdx, %rsi
shrq $0x16, %rsi
jmp 0x17df
xorl %esi, %esi
leaq 0x8fc(%rip), %rdi       # 0x20e2
xorl %eax, %eax
callq 0x1070
jmp 0x17f3
movq -0x50(%rbp), %r15
movl %r15d, %eax
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x868(%rip), %rdi       # 0x2074
movq %r14, %rsi
xorl %eax, %eax
callq 0x1070
movl $0x1, %edi
callq 0x1130
movq (%rbx), %rsi
leaq 0x7e6(%rip), %rdi       # 0x2010
xorl %eax, %eax
callq 0x1070
leaq 0x8ed(%rip), %rdi       # 0x2125
callq 0x1050
leaq 0x904(%rip), %rdi       # 0x2148
callq 0x1050
leaq 0x916(%rip), %rdi       # 0x2166
callq 0x1050
leaq 0x930(%rip), %rdi       # 0x218c
callq 0x1050
movl $0xa, %edi
callq 0x1030
xorl %edi, %edi
callq 0x1130