home *** CD-ROM | disk | FTP | other *** search
/ PC PowerPlay 22 / PCPP #22.iso / Quake2 / q2source_12_11 / utils3 / common / threads.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-08-09  |  7.0 KB  |  428 lines

  1.  
  2. #include "cmdlib.h"
  3. #include "threads.h"
  4.  
  5. #define    MAX_THREADS    64
  6.  
  7. int        dispatch;
  8. int        workcount;
  9. int        oldf;
  10. qboolean        pacifier;
  11.  
  12. qboolean    threaded;
  13.  
  14. /*
  15. =============
  16. GetThreadWork
  17.  
  18. =============
  19. */
  20. int    GetThreadWork (void)
  21. {
  22.     int    r;
  23.     int    f;
  24.  
  25.     ThreadLock ();
  26.  
  27.     if (dispatch == workcount)
  28.     {
  29.         ThreadUnlock ();
  30.         return -1;
  31.     }
  32.  
  33.     f = 10*dispatch / workcount;
  34.     if (f != oldf)
  35.     {
  36.         oldf = f;
  37.         if (pacifier)
  38.             printf ("%i...", f);
  39.     }
  40.  
  41.     r = dispatch;
  42.     dispatch++;
  43.     ThreadUnlock ();
  44.  
  45.     return r;
  46. }
  47.  
  48.  
  49. void (*workfunction) (int);
  50.  
  51. void ThreadWorkerFunction (int threadnum)
  52. {
  53.     int        work;
  54.  
  55.     while (1)
  56.     {
  57.         work = GetThreadWork ();
  58.         if (work == -1)
  59.             break;
  60. //printf ("thread %i, work %i\n", threadnum, work);
  61.         workfunction(work);
  62.     }
  63. }
  64.  
  65. void RunThreadsOnIndividual (int workcnt, qboolean showpacifier, void(*func)(int))
  66. {
  67.     if (numthreads == -1)
  68.         ThreadSetDefault ();
  69.     workfunction = func;
  70.     RunThreadsOn (workcnt, showpacifier, ThreadWorkerFunction);
  71. }
  72.  
  73.  
  74. /*
  75. ===================================================================
  76.  
  77. WIN32
  78.  
  79. ===================================================================
  80. */
  81. #ifdef WIN32
  82.  
  83. #define    USED
  84.  
  85. #include <windows.h>
  86.  
  87. int        numthreads = -1;
  88. CRITICAL_SECTION        crit;
  89. static int enter;
  90.  
  91. void ThreadSetDefault (void)
  92. {
  93.     SYSTEM_INFO info;
  94.  
  95.     if (numthreads == -1)    // not set manually
  96.     {
  97.         GetSystemInfo (&info);
  98.         numthreads = info.dwNumberOfProcessors;
  99.         if (numthreads < 1 || numthreads > 32)
  100.             numthreads = 1;
  101.     }
  102.  
  103.     qprintf ("%i threads\n", numthreads);
  104. }
  105.  
  106.  
  107. void ThreadLock (void)
  108. {
  109.     if (!threaded)
  110.         return;
  111.     EnterCriticalSection (&crit);
  112.     if (enter)
  113.         Error ("Recursive ThreadLock\n");
  114.     enter = 1;
  115. }
  116.  
  117. void ThreadUnlock (void)
  118. {
  119.     if (!threaded)
  120.         return;
  121.     if (!enter)
  122.         Error ("ThreadUnlock without lock\n");
  123.     enter = 0;
  124.     LeaveCriticalSection (&crit);
  125. }
  126.  
  127. /*
  128. =============
  129. RunThreadsOn
  130. =============
  131. */
  132. void RunThreadsOn (int workcnt, qboolean showpacifier, void(*func)(int))
  133. {
  134.     int        threadid[MAX_THREADS];
  135.     HANDLE    threadhandle[MAX_THREADS];
  136.     int        i;
  137.     int        start, end;
  138.  
  139.     start = I_FloatTime ();
  140.     dispatch = 0;
  141.     workcount = workcnt;
  142.     oldf = -1;
  143.     pacifier = showpacifier;
  144.     threaded = true;
  145.  
  146.     //
  147.     // run threads in parallel
  148.     //
  149.     InitializeCriticalSection (&crit);
  150.  
  151.     if (numthreads == 1)
  152.     {    // use same thread
  153.         func (0);
  154.     }
  155.     else
  156.     {
  157.         for (i=0 ; i<numthreads ; i++)
  158.         {
  159.             threadhandle[i] = CreateThread(
  160.                NULL,    // LPSECURITY_ATTRIBUTES lpsa,
  161.                0,        // DWORD cbStack,
  162.                (LPTHREAD_START_ROUTINE)func,    // LPTHREAD_START_ROUTINE lpStartAddr,
  163.                (LPVOID)i,    // LPVOID lpvThreadParm,
  164.                0,            //   DWORD fdwCreate,
  165.                &threadid[i]);
  166.         }
  167.  
  168.         for (i=0 ; i<numthreads ; i++)
  169.             WaitForSingleObject (threadhandle[i], INFINITE);
  170.     }
  171.     DeleteCriticalSection (&crit);
  172.  
  173.     threaded = false;
  174.     end = I_FloatTime ();
  175.     if (pacifier)
  176.         printf (" (%i)\n", end-start);
  177. }
  178.  
  179.  
  180. #endif
  181.  
  182. /*
  183. ===================================================================
  184.  
  185. OSF1
  186.  
  187. ===================================================================
  188. */
  189.  
  190. #ifdef __osf__
  191. #define    USED
  192.  
  193. int        numthreads = 4;
  194.  
  195. void ThreadSetDefault (void)
  196. {
  197.     if (numthreads == -1)    // not set manually
  198.     {
  199.         numthreads = 4;
  200.     }
  201. }
  202.  
  203.  
  204. #include <pthread.h>
  205.  
  206. pthread_mutex_t    *my_mutex;
  207.  
  208. void ThreadLock (void)
  209. {
  210.     if (my_mutex)
  211.         pthread_mutex_lock (my_mutex);
  212. }
  213.  
  214. void ThreadUnlock (void)
  215. {
  216.     if (my_mutex)
  217.         pthread_mutex_unlock (my_mutex);
  218. }
  219.  
  220.  
  221. /*
  222. =============
  223. RunThreadsOn
  224. =============
  225. */
  226. void RunThreadsOn (int workcnt, qboolean showpacifier, void(*func)(int))
  227. {
  228.     int        i;
  229.     pthread_t    work_threads[MAX_THREADS];
  230.     pthread_addr_t    status;
  231.     pthread_attr_t    attrib;
  232.     pthread_mutexattr_t    mattrib;
  233.     int        start, end;
  234.  
  235.     start = I_FloatTime ();
  236.     dispatch = 0;
  237.     workcount = workcnt;
  238.     oldf = -1;
  239.     pacifier = showpacifier;
  240.     threaded = true;
  241.  
  242.     if (pacifier)
  243.         setbuf (stdout, NULL);
  244.  
  245.     if (!my_mutex)
  246.     {
  247.         my_mutex = malloc (sizeof(*my_mutex));
  248.         if (pthread_mutexattr_create (&mattrib) == -1)
  249.             Error ("pthread_mutex_attr_create failed");
  250.         if (pthread_mutexattr_setkind_np (&mattrib, MUTEX_FAST_NP) == -1)
  251.             Error ("pthread_mutexattr_setkind_np failed");
  252.         if (pthread_mutex_init (my_mutex, mattrib) == -1)
  253.             Error ("pthread_mutex_init failed");
  254.     }
  255.  
  256.     if (pthread_attr_create (&attrib) == -1)
  257.         Error ("pthread_attr_create failed");
  258.     if (pthread_attr_setstacksize (&attrib, 0x100000) == -1)
  259.         Error ("pthread_attr_setstacksize failed");
  260.     
  261.     for (i=0 ; i<numthreads ; i++)
  262.     {
  263.           if (pthread_create(&work_threads[i], attrib
  264.         , (pthread_startroutine_t)func, (pthread_addr_t)i) == -1)
  265.             Error ("pthread_create failed");
  266.     }
  267.         
  268.     for (i=0 ; i<numthreads ; i++)
  269.     {
  270.         if (pthread_join (work_threads[i], &status) == -1)
  271.             Error ("pthread_join failed");
  272.     }
  273.  
  274.     threaded = false;
  275.  
  276.     end = I_FloatTime ();
  277.     if (pacifier)
  278.         printf (" (%i)\n", end-start);
  279. }
  280.  
  281.  
  282. #endif
  283.  
  284. /*
  285. ===================================================================
  286.  
  287. IRIX
  288.  
  289. ===================================================================
  290. */
  291.  
  292. #ifdef _MIPS_ISA 
  293. #define    USED
  294.  
  295. #include <task.h>
  296. #include <abi_mutex.h>
  297. #include <sys/types.h>
  298. #include <sys/prctl.h>
  299.  
  300.  
  301. int        numthreads = -1;
  302. abilock_t        lck;
  303.  
  304. void ThreadSetDefault (void)
  305. {
  306.     if (numthreads == -1)
  307.         numthreads = prctl(PR_MAXPPROCS);
  308.     printf ("%i threads\n", numthreads);
  309. //@@
  310.     usconfig (CONF_INITUSERS, numthreads);
  311. }
  312.  
  313.  
  314. void ThreadLock (void)
  315. {
  316.     spin_lock (&lck);
  317. }
  318.  
  319. void ThreadUnlock (void)
  320. {
  321.     release_lock (&lck);
  322. }
  323.  
  324.  
  325. /*
  326. =============
  327. RunThreadsOn
  328. =============
  329. */
  330. void RunThreadsOn (int workcnt, qboolean showpacifier, void(*func)(int))
  331. {
  332.     int        i;
  333.     int        pid[MAX_THREADS];
  334.     int        start, end;
  335.  
  336.     start = I_FloatTime ();
  337.     dispatch = 0;
  338.     workcount = workcnt;
  339.     oldf = -1;
  340.     pacifier = showpacifier;
  341.     threaded = true;
  342.  
  343.     if (pacifier)
  344.         setbuf (stdout, NULL);
  345.  
  346.     init_lock (&lck);
  347.  
  348.     for (i=0 ; i<numthreads-1 ; i++)
  349.     {
  350.         pid[i] = sprocsp ( (void (*)(void *, size_t))func, PR_SALL, (void *)i
  351.             , NULL, 0x100000);
  352. //        pid[i] = sprocsp ( (void (*)(void *, size_t))func, PR_SALL, (void *)i
  353. //            , NULL, 0x80000);
  354.         if (pid[i] == -1)
  355.         {
  356.             perror ("sproc");
  357.             Error ("sproc failed");
  358.         }
  359.     }
  360.         
  361.     func(i);
  362.             
  363.     for (i=0 ; i<numthreads-1 ; i++)
  364.         wait (NULL);
  365.  
  366.     threaded = false;
  367.  
  368.     end = I_FloatTime ();
  369.     if (pacifier)
  370.         printf (" (%i)\n", end-start);
  371. }
  372.  
  373.  
  374. #endif
  375.  
  376. /*
  377. =======================================================================
  378.  
  379.   SINGLE THREAD
  380.  
  381. =======================================================================
  382. */
  383.  
  384. #ifndef USED
  385.  
  386. int        numthreads = 1;
  387.  
  388. void ThreadSetDefault (void)
  389. {
  390.     numthreads = 1;
  391. }
  392.  
  393. void ThreadLock (void)
  394. {
  395. }
  396.  
  397. void ThreadUnlock (void)
  398. {
  399. }
  400.  
  401. /*
  402. =============
  403. RunThreadsOn
  404. =============
  405. */
  406. void RunThreadsOn (int workcnt, qboolean showpacifier, void(*func)(int))
  407. {
  408.     int        i;
  409.     int        start, end;
  410.  
  411.     dispatch = 0;
  412.     workcount = workcnt;
  413.     oldf = -1;
  414.     pacifier = showpacifier;
  415.     start = I_FloatTime (); 
  416. #ifdef NeXT
  417.     if (pacifier)
  418.         setbuf (stdout, NULL);
  419. #endif
  420.     func(0);
  421.  
  422.     end = I_FloatTime ();
  423.     if (pacifier)
  424.         printf (" (%i)\n", end-start);
  425. }
  426.  
  427. #endif
  428.