home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mesa5.zip / mesa5src.zip / MesaDLL / glthread.cpp < prev    next >
C/C++ Source or Header  |  2002-12-12  |  8KB  |  369 lines

  1. /* $Id: glthread.c,v 1.10 2002/10/24 23:57:20 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  4.1
  6.  *
  7.  * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
  8.  *
  9.  * Permission is hereby granted, free of charge, to any person obtaining a
  10.  * copy of this software and associated documentation files (the "Software"),
  11.  * to deal in the Software without restriction, including without limitation
  12.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  13.  * and/or sell copies of the Software, and to permit persons to whom the
  14.  * Software is furnished to do so, subject to the following conditions:
  15.  *
  16.  * The above copyright notice and this permission notice shall be included
  17.  * in all copies or substantial portions of the Software.
  18.  *
  19.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  20.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  22.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  23.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  24.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  */
  26.  
  27.  
  28. /*
  29.  * XXX There's probably some work to do in order to make this file
  30.  * truly reusable outside of Mesa.  First, the glheader.h include must go.
  31.  */
  32.  
  33.  
  34. #include "glheader.h"
  35. #include "glthread.h"
  36.  
  37.  
  38. /*
  39.  * This file should still compile even when THREADS is not defined.
  40.  * This is to make things easier to deal with on the makefile scene..
  41.  */
  42. #ifdef THREADS
  43. #include <errno.h>
  44.  
  45. /*
  46.  * Error messages
  47.  */
  48. #define INIT_TSD_ERROR "_glthread_: failed to allocate key for thread specific data"
  49. #define GET_TSD_ERROR "_glthread_: failed to get thread specific data"
  50. #define SET_TSD_ERROR "_glthread_: thread failed to set thread specific data"
  51.  
  52.  
  53. /*
  54.  * Magic number to determine if a TSD object has been initialized.
  55.  * Kind of a hack but there doesn't appear to be a better cross-platform
  56.  * solution.
  57.  */
  58. #define INIT_MAGIC 0xff8adc98
  59.  
  60.  
  61.  
  62. /*
  63.  * POSIX Threads -- The best way to go if your platform supports them.
  64.  *                  Solaris >= 2.5 have POSIX threads, IRIX >= 6.4 reportedly
  65.  *                  has them, and many of the free Unixes now have them.
  66.  *                  Be sure to use appropriate -mt or -D_REENTRANT type
  67.  *                  compile flags when building.
  68.  */
  69. #ifdef PTHREADS
  70.  
  71. unsigned long
  72. _glthread_GetID(void)
  73. {
  74.    return (unsigned long) pthread_self();
  75. }
  76.  
  77.  
  78. void
  79. _glthread_InitTSD(_glthread_TSD *tsd)
  80. {
  81.    if (pthread_key_create(&tsd->key, NULL/*free*/) != 0) {
  82.       perror(INIT_TSD_ERROR);
  83.       exit(-1);
  84.    }
  85.    tsd->initMagic = INIT_MAGIC;
  86. }
  87.  
  88.  
  89. void *
  90. _glthread_GetTSD(_glthread_TSD *tsd)
  91. {
  92.    if (tsd->initMagic != (int) INIT_MAGIC) {
  93.       _glthread_InitTSD(tsd);
  94.    }
  95.    return pthread_getspecific(tsd->key);
  96. }
  97.  
  98.  
  99. void
  100. _glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
  101. {
  102.    if (tsd->initMagic != (int) INIT_MAGIC) {
  103.       _glthread_InitTSD(tsd);
  104.    }
  105.    if (pthread_setspecific(tsd->key, ptr) != 0) {
  106.       perror(SET_TSD_ERROR);
  107.       exit(-1);
  108.    }
  109. }
  110.  
  111. #endif /* PTHREADS */
  112.  
  113.  
  114.  
  115. /*
  116.  * Solaris/Unix International Threads -- Use only if POSIX threads
  117.  *   aren't available on your Unix platform.  Solaris 2.[34] are examples
  118.  *   of platforms where this is the case.  Be sure to use -mt and/or
  119.  *   -D_REENTRANT when compiling.
  120.  */
  121. #ifdef SOLARIS_THREADS
  122. #define USE_LOCK_FOR_KEY       /* undef this to try a version without
  123.                                   lock for the global key... */
  124.  
  125. unsigned long
  126. _glthread_GetID(void)
  127. {
  128.    abort();   /* XXX not implemented yet */
  129.    return (unsigned long) 0;
  130. }
  131.  
  132.  
  133. void
  134. _glthread_InitTSD(_glthread_TSD *tsd)
  135. {
  136.    if ((errno = mutex_init(&tsd->keylock, 0, NULL)) != 0 ||
  137.       (errno = thr_keycreate(&(tsd->key), free)) != 0) {
  138.       perror(INIT_TSD_ERROR);
  139.       exit(-1);
  140.    }
  141.    tsd->initMagic = INIT_MAGIC;
  142. }
  143.  
  144.  
  145. void *
  146. _glthread_GetTSD(_glthread_TSD *tsd)
  147. {
  148.    void* ret;
  149.    if (tsd->initMagic != INIT_MAGIC) {
  150.       _glthread_InitTSD(tsd);
  151.    }
  152. #ifdef USE_LOCK_FOR_KEY
  153.    mutex_lock(&tsd->keylock);
  154.    thr_getspecific(tsd->key, &ret);
  155.    mutex_unlock(&tsd->keylock);
  156. #else
  157.    if ((errno = thr_getspecific(tsd->key, &ret)) != 0) {
  158.       perror(GET_TSD_ERROR);
  159.       exit(-1);
  160.    }
  161. #endif
  162.    return ret;
  163. }
  164.  
  165.  
  166. void
  167. _glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
  168. {
  169.    if (tsd->initMagic != INIT_MAGIC) {
  170.       _glthread_InitTSD(tsd);
  171.    }
  172.    if ((errno = thr_setspecific(tsd->key, ptr)) != 0) {
  173.       perror(SET_TSD_ERROR);
  174.       exit(-1);
  175.    }
  176. }
  177.  
  178. #undef USE_LOCK_FOR_KEY
  179. #endif /* SOLARIS_THREADS */
  180.  
  181.  
  182.  
  183. /*
  184.  * Win32 Threads.  The only available option for Windows 95/NT.
  185.  * Be sure that you compile using the Multithreaded runtime, otherwise
  186.  * bad things will happen.
  187.  */
  188. #ifdef WIN32_THREADS
  189.  
  190. unsigned long
  191. _glthread_GetID(void)
  192. {
  193.    abort();   /* XXX not implemented yet */
  194.    return (unsigned long) 0;
  195. }
  196.  
  197.  
  198. void
  199. _glthread_InitTSD(_glthread_TSD *tsd)
  200. {
  201.    tsd->key = TlsAlloc();
  202.    if (tsd->key == 0xffffffff) {
  203.       /* Can Windows handle stderr messages for non-console
  204.          applications? Does Windows have perror? */
  205.       /* perror(SET_INIT_ERROR);*/
  206.       exit(-1);
  207.    }
  208.    tsd->initMagic = INIT_MAGIC;
  209. }
  210.  
  211.  
  212. void *
  213. _glthread_GetTSD(_glthread_TSD *tsd)
  214. {
  215.    if (tsd->initMagic != INIT_MAGIC) {
  216.       _glthread_InitTSD(tsd);
  217.    }
  218.    return TlsGetValue(tsd->key);
  219. }
  220.  
  221.  
  222. void
  223. _glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
  224. {
  225.    /* the following code assumes that the _glthread_TSD has been initialized
  226.       to zero at creation */
  227.    if (tsd->initMagic != INIT_MAGIC) {
  228.       _glthread_InitTSD(tsd);
  229.    }
  230.    if (TlsSetValue(tsd->key, ptr) == 0) {
  231.       /* Can Windows handle stderr messages for non-console
  232.          applications? Does Windows have perror? */
  233.       /* perror(SET_TSD_ERROR);*/
  234.       exit(-1);
  235.    }
  236. }
  237.  
  238. #endif /* WIN32_THREADS */
  239.  
  240.  
  241.  
  242. /*
  243.  * XFree86 has its own thread wrapper, Xthreads.h
  244.  * We wrap it again for GL.
  245.  */
  246. #ifdef XTHREADS
  247.  
  248. unsigned long
  249. _glthread_GetID(void)
  250. {
  251.    return (unsigned long) xthread_self();
  252. }
  253.  
  254.  
  255. void
  256. _glthread_InitTSD(_glthread_TSD *tsd)
  257. {
  258.    if (xthread_key_create(&tsd->key, NULL) != 0) {
  259.       perror(INIT_TSD_ERROR);
  260.       exit(-1);
  261.    }
  262.    tsd->initMagic = INIT_MAGIC;
  263. }
  264.  
  265.  
  266. void *
  267. _glthread_GetTSD(_glthread_TSD *tsd)
  268. {
  269.    void *ptr;
  270.    if (tsd->initMagic != INIT_MAGIC) {
  271.       _glthread_InitTSD(tsd);
  272.    }
  273.    xthread_get_specific(tsd->key, &ptr);
  274.    return ptr;
  275. }
  276.  
  277.  
  278. void
  279. _glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
  280. {
  281.    if (tsd->initMagic != INIT_MAGIC) {
  282.       _glthread_InitTSD(tsd);
  283.    }
  284.    xthread_set_specific(tsd->key, ptr);
  285. }
  286.  
  287. #endif /* XTHREAD */
  288.  
  289.  
  290.  
  291. /*
  292.  * BeOS threads
  293.  */
  294. #ifdef BEOS_THREADS
  295.  
  296. unsigned long
  297. _glthread_GetID(void)
  298. {
  299.    return (unsigned long) find_thread(NULL);
  300. }
  301.  
  302. void
  303. _glthread_InitTSD(_glthread_TSD *tsd)
  304. {
  305.    tsd->key = tls_allocate();
  306.    tsd->initMagic = INIT_MAGIC;
  307. }
  308.  
  309. void *
  310. _glthread_GetTSD(_glthread_TSD *tsd)
  311. {
  312.    if (tsd->initMagic != (int) INIT_MAGIC) {
  313.       _glthread_InitTSD(tsd);
  314.    }
  315.    return tls_get(tsd->key);
  316. }
  317.  
  318. void
  319. _glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
  320. {
  321.    if (tsd->initMagic != (int) INIT_MAGIC) {
  322.       _glthread_InitTSD(tsd);
  323.    }
  324.    tls_set(tsd->key, ptr);
  325. }
  326.  
  327. #endif /* BEOS_THREADS */
  328.  
  329.  
  330.  
  331. #else  /* THREADS */
  332.  
  333.  
  334. /*
  335.  * no-op functions
  336.  */
  337.  
  338. unsigned long
  339. _glthread_GetID(void)
  340. {
  341.    return 0;
  342. }
  343.  
  344.  
  345. void
  346. _glthread_InitTSD(_glthread_TSD *tsd)
  347. {
  348. //   (void) tsd;
  349. }
  350.  
  351.  
  352. void *
  353. _glthread_GetTSD(_glthread_TSD *tsd)
  354. {
  355. //   (void) tsd;
  356.    return NULL;
  357. }
  358.  
  359.  
  360. void
  361. _glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
  362. {
  363. //   (void) tsd;
  364. //   (void) ptr;
  365. }
  366.  
  367.  
  368. #endif /* THREADS */
  369.