// File: /workspace/github_c_makefile_star2_O2/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:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
callq 0x10e0
callq 0x1070
movl %eax, %ebp
decl %ebp
pushq $0x8
popq %rdi
callq 0x10c0
movq %rax, %rbx
callq 0x10a0
testl %eax, %eax
jne 0x1264
leaq 0xde8(%rip), %rdi       # 0x2008
pushq $0x4
popq %rsi
xorl %eax, %eax
callq 0x1030
leaq 0xdf0(%rip), %rdi       # 0x2021
movq %rbx, %rsi
xorl %eax, %eax
callq 0x1030
leaq 0x4(%rbx), %rsi
leaq 0xdf6(%rip), %rdi       # 0x203c
xorl %eax, %eax
callq 0x1030
leaq 0xe03(%rip), %rdi       # 0x2057
movl $0x2710, %esi           # imm = 0x2710
xorl %edx, %edx
movl %ebp, %ecx
xorl %eax, %eax
callq 0x1030
andq $0x0, (%rbx)
callq 0x10d0
callq 0x10a0
testl %eax, %eax
je 0x12d9
callq 0x10a0
cmpl %ebp, %eax
jne 0x1363
addq $0x4, %rbx
leaq 0xe77(%rip), %r14       # 0x2105
leaq 0xe47(%rip), %r15       # 0x20dc
xorl %ebp, %ebp
xorl %r12d, %r12d
cmpq $0x2710, %r12           # imm = 0x2710
je 0x133b
movq %rbx, %rdi
xorl %esi, %esi
callq 0x1080
movslq %eax, %rdx
cmpq %rdx, %r12
je 0x12d4
movq %r15, %rdi
movq %r12, %rsi
movq %r12, %rcx
xorl %eax, %eax
callq 0x1030
cmpl $0xa, %ebp
jge 0x1398
incl %ebp
incq %r12
jmp 0x129a
leaq 0xddc(%rip), %r14       # 0x20bc
leaq 0xda6(%rip), %r15       # 0x208d
xorl %ebp, %ebp
xorl %r12d, %r12d
cmpq $0x2710, %r12           # imm = 0x2710
je 0x133b
movl %r12d, %r13d
andl $0x1, %r13d
orq $0x2, %r13
movq %rbx, %rdi
movl %r13d, %esi
xorl %edx, %edx
callq 0x1040
movq %rbx, %rdi
xorl %esi, %esi
callq 0x10b0
movslq %eax, %rdx
cmpq %rdx, %r13
je 0x1336
movq %r15, %rdi
movq %r12, %rsi
movq %r13, %rcx
xorl %eax, %eax
callq 0x1030
cmpl $0xa, %ebp
jge 0x1398
incl %ebp
incq %r12
jmp 0x12ec
callq 0x10a0
movq %r14, %rdi
movl %eax, %esi
xorl %eax, %eax
callq 0x1030
callq 0x10d0
testl %ebp, %ebp
je 0x1368
leaq 0xdcf(%rip), %rdi       # 0x212b
callq 0x1060
jmp 0x1368
callq 0x10d0
callq 0x10d0
callq 0x10a0
testl %eax, %eax
jne 0x1382
leaq 0xda0(%rip), %rdi       # 0x211d
callq 0x1060
callq 0x1090
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xd8c(%rip), %rdi       # 0x212b
callq 0x1060
callq 0x1050