/* * Copyright (C) 2004 Aleksandar Colovic * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * */ #include "types.h" #include "timer.h" static int nThreadsSoFar = 0; static int nThreadsMax = 0; static int nStackSize = 0; #ifdef LINUX static pthread_mutex_t guard; static pthread_attr_t attr; #elif defined WIN32 static CRITICAL_SECTION guard; #endif #ifdef LINUX void* #elif defined WIN32 unsigned __stdcall #endif doWork(void* pArg) { #ifdef LINUX pthread_mutex_lock(&guard); #elif defined WIN32 EnterCriticalSection(&guard); #endif if (nThreadsSoFar>=nThreadsMax) { #ifdef LINUX pthread_mutex_unlock(&guard); #elif defined WIN32 LeaveCriticalSection(&guard); #endif return 0; } int nDone = -1; THR_HANDLE hThread1; #ifdef LINUX if (0 != (nDone = pthread_create(&hThread1, &attr, doWork, 0))) { cout << "pthread_create failed " << strerror(nDone) << endl; pthread_mutex_unlock(&guard); pthread_exit(0); } #elif defined WIN32 hThread1 = (HANDLE)_beginthreadex( 0, nStackSize, &doWork, 0, 0, 0 ); if (0 == hThread1) { perror("_beginthreadex failed "); LeaveCriticalSection(&guard); _endthreadex(0); } #endif ++nThreadsSoFar; THR_HANDLE hThread2; #ifdef LINUX if (0 != (nDone = pthread_create(&hThread2, &attr, &doWork, 0))) { cout << "pthread_create failed " << strerror(nDone) << endl; pthread_mutex_unlock(&guard); pthread_exit(0); } #elif defined WIN32 hThread2 = (HANDLE)_beginthreadex( 0, nStackSize, &doWork, 0, 0, 0 ); if (0 == hThread2) { perror("_beginthreadex failed "); LeaveCriticalSection(&guard); _endthreadex(0); } #endif ++nThreadsSoFar; #ifdef LINUX pthread_mutex_unlock(&guard); pthread_join(hThread1, 0); pthread_join(hThread2, 0); #elif defined WIN32 LeaveCriticalSection(&guard); WaitForSingleObject(hThread1, INFINITE); CloseHandle(hThread1); WaitForSingleObject(hThread2, INFINITE); CloseHandle(hThread2); #endif return 0; } int main(int argc, char* const argv[]) { Timer timer; timer.start (); nThreadsMax = 2 << ((argc > 1) ? atoi(argv[1])-1 : 0); nStackSize = (argc > 2) ? 1024 * atoi(argv[2]) : -1; #ifdef LINUX pthread_mutex_init(&guard, 0); pthread_attr_init (&attr); int nDone = -1; if (-1 != nStackSize && 0 != (nDone = pthread_attr_setstacksize (&attr, nStackSize))) { cout << "pthread_attr_setstacksize failed: " << strerror(nDone) << endl; return 1; } #elif defined WIN32 InitializeCriticalSection(&guard); #endif THR_HANDLE hThread; #ifdef LINUX pthread_create(&hThread, 0, &doWork, 0); pthread_join(hThread, 0); pthread_attr_destroy (&attr); #elif defined WIN32 hThread = (HANDLE)_beginthreadex( 0, nStackSize, &doWork, 0, 0, 0 ); WaitForSingleObject(hThread, INFINITE ); CloseHandle(hThread); DeleteCriticalSection(&guard); #endif timer.stop(); cout << "Successfully created " << nThreadsSoFar << " threads!" << endl; cout << "Real time: " << timer.seconds() << "sec" << endl; return 0; };