// File: epfml[P]Bi-Sent2Vec/src/shmem_matrix.cc
// Function: fasttext::ShmemMatrix::ShmemMatrix(char const*, long, long, int)
ShmemMatrix::ShmemMatrix(const char* name, const int64_t m, const int64_t n, const int timeout_sec) {
  m_ = m;
  n_ = n;

  // Open an existing shared memory segment (keep retrying until timeout expires)
  int fd = -1;
  int waited_sec = 0;
  while (true) {
    fd = shm_open(name, O_RDONLY, 0444);
    if (fd != -1) break;
    if (errno == ENOENT) {
      if (timeout_sec != -1 && waited_sec >= timeout_sec) {
        fprintf(stderr, "ERROR ShmemMatrix::ShmemMatrix: timeout expired\n");
        exit(-1);
      } else {
        sleep(1);
        waited_sec += 1;
      }
    } else {
      perror("ERROR ShmemMatrix::ShmemMatrix: shm_open failed");
      exit(-1);
    }
  }

  // Map the shared memory segment
  size_t size = m_ * n_ * sizeof(real);
  void* ptr = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
  if (ptr == (void*)-1) {
    perror("ERROR ShmemMatrix::ShmemMatrix: mmap failed");
    exit(-1);
  } else {
    data_ = (real*)ptr;
  }

  // Close the file descriptor
  int ret = close(fd);
  if (ret == -1) {
    perror("ERROR ShmemMatrix::ShmemMatrix: close failed");
    exit(-1);
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movl %r8d, -0x24(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x60(%rbp)
callq 0x1ddd0
movq -0x60(%rbp), %rax
movq -0x18(%rbp), %rcx
movq %rcx, 0x8(%rax)
movq -0x20(%rbp), %rcx
movq %rcx, 0x10(%rax)
movl $0xffffffff, -0x28(%rbp) # imm = 0xFFFFFFFF
movl $0x0, -0x2c(%rbp)
jmp 0x1e89d
movq -0x10(%rbp), %rdi
xorl %esi, %esi
movl $0x124, %edx            # imm = 0x124
callq 0x5730
movl %eax, -0x64(%rbp)
jmp 0x1e8b2
movl -0x64(%rbp), %eax
movl %eax, -0x28(%rbp)
cmpl $-0x1, -0x28(%rbp)
je 0x1e8dd
jmp 0x1e94b
movq -0x60(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
callq 0x1df90
jmp 0x1e9e7
callq 0x5080
cmpl $0x2, (%rax)
jne 0x1e92e
cmpl $-0x1, -0x24(%rbp)
je 0x1e917
movl -0x2c(%rbp), %eax
cmpl -0x24(%rbp), %eax
jl 0x1e917
movq 0x406cc(%rip), %rax     # 0x5efc8
movq (%rax), %rdi
leaq 0x24546(%rip), %rsi     # 0x42e4c
movb $0x0, %al
callq 0x5630
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x54f0
movl $0x1, %edi
callq 0x5340
jmp 0x1e923
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x1e946
leaq 0x24548(%rip), %rdi     # 0x42e7d
callq 0x53a0
jmp 0x1e93c
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x54f0
jmp 0x1e89b
movq -0x60(%rbp), %rcx
movq 0x8(%rcx), %rax
imulq 0x10(%rcx), %rax
shlq $0x2, %rax
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rsi
movl -0x28(%rbp), %r8d
xorl %eax, %eax
movl %eax, %r9d
movl $0x1, %ecx
movq %r9, %rdi
movl %ecx, %edx
callq 0x57c0
movq %rax, -0x50(%rbp)
movq $-0x1, %rax
cmpq %rax, -0x50(%rbp)
jne 0x1e9a5
leaq 0x24519(%rip), %rdi     # 0x42ead
callq 0x53a0
jmp 0x1e99b
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x54f0
movq -0x60(%rbp), %rax
movq -0x50(%rbp), %rcx
movq %rcx, (%rax)
movl -0x28(%rbp), %edi
callq 0x5880
movl %eax, -0x68(%rbp)
jmp 0x1e9bd
movl -0x68(%rbp), %eax
movl %eax, -0x54(%rbp)
cmpl $-0x1, -0x54(%rbp)
jne 0x1e9e1
leaq 0x24509(%rip), %rdi     # 0x42ed9
callq 0x53a0
jmp 0x1e9d7
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x54f0
addq $0x70, %rsp
popq %rbp
retq
movq -0x38(%rbp), %rdi
callq 0x57a0