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