// File: shancheng[P]shancheng/db/sqlite_busyhandler_test.cpp
// Function: main
int main(int argc, char* argv[]) {
  po::options_description opts("Options");
  opts.add_options()
    ("threadcount",  po::value<size_t>(), "set thread count")
    ("busytimeout",  po::value<size_t>(), "set busy timeout value (ms)")
    ("debug",                             "debug mode")
    ("help,h",                            "show the help");

  po::variables_map vm;
  po::store(po::parse_command_line(argc, argv, opts), vm);
  po::notify(vm);
  if (vm.count("help") > 0 ) {
    cout << opts << "\n";
    return 0;
  }
  if (vm.count("threadcount") > 0) {
    option.threadcount = vm["threadcount"].as<size_t>();
  }
  if (vm.count("busytimeout") > 0) {
    option.busytimeout = vm["busytimeout"].as<size_t>();
  }
  if (vm.count("debug") > 0) {
    option.debug = true;
  }
  option.Print(cout);

  boost::thread_group threadgroup;
  dbvec.resize(option.threadcount);
  time_t begin = time(NULL);
  for (size_t i = 0; i < option.threadcount; ++i) {
    if (sqlite3_open("concurrencytest.db", &dbvec[i]) != SQLITE_OK) {
      cerr << "Failed to open database\n";
      goto cleanup;
    }
    if (sqlite3_busy_handler(dbvec[i], BusyHandler, NULL) != SQLITE_OK) {
      cerr << "Failed to set busy handler (" << sqlite3_errmsg(dbvec[i]) << ")\n";
      goto cleanup;
    }
  }
  for (size_t i = 0; i < option.threadcount; ++i) {
    threadgroup.create_thread(Job(i, dbvec[i]));
  }
  for (size_t i = 0; ; ++i) {
    sleep(1);
    time_t now = time(NULL);
    cout << i << " IOPS: " << 1000L * total_iocount / (now - begin) << " busy count:" << total_busycount << "\n";
  }
  threadgroup.join_all();

cleanup:
  for (size_t i = 0; i < option.threadcount; ++i) {
    sqlite3_close(dbvec[i]);
  }

  return 0;
}

