This source file includes following definitions.
- SetTestResourceLimit
 
- RunThread
 
- RunManyThreads
 
- RunManyThreadsWithId
 
- RunFunctionInThread
 
- RunFunctionInThreadWithId
 
- RunManyThreads
 
- RunThread
 
- RunManyThreadsWithId
 
- RunFunctionInThread
 
- RunFunctionInThreadWithId
 
- RunThread
 
- RunManyThreads
 
- RunManyThreadsWithId
 
#include "config_for_unittests.h"
#include <stdlib.h>           
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#ifdef HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
#endif
#include "tests/testutil.h"
void SetTestResourceLimit() {
#ifdef HAVE_SYS_RESOURCE_H
  
  
  
  
#ifdef RLIMIT_AS
#define USE_RESOURCE RLIMIT_AS
#else
#define USE_RESOURCE RLIMIT_RSS
#endif
  
  
  const rlim_t kMaxMem = 1<<30;
  struct rlimit rlim;
  if (getrlimit(USE_RESOURCE, &rlim) == 0) {
    if (rlim.rlim_cur == RLIM_INFINITY || rlim.rlim_cur > kMaxMem) {
      rlim.rlim_cur = kMaxMem;
      setrlimit(USE_RESOURCE, &rlim); 
    }
  }
#endif  
}
struct FunctionAndId {
  void (*ptr_to_function)(int);
  int id;
};
#if defined(NO_THREADS) || !(defined(HAVE_PTHREAD) || defined(_WIN32))
extern "C" void RunThread(void (*fn)()) {
  (*fn)();
}
extern "C" void RunManyThreads(void (*fn)(), int count) {
  
  for (int i = 0; i < count; i++)
    (*fn)();
}
extern "C" void RunManyThreadsWithId(void (*fn)(int), int count, int) {
  for (int i = 0; i < count; i++)
    (*fn)(i);    
}
#elif defined(_WIN32)
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN  
#endif
#include <windows.h>
extern "C" {
  
  DWORD WINAPI RunFunctionInThread(LPVOID ptr_to_ptr_to_fn) {
    (**static_cast<void (**)()>(ptr_to_ptr_to_fn))();    
    return 0;
  }
  DWORD WINAPI RunFunctionInThreadWithId(LPVOID ptr_to_fnid) {
    FunctionAndId* fn_and_id = static_cast<FunctionAndId*>(ptr_to_fnid);
    (*fn_and_id->ptr_to_function)(fn_and_id->id);   
    return 0;
  }
  void RunManyThreads(void (*fn)(), int count) {
    DWORD dummy;
    HANDLE* hThread = new HANDLE[count];
    for (int i = 0; i < count; i++) {
      hThread[i] = CreateThread(NULL, 0, RunFunctionInThread, &fn, 0, &dummy);
      if (hThread[i] == NULL)  ExitProcess(i);
    }
    WaitForMultipleObjects(count, hThread, TRUE, INFINITE);
    for (int i = 0; i < count; i++) {
      CloseHandle(hThread[i]);
    }
    delete[] hThread;
  }
  void RunThread(void (*fn)()) {
    RunManyThreads(fn, 1);
  }
  void RunManyThreadsWithId(void (*fn)(int), int count, int stacksize) {
    DWORD dummy;
    HANDLE* hThread = new HANDLE[count];
    FunctionAndId* fn_and_ids = new FunctionAndId[count];
    for (int i = 0; i < count; i++) {
      fn_and_ids[i].ptr_to_function = fn;
      fn_and_ids[i].id = i;
      hThread[i] = CreateThread(NULL, stacksize, RunFunctionInThreadWithId,
                                &fn_and_ids[i], 0, &dummy);
      if (hThread[i] == NULL)  ExitProcess(i);
    }
    WaitForMultipleObjects(count, hThread, TRUE, INFINITE);
    for (int i = 0; i < count; i++) {
      CloseHandle(hThread[i]);
    }
    delete[] fn_and_ids;
    delete[] hThread;
  }
}
#else  
#include <pthread.h>
#define SAFE_PTHREAD(fncall)  do { if ((fncall) != 0) abort(); } while (0)
extern "C" {
  
  static void* RunFunctionInThread(void *ptr_to_ptr_to_fn) {
    (**static_cast<void (**)()>(ptr_to_ptr_to_fn))();    
    return NULL;
  }
  static void* RunFunctionInThreadWithId(void *ptr_to_fnid) {
    FunctionAndId* fn_and_id = static_cast<FunctionAndId*>(ptr_to_fnid);
    (*fn_and_id->ptr_to_function)(fn_and_id->id);   
    return NULL;
  }
  
  
  
  
  void RunThread(void (*fn)()) {
    pthread_t thr;
    
    
    SAFE_PTHREAD(pthread_create(&thr, NULL, RunFunctionInThread, &fn));
    SAFE_PTHREAD(pthread_join(thr, NULL));
  }
  void RunManyThreads(void (*fn)(), int count) {
    pthread_t* thr = new pthread_t[count];
    for (int i = 0; i < count; i++) {
      SAFE_PTHREAD(pthread_create(&thr[i], NULL, RunFunctionInThread, &fn));
    }
    for (int i = 0; i < count; i++) {
      SAFE_PTHREAD(pthread_join(thr[i], NULL));
    }
    delete[] thr;
  }
  void RunManyThreadsWithId(void (*fn)(int), int count, int stacksize) {
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setstacksize(&attr, stacksize);
    pthread_t* thr = new pthread_t[count];
    FunctionAndId* fn_and_ids = new FunctionAndId[count];
    for (int i = 0; i < count; i++) {
      fn_and_ids[i].ptr_to_function = fn;
      fn_and_ids[i].id = i;
      SAFE_PTHREAD(pthread_create(&thr[i], &attr,
                                  RunFunctionInThreadWithId, &fn_and_ids[i]));
    }
    for (int i = 0; i < count; i++) {
      SAFE_PTHREAD(pthread_join(thr[i], NULL));
    }
    delete[] fn_and_ids;
    delete[] thr;
    pthread_attr_destroy(&attr);
  }
}
#endif