| 325 | |
| 326 | template <typename ThreadId, typename ThreadCreateFn, typename ThreadJoinFn> |
| 327 | void PerfTest(uint32_t writer_ratio, ThreadId* /*dummy*/, int thread_num, |
| 328 | const ThreadCreateFn& create_fn, const ThreadJoinFn& join_fn) { |
| 329 | ASSERT_LE(writer_ratio, 100U); |
| 330 | |
| 331 | g_started = false; |
| 332 | g_stopped = false; |
| 333 | bthread_setconcurrency(thread_num + 4); |
| 334 | std::vector<ThreadId> threads(thread_num); |
| 335 | std::vector<PerfArgs> args(thread_num); |
| 336 | bthread_rwlock_t rw; |
| 337 | bthread_rwlock_init(&rw, NULL); |
| 338 | int writer_num = thread_num * writer_ratio / 100; |
| 339 | int reader_num = thread_num - writer_num; |
| 340 | for (int i = 0; i < thread_num; ++i) { |
| 341 | args[i].rw = &rw; |
| 342 | if (i < writer_num) { |
| 343 | ASSERT_EQ(0, create_fn(&threads[i], NULL, add_with_mutex<false>, &args[i])); |
| 344 | } else { |
| 345 | ASSERT_EQ(0, create_fn(&threads[i], NULL, add_with_mutex<true>, &args[i])); |
| 346 | } |
| 347 | } |
| 348 | while (true) { |
| 349 | bool all_ready = true; |
| 350 | for (int i = 0; i < thread_num; ++i) { |
| 351 | if (!args[i].ready) { |
| 352 | all_ready = false; |
| 353 | break; |
| 354 | } |
| 355 | } |
| 356 | if (all_ready) { |
| 357 | break; |
| 358 | } |
| 359 | usleep(1000); |
| 360 | } |
| 361 | g_started = true; |
| 362 | char prof_name[32]; |
| 363 | snprintf(prof_name, sizeof(prof_name), "bthread_rwlock_perf_%d.prof", ++g_prof_name_counter); |
| 364 | ProfilerStart(prof_name); |
| 365 | usleep(1000 * 1000); |
| 366 | ProfilerStop(); |
| 367 | g_stopped = true; |
| 368 | |
| 369 | int64_t read_wait_time = 0; |
| 370 | int64_t read_count = 0; |
| 371 | int64_t write_wait_time = 0; |
| 372 | int64_t write_count = 0; |
| 373 | for (int i = 0; i < thread_num; ++i) { |
| 374 | ASSERT_EQ(0, join_fn(threads[i], NULL)); |
| 375 | if (i < writer_num) { |
| 376 | write_wait_time += args[i].elapse_ns; |
| 377 | write_count += args[i].counter; |
| 378 | } else { |
| 379 | read_wait_time += args[i].elapse_ns; |
| 380 | read_count += args[i].counter; |
| 381 | } |
| 382 | } |
| 383 | LOG(INFO) << "bthread rwlock in " |
| 384 | << ((void*)create_fn == (void*)pthread_create ? "pthread" : "bthread") |
no test coverage detected