// File: trapexit[P]bbf/src/bbf_filethrash.cpp
// Function: bbf::filethrash(Options const&)
AppError
  filethrash(const Options &opts_)
  {
    int rv;
    int cores;
    FileThrashState state;
    struct statfs vfs;
    std::vector<pthread_t> threads;

    printf("Creating file: %s\n",opts_.device.c_str());
    rv = open(opts_.device.c_str(),O_RDWR|O_CREAT|O_SYNC|O_EXCL,0666);
    if(rv == -1)
      return AppError::opening_file(errno,opts_.device);

    state.fd = rv;

    rv = fstatfs(rv,&vfs);
    if(rv == -1)
      goto error;

    state.size = (vfs.f_bavail * vfs.f_frsize);

    printf("Expanding file to fill drive: %lu bytes\n",state.size);
    rv = fallocate(state.fd,FALLOC_FL_ZERO_RANGE,0,state.size);
    if(rv == -1)
      goto error;

    cores = l::nprocs();
    printf("Spawning thrashing threads: %d (one per core)\n",cores);
    for(int i = 0; i < cores; i++)
      l::spawn_thread(l::write_thread,&state,&threads);

    printf("CTRL-C to exit...\n");
    pause();

    l::disable_signals();
    state.is_finished = true;
    for(size_t i = 0; i < threads.size(); i++)
      pthread_join(threads[i],NULL);

    close(state.fd);
    unlink(opts_.device.c_str());

    return AppError::success();

  error:
    close(state.fd);
    unlink(opts_.device.c_str());
    return AppError::opening_file(errno,opts_.device);
  }

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x110, %rsp            # imm = 0x110
movq %rdi, -0xf0(%rbp)
movq %rdi, %rax
movq %rax, -0xe8(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
leaq -0x30(%rbp), %rdi
callq 0xb5d0
leaq -0xc0(%rbp), %rdi
callq 0x7250
movq -0x10(%rbp), %rdi
addq $0x8, %rdi
callq 0x4210
movq %rax, %rsi
leaq 0x1807f(%rip), %rdi     # 0x231af
xorl %eax, %eax
callq 0x4080
jmp 0xb139
movq -0x10(%rbp), %rdi
addq $0x8, %rdi
callq 0x4210
movq %rax, %rdi
xorl %eax, %eax
movl $0x1010c2, %esi         # imm = 0x1010C2
movl $0x1b6, %edx            # imm = 0x1B6
callq 0x43d0
movl %eax, -0xf4(%rbp)
jmp 0xb162
movl -0xf4(%rbp), %eax
movl %eax, -0x14(%rbp)
cmpl $-0x1, -0x14(%rbp)
jne 0xb1c0
callq 0x4070
movq -0xf0(%rbp), %rdi
movl (%rax), %esi
movq -0x10(%rbp), %rdx
addq $0x8, %rdx
callq 0x17890
jmp 0xb18e
movl $0x1, -0xd0(%rbp)
jmp 0xb3b1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
leaq -0xc0(%rbp), %rdi
callq 0x7360
jmp 0xb3cd
movl -0x14(%rbp), %eax
movl %eax, -0x30(%rbp)
movl -0x14(%rbp), %edi
leaq -0xa8(%rbp), %rsi
callq 0x41d0
movl %eax, -0x14(%rbp)
cmpl $-0x1, -0x14(%rbp)
jne 0xb1e3
jmp 0xb36b
movq -0x88(%rbp), %rax
movq -0x60(%rbp), %rcx
imulq %rcx, %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rsi
leaq 0x17fc1(%rip), %rdi     # 0x231c2
xorl %eax, %eax
callq 0x4080
jmp 0xb20a
movl -0x30(%rbp), %edi
movq -0x28(%rbp), %rcx
xorl %eax, %eax
movl %eax, %edx
movl $0x10, %esi
callq 0x4430
movl %eax, -0xf8(%rbp)
jmp 0xb227
movl -0xf8(%rbp), %eax
movl %eax, -0x14(%rbp)
cmpl $-0x1, -0x14(%rbp)
jne 0xb23b
jmp 0xb36b
callq 0xb3e0
movl %eax, -0xfc(%rbp)
jmp 0xb248
movl -0xfc(%rbp), %eax
movl %eax, -0x18(%rbp)
movl -0x18(%rbp), %esi
leaq 0x17f90(%rip), %rdi     # 0x231eb
xorl %eax, %eax
callq 0x4080
jmp 0xb264
movl $0x0, -0xd4(%rbp)
movl -0xd4(%rbp), %eax
cmpl -0x18(%rbp), %eax
jge 0xb2a5
leaq 0x200(%rip), %rdi       # 0xb480
leaq -0x30(%rbp), %rsi
leaq -0xc0(%rbp), %rdx
callq 0xb3f0
jmp 0xb292
jmp 0xb294
movl -0xd4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xd4(%rbp)
jmp 0xb26e
leaq 0x17f6e(%rip), %rdi     # 0x2321a
xorl %eax, %eax
callq 0x4080
jmp 0xb2b5
callq 0x40b0
jmp 0xb2bc
callq 0xb5a0
jmp 0xb2c3
movb $0x1, -0x20(%rbp)
movq $0x0, -0xe0(%rbp)
movq -0xe0(%rbp), %rax
movq %rax, -0x108(%rbp)
leaq -0xc0(%rbp), %rdi
callq 0x58d0
movq %rax, %rcx
movq -0x108(%rbp), %rax
cmpq %rcx, %rax
jae 0xb332
movq -0xe0(%rbp), %rsi
leaq -0xc0(%rbp), %rdi
callq 0xb5f0
movq (%rax), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x44b0
jmp 0xb31c
jmp 0xb31e
movq -0xe0(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xe0(%rbp)
jmp 0xb2d2
movl -0x30(%rbp), %edi
callq 0x4960
jmp 0xb33c
movq -0x10(%rbp), %rdi
addq $0x8, %rdi
callq 0x4210
movq %rax, %rdi
callq 0x4270
movq -0xf0(%rbp), %rdi
callq 0x17420
jmp 0xb35f
movl $0x1, -0xd0(%rbp)
jmp 0xb3b1
movl -0x30(%rbp), %edi
callq 0x4960
jmp 0xb375
movq -0x10(%rbp), %rdi
addq $0x8, %rdi
callq 0x4210
movq %rax, %rdi
callq 0x4270
callq 0x4070
movq -0xf0(%rbp), %rdi
movl (%rax), %esi
movq -0x10(%rbp), %rdx
addq $0x8, %rdx
callq 0x17890
jmp 0xb3a7
movl $0x1, -0xd0(%rbp)
leaq -0xc0(%rbp), %rdi
callq 0x7360
movq -0xe8(%rbp), %rax
addq $0x110, %rsp            # imm = 0x110
popq %rbp
retq
movq -0xc8(%rbp), %rdi
callq 0x4890
nopl (%rax)