// File: /workspace/github_cpp_makefile_star2_O3/williewillus[P]panda_scratchpad/src/wrapper/workload.cpp
// Function: wrapper::WriteDataMmap(int, unsigned int, unsigned int)
int WriteDataMmap(int fd, unsigned int offset, unsigned int size) {
  const unsigned int map_size = size + (offset & ((1 << 12) - 1));
  char *filep = (char *) mmap(NULL, size, PROT_WRITE | PROT_READ, MAP_SHARED,
      fd, offset & ~((1 << 12) - 1));
  if (filep == MAP_FAILED) {
    return -1;
  }

  // Offset into a data block to start working at.
  const unsigned int rounded_offset_diff =
    ((offset + (kTestDataSize - 1)) & (~(kTestDataSize - 1))) - offset;

  // The start of the write range is not aligned with our data blocks.
  // Therefore, we should write out part of a data block for this segment,
  // with the first character in the data block aligning with the data block
  // boundary.
  if (rounded_offset_diff != 0) {
    const char *file_start_offset = filep + (offset & ((1 << 12) - 1));
    const unsigned int test_data_offset = offset & (kTestDataSize - 1);
    memcpy((char *) file_start_offset, kTestDataBlock + test_data_offset,
        kTestDataSize - test_data_offset);
  }

  // Write out the rest of the data for this request. All writes from here out
  // will have their first byte aligned with kTestDataSize.
  unsigned int num_written = 0;
  while (num_written != size - rounded_offset_diff) {
    const unsigned int to_write =
      (num_written + kTestDataSize > size - rounded_offset_diff)
      ? size - rounded_offset_diff - num_written
      : kTestDataSize;
    memcpy(filep + rounded_offset_diff + num_written, kTestDataBlock,
        to_write);
    num_written += to_write;
  }

  if (msync(filep, map_size, MS_SYNC) < 0) {
    munmap(filep, map_size);
    return -1;
  }

  munmap(filep, map_size);
  return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movl %edx, %ebx
movl %esi, %r15d
movl %edi, %r8d
movl %edx, %esi
movl %r15d, %r9d
andl $0xfffff000, %r9d       # imm = 0xFFFFF000
xorl %edi, %edi
movl $0x3, %edx
movl $0x1, %ecx
callq 0x85f0
cmpq $-0x1, %rax
je 0x9c70
movq %rax, %r12
movl %r15d, %r13d
andl $0xfff, %r13d           # imm = 0xFFF
leal 0xfff(%r15), %r14d
andl $0xfffff000, %r14d      # imm = 0xFFFFF000
subl %r15d, %r14d
je 0x9bf3
movl %r13d, %eax
leaq (%r12,%rax), %rdi
leaq 0x451d(%rip), %rsi      # 0xe100
addq %rax, %rsi
movl $0x1000, %edx           # imm = 0x1000
subl %r13d, %edx
callq 0x82d0
movq %r12, -0x38(%rbp)
addl %ebx, %r13d
movl %r13d, -0x2c(%rbp)
subl %r14d, %ebx
je 0x9c46
movl %r14d, %eax
movq -0x38(%rbp), %r14
addq %rax, %r14
xorl %r15d, %r15d
movl $0x1000, %r13d          # imm = 0x1000
leal (%r15,%r13), %eax
movl %ebx, %r12d
subl %r15d, %r12d
cmpl %ebx, %eax
cmovbel %r13d, %r12d
movl %r15d, %edi
addq %r14, %rdi
leaq 0x44cd(%rip), %rsi      # 0xe100
movq %r12, %rdx
callq 0x82d0
addl %r15d, %r12d
movl %r12d, %r15d
cmpl %ebx, %r12d
jne 0x9c16
movl -0x2c(%rbp), %r15d
movq -0x38(%rbp), %r14
movq %r14, %rdi
movq %r15, %rsi
movl $0x4, %edx
callq 0x8080
movl %eax, %ebx
movq %r14, %rdi
movq %r15, %rsi
callq 0x81f0
sarl $0x1f, %ebx
jmp 0x9c75
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
movl %ebx, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop