18d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveev// A benchmark that executes malloc/free pairs in parallel. 28d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveev// Usage: ./a.out number_of_threads total_number_of_allocations 38d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveev// RUN: %clangxx_lsan %s -o %t 42d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// RUN: %run %t 5 1000000 2>&1 58d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveev#include <assert.h> 68d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveev#include <pthread.h> 78d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveev#include <stdlib.h> 88d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveev#include <stdio.h> 98d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveev 108d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveevint num_threads; 118d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveevint total_num_alloc; 125bd2174c1385ec10b172cc9a32bc33b1967d60b5Alexey Samsonovconst int kMaxNumThreads = 5000; 135bd2174c1385ec10b172cc9a32bc33b1967d60b5Alexey Samsonovpthread_t tid[kMaxNumThreads]; 148d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveev 158d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveevpthread_cond_t cond = PTHREAD_COND_INITIALIZER; 168d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveevpthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 178d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveevbool go = false; 188d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveev 195bd2174c1385ec10b172cc9a32bc33b1967d60b5Alexey Samsonovvoid *thread_fun(void *arg) { 208d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveev pthread_mutex_lock(&mutex); 218d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveev while (!go) pthread_cond_wait(&cond, &mutex); 228d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveev pthread_mutex_unlock(&mutex); 238d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveev for (int i = 0; i < total_num_alloc / num_threads; i++) { 248d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveev void *p = malloc(10); 258d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveev __asm__ __volatile__("" : : "r"(p) : "memory"); 268d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveev free((void *)p); 278d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveev } 288d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveev return 0; 298d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveev} 308d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveev 318d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveevint main(int argc, char** argv) { 328d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveev assert(argc == 3); 338d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveev num_threads = atoi(argv[1]); 348d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveev assert(num_threads > 0); 355bd2174c1385ec10b172cc9a32bc33b1967d60b5Alexey Samsonov assert(num_threads <= kMaxNumThreads); 368d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveev total_num_alloc = atoi(argv[2]); 378d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveev assert(total_num_alloc > 0); 388d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveev printf("%d threads, %d allocations in each\n", num_threads, 398d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveev total_num_alloc / num_threads); 408d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveev for (int i = 0; i < num_threads; i++) 418d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveev pthread_create(&tid[i], 0, thread_fun, 0); 428d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveev pthread_mutex_lock(&mutex); 438d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveev go = true; 448d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveev pthread_cond_broadcast(&cond); 458d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveev pthread_mutex_unlock(&mutex); 468d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveev for (int i = 0; i < num_threads; i++) pthread_join(tid[i], 0); 478d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveev return 0; 488d0c5ba5a63e2934136336db1884804c00932be9Sergey Matveev} 49