// File: /workspace/github_c_makefile_star2_O0/USArmyResearchLab[P]ARL_OpenSHMEM/src/shmem_init.c
// Function: shmem_init
SHMEM_SCOPE
void shmem_init(void)
{
	int run_id;
	int my_pe;
	int n_pes;
	int n_pes_log2;
	size_t heap_size;

	debug("shmem_init begin");

	bzero(&__shmem,sizeof(shmem_internals_t));

	const char* env_var_run_id = getenv("SHMEM_RUN_ID");
	const char* env_var_my_pe = getenv("SHMEM_MY_PE");
	const char* env_var_n_pes = getenv("SHMEM_N_PES");
	const char* env_var_heap_size = getenv("SHMEM_SYMMETRIC_HEAP_SIZE");

	if ( env_var_run_id && env_var_my_pe && env_var_n_pes ) {
		run_id = atoi(env_var_run_id);
		my_pe = atoi(env_var_my_pe);
		n_pes = atoi(env_var_n_pes);
	} else {
		run_id = getpid();
		my_pe = 0;
		n_pes = 1;
		fprintf(stderr,"shmem warning: SHMEM_RUN_ID, SHMEM_MY_PE, or"
			" SHMEM_N_PES not set. Defaulting to serial execution\n");
	}

	if (env_var_heap_size) {
		size_t len = strnlen(env_var_heap_size,1024);
		unsigned int x = 1;
		if (env_var_heap_size[len-1]=='K') {
			x = 1024;
		} else if (env_var_heap_size[len-1]=='M') {
			x = 1024*1024;
		}
		heap_size = x * atoi(env_var_heap_size);
	} else {
		heap_size = 128*1024*1024;
		if (my_pe == 0) {
			fprintf(stderr,"shmem warning: SHMEM_SYMMETRIC_HEAP_SIZE not set."
				" Defaulting to %ld bytes\n", heap_size);
		}
	}

	debug("run_id=%d\nmy_pe=%d\nn_pes=%d\nheap_size=%ld\n",
		run_id, my_pe, n_pes, heap_size);

	if ( n_pes < 0 || n_pes > SHMEM_MAX_PES ) {
		fprintf(stderr,"shmem error: n_pes out of range: %d\n",n_pes);
		exit(-1);
	}

	if ( my_pe < 0 || my_pe >= n_pes ) {
		fprintf(stderr,"shmem error: my_pe out of range: %d\n",my_pe);
		exit(-1);
	}


	// log2_ceil of n_pes precalculated once
	n_pes_log2 = 0;
	unsigned int x = n_pes - 1;
	while (x > 0) {
		n_pes_log2++;
		x >>= 1;
	}

	__shmem.run_id = run_id;
	__shmem_my_pe = __shmem.my_pe = my_pe;
	__shmem_n_pes = __shmem.n_pes = n_pes;
	__shmem.n_pes_log2 = n_pes_log2;
	__shmem.heap_size = heap_size;


	__shmem.giant_barrier_count = 0;
	sem_init(&__shmem.giant_mutex,1,0);
	sem_init(&__shmem.giant_barrier_gate1,1,0);
	sem_init(&__shmem.giant_barrier_gate2,1,0);

	sem_init(&__shmem.sync_mutex,1,0);


	/* First we need to remap .data and .bss into a shm allocation. */

	int data_fd;
	void* data_start;
	size_t data_size;

	find_data_pages(&data_start,&data_size);

	intptr_t data_shm_base 
		= (intptr_t)shm_alloc(n_pes*data_size,run_id,0,&data_fd);
	
	munmap((void*)(data_shm_base+my_pe*data_size), data_size);

	remap_pages(data_fd, my_pe*data_size, data_start, data_size);

	__shmem.data_fd = data_fd;
	__shmem.data_base = (intptr_t)data_start;
	__shmem.data_size = data_size;
	__shmem.data_shm_base = data_shm_base;

	debug("symmetric data:\n\tdata_fd=%d\n\tdata_base=%p\n\tdata_size=%ld\n"
		"\tdata_shm_base=%p\n",data_fd,data_start,data_size,(void*)data_shm_base);


	/* we now have enough information to setup the symmetric heap -DAR */

	debug("shmem_init setup shared memory region");

	intptr_t heap_shm_base = (intptr_t)shm_alloc(n_pes*heap_size,run_id,1,0);

	debug("shmem_init shm_alloc returned %p",(void*)heap_shm_base);

	__shmem.heap_shm_base = heap_shm_base;

	debug("__shmem.heap_shm_base %p\n",(void*)__shmem.heap_shm_base);


	int c, r;
	for (c = 0, r = 1; r < __shmem.n_pes; c++, r <<= 1)
	{
		int to = __shmem.my_pe + r;
		if (to >= __shmem.n_pes) to -= __shmem.n_pes;
		long* lock = (long*)(__shmem.barrier_sync + c);
		long* remote_lock = (long*)shmem_ptr((void*)lock, to);
		__shmem.barrier_psync[c] = remote_lock;
	}
	debug("pe %d barrier_psync[0] %p",__shmem.my_pe,__shmem.barrier_psync[0]);


	__shmem.local_mem_base 
		= __shmem.heap_shm_base + my_pe * heap_size + getpagesize();

	__shmem.free_mem = __shmem.local_mem_base;

	__shmem.xmem0 = xmalloc_init( 
		(void*)__shmem.local_mem_base, heap_size - getpagesize(), 0 );

	debug("[%d] before barrier\n",my_pe);

	__shmem.p_giant_mutex = (sem_t*)shmem_ptr((void*)&__shmem.giant_mutex,0);

	if (my_pe == 0) sem_post(&__shmem.giant_mutex);
	sem_post(&__shmem.sync_mutex);


	shmem_sync_all();


	debug("[%d] after barrier\n",my_pe);


	if (__shmem.n_pes == 1) return;

	if (!__shmem.my_pe) {
		debug("master set psync to 1 @ %p",__shmem.barrier_psync[0]);
		*__shmem.barrier_psync[0] = 1;
	}

	debug("spin on sync at %p",__shmem.barrier_sync);
	while(*__shmem.barrier_sync == SHMEM_SYNC_VALUE);

	if (__shmem.my_pe) {
		debug("slave set psync to 1 @ %p",__shmem.barrier_psync[0]);
		*__shmem.barrier_psync[0] = 1;
	}

	debug("set sync to SHMEM_SYNC_VALUE @ %p",__shmem.barrier_sync);
	*__shmem.barrier_sync = SHMEM_SYNC_VALUE;

	debug("shmem_init done");

	
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xb0, %rsp
leaq 0x5a7e(%rip), %rdi      # 0x71f0
xorl %esi, %esi
movl $0x298, %edx            # imm = 0x298
callq 0x1130
leaq 0x390b(%rip), %rdi      # 0x5090
callq 0x1030
movq %rax, -0x20(%rbp)
leaq 0x3908(%rip), %rdi      # 0x509d
callq 0x1030
movq %rax, -0x28(%rbp)
leaq 0x3904(%rip), %rdi      # 0x50a9
callq 0x1030
movq %rax, -0x30(%rbp)
leaq 0x3900(%rip), %rdi      # 0x50b5
callq 0x1030
movq %rax, -0x38(%rbp)
cmpq $0x0, -0x20(%rbp)
je 0x17f9
cmpq $0x0, -0x28(%rbp)
je 0x17f9
cmpq $0x0, -0x30(%rbp)
je 0x17f9
movq -0x20(%rbp), %rdi
callq 0x1210
movl %eax, -0x4(%rbp)
movq -0x28(%rbp), %rdi
callq 0x1210
movl %eax, -0x8(%rbp)
movq -0x30(%rbp), %rdi
callq 0x1210
movl %eax, -0xc(%rbp)
jmp 0x1827
callq 0x10a0
movl %eax, -0x4(%rbp)
movl $0x0, -0x8(%rbp)
movl $0x1, -0xc(%rbp)
movq 0x57e2(%rip), %rax      # 0x6ff8
movq (%rax), %rdi
leaq 0x38af(%rip), %rsi      # 0x50cf
movb $0x0, %al
callq 0x1180
cmpq $0x0, -0x38(%rbp)
je 0x18a8
movq -0x38(%rbp), %rdi
movl $0x400, %esi            # imm = 0x400
callq 0x1140
movq %rax, -0x40(%rbp)
movl $0x1, -0x44(%rbp)
movq -0x38(%rbp), %rax
movq -0x40(%rbp), %rcx
subq $0x1, %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x4b, %eax
jne 0x1865
movl $0x400, -0x44(%rbp)     # imm = 0x400
jmp 0x1883
movq -0x38(%rbp), %rax
movq -0x40(%rbp), %rcx
subq $0x1, %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x4d, %eax
jne 0x1881
movl $0x100000, -0x44(%rbp)  # imm = 0x100000
jmp 0x1883
movl -0x44(%rbp), %eax
movl %eax, -0x94(%rbp)
movq -0x38(%rbp), %rdi
callq 0x1210
movl %eax, %ecx
movl -0x94(%rbp), %eax
imull %ecx, %eax
movl %eax, %eax
movq %rax, -0x18(%rbp)
jmp 0x18d4
movq $0x8000000, -0x18(%rbp) # imm = 0x8000000
cmpl $0x0, -0x8(%rbp)
jne 0x18d2
movq 0x573b(%rip), %rax      # 0x6ff8
movq (%rax), %rdi
movq -0x18(%rbp), %rdx
leaq 0x3866(%rip), %rsi      # 0x5131
movb $0x0, %al
callq 0x1180
jmp 0x18d4
cmpl $0x0, -0xc(%rbp)
jl 0x18e3
cmpl $0x10000, -0xc(%rbp)    # imm = 0x10000
jle 0x1908
movq 0x570e(%rip), %rax      # 0x6ff8
movq (%rax), %rdi
movl -0xc(%rbp), %edx
leaq 0x3885(%rip), %rsi      # 0x517c
movb $0x0, %al
callq 0x1180
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x1230
cmpl $0x0, -0x8(%rbp)
jl 0x1916
movl -0x8(%rbp), %eax
cmpl -0xc(%rbp), %eax
jl 0x193b
movq 0x56db(%rip), %rax      # 0x6ff8
movq (%rax), %rdi
movl -0x8(%rbp), %edx
leaq 0x3877(%rip), %rsi      # 0x51a1
movb $0x0, %al
callq 0x1180
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x1230
movl $0x0, -0x10(%rbp)
movl -0xc(%rbp), %eax
subl $0x1, %eax
movl %eax, -0x48(%rbp)
cmpl $0x0, -0x48(%rbp)
jbe 0x1964
movl -0x10(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x10(%rbp)
movl -0x48(%rbp), %eax
shrl %eax
movl %eax, -0x48(%rbp)
jmp 0x194b
movl -0x4(%rbp), %eax
movl %eax, 0x5883(%rip)      # 0x71f0
movl -0x8(%rbp), %eax
movl %eax, 0x587e(%rip)      # 0x71f4
movl %eax, 0x57bc(%rip)      # 0x7138
movl -0xc(%rbp), %eax
movl %eax, 0x5873(%rip)      # 0x71f8
movl %eax, 0x57b1(%rip)      # 0x713c
movl -0x10(%rbp), %eax
movl %eax, 0x5868(%rip)      # 0x71fc
movq -0x18(%rbp), %rax
movq %rax, 0x59a1(%rip)      # 0x7340
movl $0x0, 0x590f(%rip)      # 0x72b8
leaq 0x5840(%rip), %rdi      # 0x71f0
addq $0xa0, %rdi
movl $0x1, %esi
xorl %edx, %edx
callq 0x11d0
leaq 0x5826(%rip), %rdi      # 0x71f0
addq $0xd0, %rdi
movl $0x1, %esi
xorl %edx, %edx
callq 0x11d0
leaq 0x580c(%rip), %rdi      # 0x71f0
addq $0xf0, %rdi
movl $0x1, %esi
xorl %edx, %edx
callq 0x11d0
leaq 0x57f2(%rip), %rdi      # 0x71f0
addq $0x110, %rdi            # imm = 0x110
movl $0x1, %esi
xorl %edx, %edx
callq 0x11d0
leaq -0x58(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x1ca0
movslq -0xc(%rbp), %rdi
imulq -0x60(%rbp), %rdi
movl -0x4(%rbp), %esi
xorl %edx, %edx
leaq -0x4c(%rbp), %rcx
callq 0x1d40
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rdi
movslq -0x8(%rbp), %rax
imulq -0x60(%rbp), %rax
addq %rax, %rdi
movq -0x60(%rbp), %rsi
callq 0x11c0
movl -0x4c(%rbp), %edi
movslq -0x8(%rbp), %rsi
imulq -0x60(%rbp), %rsi
movq -0x58(%rbp), %rdx
movq -0x60(%rbp), %rcx
callq 0x1fa0
movl -0x4c(%rbp), %eax
movl %eax, 0x58ac(%rip)      # 0x7320
movq -0x58(%rbp), %rax
movq %rax, 0x58b1(%rip)      # 0x7330
movq -0x60(%rbp), %rax
movq %rax, 0x589e(%rip)      # 0x7328
movq -0x68(%rbp), %rax
movq %rax, 0x58a3(%rip)      # 0x7338
movslq -0xc(%rbp), %rdi
imulq -0x18(%rbp), %rdi
movl -0x4(%rbp), %esi
movl $0x1, %edx
xorl %eax, %eax
movl %eax, %ecx
callq 0x1d40
movq %rax, -0x70(%rbp)
movq -0x70(%rbp), %rax
movq %rax, 0x588a(%rip)      # 0x7348
movl $0x0, -0x74(%rbp)
movl $0x1, -0x78(%rbp)
movl -0x78(%rbp), %eax
cmpl 0x5723(%rip), %eax      # 0x71f8
jge 0x1b65
movl 0x5713(%rip), %eax      # 0x71f4
addl -0x78(%rbp), %eax
movl %eax, -0x7c(%rbp)
movl -0x7c(%rbp), %eax
cmpl 0x5708(%rip), %eax      # 0x71f8
jl 0x1b00
movl 0x5700(%rip), %ecx      # 0x71f8
movl -0x7c(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x7c(%rbp)
movslq -0x74(%rbp), %rcx
leaq 0x56e5(%rip), %rax      # 0x71f0
addq $0x170, %rax            # imm = 0x170
shlq $0x3, %rcx
addq %rcx, %rax
movq %rax, -0x88(%rbp)
movq -0x88(%rbp), %rdi
movl -0x7c(%rbp), %esi
callq 0x2130
movq %rax, -0x90(%rbp)
movq -0x90(%rbp), %rdx
movslq -0x74(%rbp), %rcx
leaq 0x56a9(%rip), %rax      # 0x71f0
movq %rdx, 0x1b0(%rax,%rcx,8)
movl -0x74(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x74(%rbp)
movl -0x78(%rbp), %eax
shll %eax
movl %eax, -0x78(%rbp)
jmp 0x1acc
movq 0x57dc(%rip), %rax      # 0x7348
movslq -0x8(%rbp), %rcx
imulq -0x18(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0xb0(%rbp)
callq 0x1220
movl %eax, %ecx
movq -0xb0(%rbp), %rax
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, 0x57b6(%rip)      # 0x7350
movq 0x57af(%rip), %rax      # 0x7350
movq %rax, 0x57b0(%rip)      # 0x7358
movq 0x57a1(%rip), %rax      # 0x7350
movq %rax, -0xa0(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0xa8(%rbp)
callq 0x1220
movq -0xa8(%rbp), %rsi
movq -0xa0(%rbp), %rdi
cltq
subq %rax, %rsi
xorl %edx, %edx
callq 0x23f0
movq %rax, 0x5899(%rip)      # 0x7480
leaq 0x5602(%rip), %rdi      # 0x71f0
addq $0xa0, %rdi
xorl %esi, %esi
callq 0x2130
movq %rax, 0x56ad(%rip)      # 0x72b0
cmpl $0x0, -0x8(%rbp)
jne 0x1c1c
leaq 0x55e0(%rip), %rdi      # 0x71f0
addq $0xa0, %rdi
callq 0x1160
leaq 0x55cd(%rip), %rdi      # 0x71f0
addq $0x110, %rdi            # imm = 0x110
callq 0x1160
callq 0x2200
cmpl $0x1, 0x55bd(%rip)      # 0x71f8
jne 0x1c3f
jmp 0x1c89
cmpl $0x0, 0x55ae(%rip)      # 0x71f4
jne 0x1c56
movq 0x5751(%rip), %rax      # 0x73a0
movq $0x1, (%rax)
jmp 0x1c58
movq 0x5701(%rip), %rax      # 0x7360
cmpq $0x0, %rax
jne 0x1c67
jmp 0x1c58
cmpl $0x0, 0x5586(%rip)      # 0x71f4
je 0x1c7e
movq 0x5729(%rip), %rax      # 0x73a0
movq $0x1, (%rax)
movq $0x0, 0x56d7(%rip) # 0x7360
addq $0xb0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)