// Assembly:
subq $0x588, %rsp            # imm = 0x588
movl $0x0, 0x584(%rsp)
movl %edi, 0x580(%rsp)
movq %rsi, 0x578(%rsp)
leaq 0x4d7(%rsp), %rdi
movq %rdi, 0x140(%rsp)
callq 0x9850
movq 0x140(%rsp), %rdx
leaq 0x163e4(%rip), %rsi     # 0x20029
leaq 0x4d8(%rsp), %rdi
callq 0xbea0
jmp 0x9c54
movq 0x252fd(%rip), %rax     # 0x2ef58
movl (%rax), %edx
movl %edx, %ecx
shrl %ecx
leaq 0x4f8(%rsp), %rdi
leaq 0x4d8(%rsp), %rsi
callq 0x9680
jmp 0x9c78
leaq 0x4d8(%rsp), %rdi
callq 0x9948
leaq 0x4d7(%rsp), %rdi
callq 0x94d0
leaq 0x4f8(%rsp), %rdi
callq 0x9580
movq %rax, 0x138(%rsp)
jmp 0x9ca9
movq 0x138(%rsp), %rax
movq %rax, 0x4b8(%rsp)
callq 0xbf60
movq %rax, 0x130(%rsp)
jmp 0x9cc8
movq 0x130(%rsp), %rdx
leaq 0x1635a(%rip), %rsi     # 0x20031
leaq 0x1635f(%rip), %rcx     # 0x2003d
leaq 0x4b8(%rsp), %rdi
callq 0x98e0
movq %rax, 0x128(%rsp)
jmp 0x9cf5
callq 0xbf60
movq %rax, 0x120(%rsp)
jmp 0x9d04
movq 0x120(%rsp), %rdx
movq 0x128(%rsp), %rdi
leaq 0x16333(%rip), %rsi     # 0x2004e
leaq 0x16338(%rip), %rcx     # 0x2005a
callq 0x98e0
movq %rax, 0x118(%rsp)
jmp 0x9d31
movq 0x118(%rsp), %rdi
leaq 0x16336(%rip), %rsi     # 0x20076
leaq 0x16335(%rip), %rdx     # 0x2007c
callq 0x98a0
movq %rax, 0x110(%rsp)
jmp 0x9d56
movq 0x110(%rsp), %rdi
leaq 0x16322(%rip), %rsi     # 0x20087
leaq 0x16322(%rip), %rdx     # 0x2008e
callq 0x98a0
jmp 0x9d73
leaq 0x418(%rsp), %rdi
callq 0x9190
jmp 0x9d82
movl 0x580(%rsp), %eax
movl %eax, 0x104(%rsp)
movq 0x578(%rsp), %rax
movq %rax, 0x108(%rsp)
xorps %xmm0, %xmm0
movaps %xmm0, 0x3e0(%rsp)
movaps %xmm0, 0x3d0(%rsp)
leaq 0x3d0(%rsp), %rdi
callq 0xc0a0
jmp 0x9dc2
movq 0x108(%rsp), %rdx
movl 0x104(%rsp), %esi
leaq 0x3f0(%rsp), %rdi
leaq 0x4f8(%rsp), %rcx
xorl %r8d, %r8d
leaq 0x3d0(%rsp), %r9
callq 0xbf70
jmp 0x9df3
leaq 0x3f0(%rsp), %rdi
leaq 0x418(%rsp), %rsi
xorl %edx, %edx
callq 0x9820
jmp 0x9e0c
leaq 0x3f0(%rsp), %rdi
callq 0xc0b0
leaq 0x3d0(%rsp), %rdi
callq 0xc0c0
leaq 0x418(%rsp), %rdi
callq 0x9270
jmp 0x9e35
leaq 0x428(%rsp), %rax
movq %rax, 0xf0(%rsp)
leaq 0x3af(%rsp), %rdi
movq %rdi, 0xf8(%rsp)
callq 0x9850
movq 0xf8(%rsp), %rdx
leaq 0x1622e(%rip), %rsi     # 0x20097
leaq 0x3b0(%rsp), %rdi
callq 0xbea0
jmp 0x9e78
movq 0xf0(%rsp), %rdi
leaq 0x3b0(%rsp), %rsi
callq 0xc0e0
movq %rax, 0xe8(%rsp)
jmp 0x9e97
leaq 0x3b0(%rsp), %rdi
callq 0x9948
leaq 0x3af(%rsp), %rdi
callq 0x94d0
movq 0xe8(%rsp), %rax
cmpq $0x0, %rax
jbe 0xa01f
movq 0x250e6(%rip), %rdi     # 0x2efb0
leaq 0x4f8(%rsp), %rsi
callq 0x90d0
movq %rax, 0xe0(%rsp)
jmp 0x9ee1
movq 0xe0(%rsp), %rdi
leaq 0x16216(%rip), %rsi     # 0x20106
callq 0x9460
jmp 0x9ef7
movl $0x0, 0x584(%rsp)
movl $0x1, 0x3a8(%rsp)
jmp 0xa7ef
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x4c8(%rsp)
movl %eax, 0x4c4(%rsp)
jmp 0x9f49
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x4c8(%rsp)
movl %eax, 0x4c4(%rsp)
leaq 0x4d8(%rsp), %rdi
callq 0x9948
leaq 0x4d7(%rsp), %rdi
callq 0x94d0
jmp 0xa832
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x4c8(%rsp)
movl %eax, 0x4c4(%rsp)
jmp 0xa825
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x4c8(%rsp)
movl %eax, 0x4c4(%rsp)
jmp 0xa818
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x4c8(%rsp)
movl %eax, 0x4c4(%rsp)
jmp 0x9fc4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x4c8(%rsp)
movl %eax, 0x4c4(%rsp)
leaq 0x3f0(%rsp), %rdi
callq 0xc0b0
leaq 0x3d0(%rsp), %rdi
callq 0xc0c0
jmp 0xa818
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x4c8(%rsp)
movl %eax, 0x4c4(%rsp)
jmp 0xa00d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x4c8(%rsp)
movl %eax, 0x4c4(%rsp)
leaq 0x3b0(%rsp), %rdi
callq 0x9948
leaq 0x3af(%rsp), %rdi
callq 0x94d0
jmp 0xa818
leaq 0x428(%rsp), %rax
movq %rax, 0xd0(%rsp)
leaq 0x387(%rsp), %rdi
movq %rdi, 0xd8(%rsp)
callq 0x9850
movq 0xd8(%rsp), %rdx
leaq 0x15fde(%rip), %rsi     # 0x20031
leaq 0x388(%rsp), %rdi
callq 0xbea0
jmp 0xa062
movq 0xd0(%rsp), %rdi
leaq 0x388(%rsp), %rsi
callq 0xc0e0
movq %rax, 0xc8(%rsp)
jmp 0xa081
leaq 0x388(%rsp), %rdi
callq 0x9948
leaq 0x387(%rsp), %rdi
callq 0x94d0
movq 0xc8(%rsp), %rax
cmpq $0x0, %rax
jbe 0xa1d9
leaq 0x35f(%rsp), %rdi
movq %rdi, 0xc0(%rsp)
callq 0x9850
movq 0xc0(%rsp), %rdx
leaq 0x15f60(%rip), %rsi     # 0x20031
leaq 0x360(%rsp), %rdi
callq 0xbea0
jmp 0xa0e0
leaq 0x418(%rsp), %rdi
leaq 0x360(%rsp), %rsi
callq 0xc140
movq %rax, 0xb8(%rsp)
jmp 0xa0ff
movq 0xb8(%rsp), %rdi
callq 0xc170
movq %rax, 0xb0(%rsp)
jmp 0xa116
movq 0xb0(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x253a8(%rip)     # 0x2f4d0
leaq 0x360(%rsp), %rdi
callq 0x9948
leaq 0x35f(%rsp), %rdi
callq 0x94d0
jmp 0xa1d9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x4c8(%rsp)
movl %eax, 0x4c4(%rsp)
jmp 0xa17e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x4c8(%rsp)
movl %eax, 0x4c4(%rsp)
leaq 0x388(%rsp), %rdi
callq 0x9948
leaq 0x387(%rsp), %rdi
callq 0x94d0
jmp 0xa818
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x4c8(%rsp)
movl %eax, 0x4c4(%rsp)
jmp 0xa1c7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x4c8(%rsp)
movl %eax, 0x4c4(%rsp)
leaq 0x360(%rsp), %rdi
callq 0x9948
leaq 0x35f(%rsp), %rdi
callq 0x94d0
jmp 0xa818
leaq 0x428(%rsp), %rax
movq %rax, 0xa0(%rsp)
leaq 0x337(%rsp), %rdi
movq %rdi, 0xa8(%rsp)
callq 0x9850
movq 0xa8(%rsp), %rdx
leaq 0x15e41(%rip), %rsi     # 0x2004e
leaq 0x338(%rsp), %rdi
callq 0xbea0
jmp 0xa21c
movq 0xa0(%rsp), %rdi
leaq 0x338(%rsp), %rsi
callq 0xc0e0
movq %rax, 0x98(%rsp)
jmp 0xa23b
leaq 0x338(%rsp), %rdi
callq 0x9948
leaq 0x337(%rsp), %rdi
callq 0x94d0
movq 0x98(%rsp), %rax
cmpq $0x0, %rax
jbe 0xa393
leaq 0x30f(%rsp), %rdi
movq %rdi, 0x90(%rsp)
callq 0x9850
movq 0x90(%rsp), %rdx
leaq 0x15dc3(%rip), %rsi     # 0x2004e
leaq 0x310(%rsp), %rdi
callq 0xbea0
jmp 0xa29a
leaq 0x418(%rsp), %rdi
leaq 0x310(%rsp), %rsi
callq 0xc140
movq %rax, 0x88(%rsp)
jmp 0xa2b9
movq 0x88(%rsp), %rdi
callq 0xc170
movq %rax, 0x80(%rsp)
jmp 0xa2d0
movq 0x80(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x251f6(%rip)     # 0x2f4d8
leaq 0x310(%rsp), %rdi
callq 0x9948
leaq 0x30f(%rsp), %rdi
callq 0x94d0
jmp 0xa393
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x4c8(%rsp)
movl %eax, 0x4c4(%rsp)
jmp 0xa338
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x4c8(%rsp)
movl %eax, 0x4c4(%rsp)
leaq 0x338(%rsp), %rdi
callq 0x9948
leaq 0x337(%rsp), %rdi
callq 0x94d0
jmp 0xa818
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x4c8(%rsp)
movl %eax, 0x4c4(%rsp)
jmp 0xa381
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x4c8(%rsp)
movl %eax, 0x4c4(%rsp)
leaq 0x310(%rsp), %rdi
callq 0x9948
leaq 0x30f(%rsp), %rdi
callq 0x94d0
jmp 0xa818
leaq 0x428(%rsp), %rax
movq %rax, 0x70(%rsp)
leaq 0x2e7(%rsp), %rdi
movq %rdi, 0x78(%rsp)
callq 0x9850
movq 0x78(%rsp), %rdx
leaq 0x15cb8(%rip), %rsi     # 0x20076
leaq 0x2e8(%rsp), %rdi
callq 0xbea0
jmp 0xa3cd
movq 0x70(%rsp), %rdi
leaq 0x2e8(%rsp), %rsi
callq 0xc0e0
movq %rax, 0x68(%rsp)
jmp 0xa3e6
leaq 0x2e8(%rsp), %rdi
callq 0x9948
leaq 0x2e7(%rsp), %rdi
callq 0x94d0
movq 0x68(%rsp), %rax
cmpq $0x0, %rax
jbe 0xa45d
movb $0x1, 0x250ce(%rip)     # 0x2f4e0
jmp 0xa45d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x4c8(%rsp)
movl %eax, 0x4c4(%rsp)
jmp 0xa44b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x4c8(%rsp)
movl %eax, 0x4c4(%rsp)
leaq 0x2e8(%rsp), %rdi
callq 0x9948
leaq 0x2e7(%rsp), %rdi
callq 0x94d0
jmp 0xa818
leaq 0x2506c(%rip), %rdi     # 0x2f4d0
movq 0x24b45(%rip), %rsi     # 0x2efb0
callq 0xa840
jmp 0xa472
leaq 0x190(%rsp), %rdi
callq 0xc180
jmp 0xa481
movq 0x25048(%rip), %rsi     # 0x2f4d0
leaq 0x25059(%rip), %rdi     # 0x2f4e8
callq 0xc1d0
jmp 0xa496
xorl %eax, %eax
movl %eax, %edi
callq 0x9430
movq %rax, 0x188(%rsp)
movq $0x0, 0x180(%rsp)
movq 0x180(%rsp), %rax
cmpq 0x2500e(%rip), %rax     # 0x2f4d0
jae 0xa5f6
movq 0x180(%rsp), %rsi
leaq 0x25011(%rip), %rdi     # 0x2f4e8
callq 0xc270
movq %rax, %rsi
leaq 0x15bb6(%rip), %rdi     # 0x2009c
callq 0x9810
movl %eax, 0x64(%rsp)
jmp 0xa4f1
movl 0x64(%rsp), %eax
cmpl $0x0, %eax
je 0xa53a
movq 0x24aef(%rip), %rdi     # 0x2eff0
leaq 0x15ba7(%rip), %rsi     # 0x200af
callq 0x9460
jmp 0xa50f
jmp 0xa779
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x4c8(%rsp)
movl %eax, 0x4c4(%rsp)
leaq 0x190(%rsp), %rdi
callq 0xc290
jmp 0xa818
movq 0x180(%rsp), %rsi
leaq 0x24f9f(%rip), %rdi     # 0x2f4e8
callq 0xc270
movq (%rax), %rdi
leaq 0x3d8(%rip), %rsi       # 0xa930
xorl %eax, %eax
movl %eax, %edx
callq 0x94e0
movl %eax, 0x60(%rsp)
jmp 0xa567
movl 0x60(%rsp), %eax
cmpl $0x0, %eax
je 0xa5db
movq 0x24a79(%rip), %rdi     # 0x2eff0
leaq 0x15b4a(%rip), %rsi     # 0x200c8
callq 0x9460
movq %rax, 0x58(%rsp)
jmp 0xa58a
movq 0x180(%rsp), %rsi
leaq 0x24f4f(%rip), %rdi     # 0x2f4e8
callq 0xc270
movq (%rax), %rdi
callq 0x9450
movq %rax, 0x50(%rsp)
jmp 0xa5ad
movq 0x50(%rsp), %rsi
movq 0x58(%rsp), %rdi
callq 0x9460
movq %rax, 0x48(%rsp)
jmp 0xa5c3
movq 0x48(%rsp), %rdi
leaq 0x15b16(%rip), %rsi     # 0x200e5
callq 0x9460
jmp 0xa5d6
jmp 0xa779
jmp 0xa5dd
movq 0x180(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x180(%rsp)
jmp 0xa4b3
movq $0x0, 0x178(%rsp)
movq 0x178(%rsp), %rax
cmpq 0x24ebf(%rip), %rax     # 0x2f4d0
jae 0xa687
movq 0x178(%rsp), %rsi
movl %esi, %eax
movl %eax, 0x44(%rsp)
leaq 0x24ec0(%rip), %rdi     # 0x2f4e8
callq 0xc270
movl 0x44(%rsp), %esi
movq (%rax), %rdx
leaq 0x160(%rsp), %rdi
callq 0xaa70
jmp 0xa643
movq 0x170(%rsp), %rcx
movq %rsp, %rax
movq %rcx, 0x10(%rax)
movups 0x160(%rsp), %xmm0
movups %xmm0, (%rax)
leaq 0x190(%rsp), %rdi
callq 0xa960
jmp 0xa66c
jmp 0xa66e
movq 0x178(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x178(%rsp)
jmp 0xa602
movq $0x0, 0x158(%rsp)
movl $0x1, %edi
callq 0x9360
jmp 0xa69f
xorl %eax, %eax
movl %eax, %edi
callq 0x9430
movq %rax, 0x150(%rsp)
movq 0x158(%rsp), %rsi
movq 0x248f1(%rip), %rdi     # 0x2efb0
callq 0x90e0
movq %rax, 0x38(%rsp)
jmp 0xa6cb
movq 0x38(%rsp), %rdi
leaq 0x15a11(%rip), %rsi     # 0x200e8
callq 0x9460
movq %rax, 0x30(%rsp)
jmp 0xa6e3
movq 0x30(%rsp), %rdi
movl 0x24e12(%rip), %eax     # 0x2f500
imulq $0x3e8, %rax, %rax      # imm = 0x3E8
movq 0x150(%rsp), %rcx
movq 0x188(%rsp), %rdx
subq %rdx, %rcx
xorl %edx, %edx
idivq %rcx
movq %rax, %rsi
callq 0x9890
movq %rax, 0x28(%rsp)
jmp 0xa71c
movq 0x28(%rsp), %rdi
leaq 0x159c8(%rip), %rsi     # 0x200f0
callq 0x9460
movq %rax, 0x20(%rsp)
jmp 0xa734
movq 0x20(%rsp), %rdi
movl 0x24dc5(%rip), %esi     # 0x2f504
callq 0x9620
movq %rax, 0x18(%rsp)
jmp 0xa74b
movq 0x18(%rsp), %rdi
leaq 0x159af(%rip), %rsi     # 0x20106
callq 0x9460
jmp 0xa75e
jmp 0xa760
movq 0x158(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x158(%rsp)
jmp 0xa693
movq $0x0, 0x148(%rsp)
movq 0x148(%rsp), %rax
cmpq 0x24d3c(%rip), %rax     # 0x2f4d0
jae 0xa7cc
movq 0x148(%rsp), %rsi
leaq 0x24d43(%rip), %rdi     # 0x2f4e8
callq 0xc270
movq (%rax), %rdi
callq 0x9200
jmp 0xa7b4
jmp 0xa7b6
movq 0x148(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x148(%rsp)
jmp 0xa785
movl $0x0, 0x584(%rsp)
movl $0x1, 0x3a8(%rsp)
leaq 0x190(%rsp), %rdi
callq 0xc290
leaq 0x418(%rsp), %rdi
callq 0xc330
leaq 0x4f8(%rsp), %rdi
callq 0xc390
movl 0x584(%rsp), %eax
addq $0x588, %rsp            # imm = 0x588
retq
leaq 0x418(%rsp), %rdi
callq 0xc330
leaq 0x4f8(%rsp), %rdi
callq 0xc390
movq 0x4c8(%rsp), %rdi
callq 0x9830
nop