// File: /workspace/github_c_makefile_star2_O0/openshmem-org[P]openshmem-examples/c/amo.c
// Function: main
int
main()
{
    int tpe, other;
    long i;
    struct
    {
        locktype a;
        locktype b;
    } *twovars;
    int numfail = 0;
    shmem_init();
    tpe = 0;
    other = shmem_n_pes() - 1;
    twovars = shmem_malloc(sizeof(*twovars));
    if (shmem_my_pe() == 0) {
        printf("Element size: %ld bytes\n", sizeof(locktype));
        printf("Addresses: 1st element %p\n", (void *) &twovars->a);
        printf("           2nd element %p\n", (void *) &twovars->b);
        printf("Iterations: %d   target PE: %d   other active PE: %d\n",
               tries, tpe, other);
    }
    twovars->a = 0;
    twovars->b = 0;
    shmem_barrier_all();
    if (shmem_my_pe() == 0) {

        // put two values alternately to the 1st 32 bit word
        long expect, check;
        for (i = 0; i < tries; i++) {
            expect = 2 + i % 2;
            if (sizeof(locktype) == sizeof(int)) {
                shmem_int_p((void *) &twovars->a, expect, tpe);
                check = shmem_int_g((void *) &twovars->a, tpe);
            }
            else if (sizeof(locktype) == sizeof(long)) {
                shmem_long_p((void *) &twovars->a, expect, tpe);
                check = shmem_long_g((void *) &twovars->a, tpe);
            }
            if (check != expect) {
                printf("error: iter %ld get returned %ld expected %ld\n", i,
                       check, expect);
                numfail++;
                if (numfail > 10) {
                    printf("FAIL\n");
                    abort();
                }
            }
        }
        printf("PE %d done doing puts and gets\n", shmem_my_pe());
    }
    else if (shmem_my_pe() == other) {

        // keep on atomically incrementing the 2nd 32 bit word
        long oldval;
        for (i = 0; i < tries; i++) {
            if (sizeof(locktype) == sizeof(int)) {
                oldval =
                    shmem_int_atomic_fetch_inc((void *) &twovars->b, tpe);
            }
            else if (sizeof(locktype) == sizeof(long)) {
                oldval =
                    shmem_long_atomic_fetch_inc((void *) &twovars->b, tpe);
            }
            if (oldval != i) {
                printf("error: iter %ld finc got %ld expect %ld\n", i,
                       oldval, i);
                numfail++;
                if (numfail > 10) {
                    printf("FAIL\n");
                    abort();
                }
            }
        }
        printf("PE %d done doing fincs\n", shmem_my_pe());
    }
    shmem_barrier_all();
    if (numfail) {
        printf("FAIL\n");
    }
    shmem_barrier_all();
    if (shmem_my_pe() == 0) {
        printf("test complete\n");
    }
    shmem_finalize();
    return 0;
}

// Assembly:
subq $0x48, %rsp
movl $0x0, 0x44(%rsp)
movl $0x0, 0x24(%rsp)
callq 0x10d0
movl $0x0, 0x40(%rsp)
callq 0x1060
subl $0x1, %eax
movl %eax, 0x3c(%rsp)
movl $0x8, %edi
callq 0x10b0
movq %rax, 0x28(%rsp)
callq 0x1090
cmpl $0x0, %eax
jne 0x127e
leaq 0xddb(%rip), %rdi       # 0x2008
movl $0x4, %esi
movb $0x0, %al
callq 0x1030
movq 0x28(%rsp), %rsi
leaq 0xddc(%rip), %rdi       # 0x2021
movb $0x0, %al
callq 0x1030
movq 0x28(%rsp), %rsi
addq $0x4, %rsi
leaq 0xde0(%rip), %rdi       # 0x203c
movb $0x0, %al
callq 0x1030
movl 0x40(%rsp), %edx
movl 0x3c(%rsp), %ecx
leaq 0xde5(%rip), %rdi       # 0x2057
movl $0x2710, %esi           # imm = 0x2710
movb $0x0, %al
callq 0x1030
movq 0x28(%rsp), %rax
movl $0x0, (%rax)
movq 0x28(%rsp), %rax
movl $0x0, 0x4(%rax)
callq 0x10c0
callq 0x1090
cmpl $0x0, %eax
jne 0x1381
movq $0x0, 0x30(%rsp)
cmpq $0x2710, 0x30(%rsp)     # imm = 0x2710
jge 0x1367
movq 0x30(%rsp), %rax
movl $0x2, %ecx
cqto
idivq %rcx
addq $0x2, %rdx
movq %rdx, 0x18(%rsp)
movq 0x28(%rsp), %rdi
movq 0x18(%rsp), %rax
movl %eax, %esi
movl 0x40(%rsp), %edx
callq 0x1040
movq 0x28(%rsp), %rdi
movl 0x40(%rsp), %esi
callq 0x10a0
cltq
movq %rax, 0x10(%rsp)
movq 0x10(%rsp), %rax
cmpq 0x18(%rsp), %rax
je 0x1352
movq 0x30(%rsp), %rsi
movq 0x10(%rsp), %rdx
movq 0x18(%rsp), %rcx
leaq 0xd69(%rip), %rdi       # 0x208d
movb $0x0, %al
callq 0x1030
movl 0x24(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x24(%rsp)
cmpl $0xa, 0x24(%rsp)
jle 0x1350
leaq 0xd78(%rip), %rdi       # 0x20bc
movb $0x0, %al
callq 0x1030
callq 0x1050
jmp 0x1352
jmp 0x1354
movq 0x30(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x30(%rsp)
jmp 0x12b1
callq 0x1090
movl %eax, %esi
leaq 0xd4d(%rip), %rdi       # 0x20c2
movb $0x0, %al
callq 0x1030
jmp 0x1439
callq 0x1090
cmpl 0x3c(%rsp), %eax
jne 0x1437
movq $0x0, 0x30(%rsp)
cmpq $0x2710, 0x30(%rsp)     # imm = 0x2710
jge 0x1422
movq 0x28(%rsp), %rdi
addq $0x4, %rdi
movl 0x40(%rsp), %esi
callq 0x1070
cltq
movq %rax, 0x8(%rsp)
movq 0x8(%rsp), %rax
cmpq 0x30(%rsp), %rax
je 0x140d
movq 0x30(%rsp), %rsi
movq 0x8(%rsp), %rdx
movq 0x30(%rsp), %rcx
leaq 0xd03(%rip), %rdi       # 0x20e2
movb $0x0, %al
callq 0x1030
movl 0x24(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x24(%rsp)
cmpl $0xa, 0x24(%rsp)
jle 0x140b
leaq 0xcbd(%rip), %rdi       # 0x20bc
movb $0x0, %al
callq 0x1030
callq 0x1050
jmp 0x140d
jmp 0x140f
movq 0x30(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x30(%rsp)
jmp 0x1399
callq 0x1090
movl %eax, %esi
leaq 0xcdb(%rip), %rdi       # 0x210b
movb $0x0, %al
callq 0x1030
jmp 0x1439
callq 0x10c0
cmpl $0x0, 0x24(%rsp)
je 0x1453
leaq 0xc70(%rip), %rdi       # 0x20bc
movb $0x0, %al
callq 0x1030
callq 0x10c0
callq 0x1090
cmpl $0x0, %eax
jne 0x1470
leaq 0xcba(%rip), %rdi       # 0x2123
movb $0x0, %al
callq 0x1030
callq 0x1080
xorl %eax, %eax
addq $0x48, %rsp
retq