Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Mesa 3-D graphics library
  3.  * Version:  6.5.1
  4.  *
  5.  * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
  6.  *
  7.  * Permission is hereby granted, free of charge, to any person obtaining a
  8.  * copy of this software and associated documentation files (the "Software"),
  9.  * to deal in the Software without restriction, including without limitation
  10.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  11.  * and/or sell copies of the Software, and to permit persons to whom the
  12.  * Software is furnished to do so, subject to the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice shall be included
  15.  * in all copies or substantial portions of the Software.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  18.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  20.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  21.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  22.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  23.  */
  24.  
  25.  
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include "u_compiler.h"
  29. #include "u_thread.h"
  30.  
  31.  
  32. /*
  33.  * This file should still compile even when THREADS is not defined.
  34.  * This is to make things easier to deal with on the makefile scene..
  35.  */
  36. #ifdef THREADS
  37. #include <errno.h>
  38.  
  39. /*
  40.  * Error messages
  41.  */
  42. #define INIT_TSD_ERROR "_glthread_: failed to allocate key for thread specific data"
  43. #define GET_TSD_ERROR "_glthread_: failed to get thread specific data"
  44. #define SET_TSD_ERROR "_glthread_: thread failed to set thread specific data"
  45.  
  46.  
  47. /*
  48.  * Magic number to determine if a TSD object has been initialized.
  49.  * Kind of a hack but there doesn't appear to be a better cross-platform
  50.  * solution.
  51.  */
  52. #define INIT_MAGIC 0xff8adc98
  53.  
  54.  
  55.  
  56. /*
  57.  * POSIX Threads -- The best way to go if your platform supports them.
  58.  *                  Solaris >= 2.5 have POSIX threads, IRIX >= 6.4 reportedly
  59.  *                  has them, and many of the free Unixes now have them.
  60.  *                  Be sure to use appropriate -mt or -D_REENTRANT type
  61.  *                  compile flags when building.
  62.  */
  63. #ifdef PTHREADS
  64.  
  65. unsigned long
  66. u_thread_self(void)
  67. {
  68.    return (unsigned long) pthread_self();
  69. }
  70.  
  71.  
  72. void
  73. u_tsd_init(struct u_tsd *tsd)
  74. {
  75.    if (pthread_key_create(&tsd->key, NULL/*free*/) != 0) {
  76.       perror(INIT_TSD_ERROR);
  77.       exit(-1);
  78.    }
  79.    tsd->initMagic = INIT_MAGIC;
  80. }
  81.  
  82.  
  83. void *
  84. u_tsd_get(struct u_tsd *tsd)
  85. {
  86.    if (tsd->initMagic != (int) INIT_MAGIC) {
  87.       u_tsd_init(tsd);
  88.    }
  89.    return pthread_getspecific(tsd->key);
  90. }
  91.  
  92.  
  93. void
  94. u_tsd_set(struct u_tsd *tsd, void *ptr)
  95. {
  96.    if (tsd->initMagic != (int) INIT_MAGIC) {
  97.       u_tsd_init(tsd);
  98.    }
  99.    if (pthread_setspecific(tsd->key, ptr) != 0) {
  100.       perror(SET_TSD_ERROR);
  101.       exit(-1);
  102.    }
  103. }
  104.  
  105. #endif /* PTHREADS */
  106.  
  107.  
  108.  
  109. /*
  110.  * Win32 Threads.  The only available option for Windows 95/NT.
  111.  * Be sure that you compile using the Multithreaded runtime, otherwise
  112.  * bad things will happen.
  113.  */
  114. #ifdef WIN32
  115.  
  116. static void InsteadOf_exit(int nCode)
  117. {
  118.    DWORD dwErr = GetLastError();
  119. }
  120.  
  121. unsigned long
  122. u_thread_self(void)
  123. {
  124.    return GetCurrentThreadId();
  125. }
  126.  
  127.  
  128. void
  129. u_tsd_init(struct u_tsd *tsd)
  130. {
  131.    tsd->key = TlsAlloc();
  132.    if (tsd->key == TLS_OUT_OF_INDEXES) {
  133.       perror(INIT_TSD_ERROR);
  134.       InsteadOf_exit(-1);
  135.    }
  136.    tsd->initMagic = INIT_MAGIC;
  137. }
  138.  
  139.  
  140. void
  141. u_tsd_destroy(struct u_tsd *tsd)
  142. {
  143.    if (tsd->initMagic != INIT_MAGIC) {
  144.       return;
  145.    }
  146.    TlsFree(tsd->key);
  147.    tsd->initMagic = 0x0;
  148. }
  149.  
  150.  
  151. void *
  152. u_tsd_get(struct u_tsd *tsd)
  153. {
  154.    if (tsd->initMagic != INIT_MAGIC) {
  155.       u_tsd_init(tsd);
  156.    }
  157.    return TlsGetValue(tsd->key);
  158. }
  159.  
  160.  
  161. void
  162. u_tsd_set(struct u_tsd *tsd, void *ptr)
  163. {
  164.    /* the following code assumes that the struct u_tsd has been initialized
  165.       to zero at creation */
  166.    if (tsd->initMagic != INIT_MAGIC) {
  167.       u_tsd_init(tsd);
  168.    }
  169.    if (TlsSetValue(tsd->key, ptr) == 0) {
  170.       perror(SET_TSD_ERROR);
  171.       InsteadOf_exit(-1);
  172.    }
  173. }
  174.  
  175. #endif /* WIN32 */
  176.  
  177. /*
  178.  * BeOS threads
  179.  */
  180. #ifdef BEOS_THREADS
  181.  
  182. unsigned long
  183. u_thread_self(void)
  184. {
  185.    return (unsigned long) find_thread(NULL);
  186. }
  187.  
  188. void
  189. u_tsd_init(struct u_tsd *tsd)
  190. {
  191.    tsd->key = tls_allocate();
  192.    tsd->initMagic = INIT_MAGIC;
  193. }
  194.  
  195. void *
  196. u_tsd_get(struct u_tsd *tsd)
  197. {
  198.    if (tsd->initMagic != (int) INIT_MAGIC) {
  199.       u_tsd_init(tsd);
  200.    }
  201.    return tls_get(tsd->key);
  202. }
  203.  
  204. void
  205. u_tsd_set(struct u_tsd *tsd, void *ptr)
  206. {
  207.    if (tsd->initMagic != (int) INIT_MAGIC) {
  208.       u_tsd_init(tsd);
  209.    }
  210.    tls_set(tsd->key, ptr);
  211. }
  212.  
  213. #endif /* BEOS_THREADS */
  214.  
  215.  
  216.  
  217. #else  /* THREADS */
  218.  
  219.  
  220. /*
  221.  * no-op functions
  222.  */
  223.  
  224. unsigned long
  225. _glthread_GetID(void)
  226. {
  227.    return 0;
  228. }
  229.  
  230.  
  231. void
  232. u_tsd_init(struct u_tsd *tsd)
  233. {
  234.    (void) tsd;
  235. }
  236.  
  237.  
  238. void *
  239. u_tsd_get(struct u_tsd *tsd)
  240. {
  241.    (void) tsd;
  242.    return NULL;
  243. }
  244.  
  245.  
  246. void
  247. u_tsd_set(struct u_tsd *tsd, void *ptr)
  248. {
  249.    (void) tsd;
  250.    (void) ptr;
  251. }
  252.  
  253.  
  254. #endif /* THREADS */
  255.