home *** CD-ROM | disk | FTP | other *** search
/ H4CK3R 14 / hacker14.iso / programacao / cwin / c.exe / $INSTDIR / include / c++ / mingw32 / bits / gthr-posix.h < prev    next >
Encoding:
C/C++ Source or Header  |  2003-12-15  |  11.7 KB  |  510 lines

  1. /* Threads compatibility routines for libgcc2 and libobjc.  */
  2. /* Compile this one with gcc.  */
  3. /* Copyright (C) 1997, 1999, 2000, 2001 Free Software Foundation, Inc.
  4.  
  5. This file is part of GCC.
  6.  
  7. GCC is free software; you can redistribute it and/or modify it under
  8. the terms of the GNU General Public License as published by the Free
  9. Software Foundation; either version 2, or (at your option) any later
  10. version.
  11.  
  12. GCC is distributed in the hope that it will be useful, but WITHOUT ANY
  13. WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15. for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with GCC; see the file COPYING.  If not, write to the Free
  19. Software Foundation, 59 Temple Place - Suite 330, Boston, MA
  20. 02111-1307, USA.  */
  21.  
  22. /* As a special exception, if you link this library with other files,
  23.    some of which are compiled with GCC, to produce an executable,
  24.    this library does not by itself cause the resulting executable
  25.    to be covered by the GNU General Public License.
  26.    This exception does not however invalidate any other reasons why
  27.    the executable file might be covered by the GNU General Public License.  */
  28.  
  29. #ifndef _GLIBCPP_GCC_GTHR_POSIX_H
  30. #define _GLIBCPP_GCC_GTHR_POSIX_H
  31.  
  32. /* POSIX threads specific definitions.
  33.    Easy, since the interface is just one-to-one mapping.  */
  34.  
  35. #define __GTHREADS 1
  36.  
  37. #include <pthread.h>
  38.  
  39. typedef pthread_key_t __gthread_key_t;
  40. typedef pthread_once_t __gthread_once_t;
  41. typedef pthread_mutex_t __gthread_mutex_t;
  42.  
  43. #define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
  44. #define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT
  45.  
  46. #if _GLIBCPP_SUPPORTS_WEAK && _GLIBCPP_GTHREAD_USE_WEAK
  47.  
  48. #pragma weak pthread_once
  49. #pragma weak pthread_key_create
  50. #pragma weak pthread_key_delete
  51. #pragma weak pthread_getspecific
  52. #pragma weak pthread_setspecific
  53. #pragma weak pthread_create
  54.  
  55. #pragma weak pthread_mutex_lock 
  56. #pragma weak pthread_mutex_trylock 
  57. #pragma weak pthread_mutex_unlock 
  58.  
  59. #ifdef _LIBOBJC
  60. /* Objective C.  */
  61. #pragma weak pthread_cond_broadcast
  62. #pragma weak pthread_cond_destroy
  63. #pragma weak pthread_cond_init
  64. #pragma weak pthread_cond_signal
  65. #pragma weak pthread_cond_wait
  66. #pragma weak pthread_exit
  67. #pragma weak pthread_mutex_init
  68. #pragma weak pthread_mutex_destroy
  69. #pragma weak pthread_self
  70. #pragma weak sched_get_priority_max
  71. #pragma weak sched_get_priority_min
  72. #pragma weak sched_yield
  73. #pragma weak pthread_attr_destroy
  74. #pragma weak pthread_attr_init
  75. #pragma weak pthread_attr_setdetachstate
  76. #pragma weak pthread_getschedparam
  77. #pragma weak pthread_setschedparam
  78. #endif
  79.  
  80. static inline int
  81. __gthread_active_p (void)
  82. {
  83.   static void *const __gthread_active_ptr = (void *) &pthread_create;
  84.   return __gthread_active_ptr != 0;
  85. }
  86.  
  87. #else /* not _GLIBCPP_SUPPORTS_WEAK */
  88.  
  89. static inline int
  90. __gthread_active_p (void)
  91. {
  92.   return 1;
  93. }
  94.  
  95. #endif /* _GLIBCPP_SUPPORTS_WEAK */
  96.  
  97. #ifdef _LIBOBJC
  98.  
  99. /* This is the config.h file in libobjc/ */
  100. #include <config.h>
  101.  
  102. #ifdef HAVE_SCHED_H
  103. # include <sched.h>
  104. #endif
  105.  
  106. /* Key structure for maintaining thread specific storage */
  107. static pthread_key_t _objc_thread_storage;
  108. static pthread_attr_t _objc_thread_attribs;
  109.  
  110. /* Thread local storage for a single thread */
  111. static void *thread_local_storage = NULL;
  112.  
  113. /* Backend initialization functions */
  114.  
  115. /* Initialize the threads subsystem.  */
  116. static inline int
  117. __gthread_objc_init_thread_system(void)
  118. {
  119.   if (__gthread_active_p ())
  120.     {
  121.       /* Initialize the thread storage key */
  122.       if (pthread_key_create(&_objc_thread_storage, NULL) == 0)
  123.         {
  124.           /* The normal default detach state for threads is
  125.            * PTHREAD_CREATE_JOINABLE which causes threads to not die
  126.            * when you think they should.  */
  127.           if (pthread_attr_init(&_objc_thread_attribs) == 0
  128.               && pthread_attr_setdetachstate(&_objc_thread_attribs, 
  129.                                              PTHREAD_CREATE_DETACHED) == 0)
  130.             return 0;
  131.         }
  132.     }
  133.  
  134.   return -1;
  135. }
  136.  
  137. /* Close the threads subsystem.  */
  138. static inline int
  139. __gthread_objc_close_thread_system(void)
  140. {
  141.   if (__gthread_active_p ()
  142.       && pthread_key_delete(_objc_thread_storage) == 0
  143.       && pthread_attr_destroy(&_objc_thread_attribs) == 0)
  144.     return 0;
  145.  
  146.   return -1;
  147. }
  148.  
  149. /* Backend thread functions */
  150.  
  151. /* Create a new thread of execution.  */
  152. static inline objc_thread_t
  153. __gthread_objc_thread_detach(void (*func)(void *), void *arg)
  154. {
  155.   objc_thread_t thread_id;
  156.   pthread_t new_thread_handle;
  157.  
  158.   if (!__gthread_active_p ())
  159.     return NULL;
  160.  
  161.   if ( !(pthread_create(&new_thread_handle, NULL, (void *)func, arg)) )
  162.     thread_id = (objc_thread_t) new_thread_handle;
  163.   else
  164.     thread_id = NULL;
  165.   
  166.   return thread_id;
  167. }
  168.  
  169. /* Set the current thread's priority.  */
  170. static inline int
  171. __gthread_objc_thread_set_priority(int priority)
  172. {
  173.   if (!__gthread_active_p())
  174.     return -1;
  175.   else {
  176.     pthread_t thread_id = pthread_self();
  177.     int policy;
  178.     struct sched_param params;
  179.     int priority_min, priority_max;
  180.  
  181.     if (pthread_getschedparam(thread_id, &policy, ¶ms) == 0)
  182.       {
  183.         if ((priority_max = sched_get_priority_max(policy)) != 0)
  184.           return -1;
  185.  
  186.         if ((priority_min = sched_get_priority_min(policy)) != 0)
  187.           return -1;
  188.  
  189.         if (priority > priority_max)
  190.           priority = priority_max;
  191.         else if (priority < priority_min)
  192.           priority = priority_min;
  193.         params.sched_priority = priority;
  194.  
  195.         /*
  196.          * The solaris 7 and several other man pages incorrectly state that
  197.          * this should be a pointer to policy but pthread.h is universally
  198.          * at odds with this.
  199.          */
  200.         if (pthread_setschedparam(thread_id, policy, ¶ms) == 0)
  201.           return 0;
  202.       }
  203.     return -1;
  204.   }
  205. }
  206.  
  207. /* Return the current thread's priority.  */
  208. static inline int
  209. __gthread_objc_thread_get_priority(void)
  210. {
  211.   if (__gthread_active_p ())
  212.     {
  213.       int policy;
  214.       struct sched_param params;
  215.  
  216.       if (pthread_getschedparam(pthread_self(), &policy, ¶ms) == 0)
  217.         return params.sched_priority;
  218.       else
  219.         return -1;
  220.     }
  221.   else
  222.     return OBJC_THREAD_INTERACTIVE_PRIORITY;
  223. }
  224.  
  225. /* Yield our process time to another thread.  */
  226. static inline void
  227. __gthread_objc_thread_yield(void)
  228. {
  229.   if (__gthread_active_p ())
  230.     sched_yield();
  231. }
  232.  
  233. /* Terminate the current thread.  */
  234. static inline int
  235. __gthread_objc_thread_exit(void)
  236. {
  237.   if (__gthread_active_p ())
  238.     /* exit the thread */
  239.     pthread_exit(&__objc_thread_exit_status);
  240.  
  241.   /* Failed if we reached here */
  242.   return -1;
  243. }
  244.  
  245. /* Returns an integer value which uniquely describes a thread.  */
  246. static inline objc_thread_t
  247. __gthread_objc_thread_id(void)
  248. {
  249.   if (__gthread_active_p ())
  250.     return (objc_thread_t) pthread_self();
  251.   else
  252.     return (objc_thread_t) 1;
  253. }
  254.  
  255. /* Sets the thread's local storage pointer.  */
  256. static inline int
  257. __gthread_objc_thread_set_data(void *value)
  258. {
  259.   if (__gthread_active_p ())
  260.     return pthread_setspecific(_objc_thread_storage, value);
  261.   else
  262.     {
  263.       thread_local_storage = value;
  264.       return 0;
  265.     }
  266. }
  267.  
  268. /* Returns the thread's local storage pointer.  */
  269. static inline void *
  270. __gthread_objc_thread_get_data(void)
  271. {
  272.   if (__gthread_active_p ())
  273.     return pthread_getspecific(_objc_thread_storage);
  274.   else
  275.     return thread_local_storage;
  276. }
  277.  
  278. /* Backend mutex functions */
  279.  
  280. /* Allocate a mutex.  */
  281. static inline int
  282. __gthread_objc_mutex_allocate(objc_mutex_t mutex)
  283. {
  284.   if (__gthread_active_p ())
  285.     {
  286.       mutex->backend = objc_malloc(sizeof(pthread_mutex_t));
  287.  
  288.       if (pthread_mutex_init((pthread_mutex_t *)mutex->backend, NULL))
  289.     {
  290.       objc_free(mutex->backend);
  291.       mutex->backend = NULL;
  292.       return -1;
  293.     }
  294.     }
  295.  
  296.   return 0;
  297. }
  298.  
  299. /* Deallocate a mutex.  */
  300. static inline int
  301. __gthread_objc_mutex_deallocate(objc_mutex_t mutex)
  302. {
  303.   if (__gthread_active_p ())
  304.     {
  305.       int count;
  306.  
  307.       /*
  308.        * Posix Threads specifically require that the thread be unlocked
  309.        * for pthread_mutex_destroy to work.
  310.        */
  311.  
  312.       do
  313.     {
  314.       count = pthread_mutex_unlock((pthread_mutex_t *)mutex->backend);
  315.       if (count < 0)
  316.         return -1;
  317.     }
  318.       while (count);
  319.  
  320.       if (pthread_mutex_destroy((pthread_mutex_t *)mutex->backend))
  321.     return -1;
  322.  
  323.       objc_free(mutex->backend);
  324.       mutex->backend = NULL;
  325.     }
  326.   return 0;
  327. }
  328.  
  329. /* Grab a lock on a mutex.  */
  330. static inline int
  331. __gthread_objc_mutex_lock(objc_mutex_t mutex)
  332. {
  333.   if (__gthread_active_p () 
  334.       && pthread_mutex_lock((pthread_mutex_t *)mutex->backend) != 0)
  335.     {
  336.       return -1;
  337.     }
  338.  
  339.   return 0;
  340. }
  341.  
  342. /* Try to grab a lock on a mutex.  */
  343. static inline int
  344. __gthread_objc_mutex_trylock(objc_mutex_t mutex)
  345. {
  346.   if (__gthread_active_p () 
  347.       && pthread_mutex_trylock((pthread_mutex_t *)mutex->backend) != 0)
  348.     {
  349.       return -1;
  350.     }
  351.  
  352.   return 0;
  353. }
  354.  
  355. /* Unlock the mutex */
  356. static inline int
  357. __gthread_objc_mutex_unlock(objc_mutex_t mutex)
  358. {
  359.   if (__gthread_active_p () 
  360.       && pthread_mutex_unlock((pthread_mutex_t *)mutex->backend) != 0)
  361.     {
  362.       return -1;
  363.     }
  364.  
  365.   return 0;
  366. }
  367.  
  368. /* Backend condition mutex functions */
  369.  
  370. /* Allocate a condition.  */
  371. static inline int
  372. __gthread_objc_condition_allocate(objc_condition_t condition)
  373. {
  374.   if (__gthread_active_p ())
  375.     {
  376.       condition->backend = objc_malloc(sizeof(pthread_cond_t));
  377.  
  378.       if (pthread_cond_init((pthread_cond_t *)condition->backend, NULL))
  379.     {
  380.       objc_free(condition->backend);
  381.       condition->backend = NULL;
  382.       return -1;
  383.     }
  384.     }
  385.  
  386.   return 0;
  387. }
  388.  
  389. /* Deallocate a condition.  */
  390. static inline int
  391. __gthread_objc_condition_deallocate(objc_condition_t condition)
  392. {
  393.   if (__gthread_active_p ())
  394.     {
  395.       if (pthread_cond_destroy((pthread_cond_t *)condition->backend))
  396.     return -1;
  397.  
  398.       objc_free(condition->backend);
  399.       condition->backend = NULL;
  400.     }
  401.   return 0;
  402. }
  403.  
  404. /* Wait on the condition */
  405. static inline int
  406. __gthread_objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
  407. {
  408.   if (__gthread_active_p ())
  409.     return pthread_cond_wait((pthread_cond_t *)condition->backend,
  410.                (pthread_mutex_t *)mutex->backend);
  411.   else
  412.     return 0;
  413. }
  414.  
  415. /* Wake up all threads waiting on this condition.  */
  416. static inline int
  417. __gthread_objc_condition_broadcast(objc_condition_t condition)
  418. {
  419.   if (__gthread_active_p ())
  420.     return pthread_cond_broadcast((pthread_cond_t *)condition->backend);
  421.   else
  422.     return 0;
  423. }
  424.  
  425. /* Wake up one thread waiting on this condition.  */
  426. static inline int
  427. __gthread_objc_condition_signal(objc_condition_t condition)
  428. {
  429.   if (__gthread_active_p ())
  430.     return pthread_cond_signal((pthread_cond_t *)condition->backend);
  431.   else
  432.     return 0;
  433. }
  434.  
  435. #else /* _LIBOBJC */
  436.  
  437. static inline int
  438. __gthread_once (__gthread_once_t *once, void (*func) (void))
  439. {
  440.   if (__gthread_active_p ())
  441.     return pthread_once (once, func);
  442.   else
  443.     return -1;
  444. }
  445.  
  446. static inline int
  447. __gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
  448. {
  449.   return pthread_key_create (key, dtor);
  450. }
  451.  
  452. static inline int
  453. __gthread_key_dtor (__gthread_key_t key, void *ptr)
  454. {
  455.   /* Just reset the key value to zero.  */
  456.   if (ptr)
  457.     return pthread_setspecific (key, 0);
  458.   else
  459.     return 0;
  460. }
  461.  
  462. static inline int
  463. __gthread_key_delete (__gthread_key_t key)
  464. {
  465.   return pthread_key_delete (key);
  466. }
  467.  
  468. static inline void *
  469. __gthread_getspecific (__gthread_key_t key)
  470. {
  471.   return pthread_getspecific (key);
  472. }
  473.  
  474. static inline int
  475. __gthread_setspecific (__gthread_key_t key, const void *ptr)
  476. {
  477.   return pthread_setspecific (key, ptr);
  478. }
  479.  
  480. static inline int
  481. __gthread_mutex_lock (__gthread_mutex_t *mutex)
  482. {
  483.   if (__gthread_active_p ())
  484.     return pthread_mutex_lock (mutex);
  485.   else
  486.     return 0;
  487. }
  488.  
  489. static inline int
  490. __gthread_mutex_trylock (__gthread_mutex_t *mutex)
  491. {
  492.   if (__gthread_active_p ())
  493.     return pthread_mutex_trylock (mutex);
  494.   else
  495.     return 0;
  496. }
  497.  
  498. static inline int
  499. __gthread_mutex_unlock (__gthread_mutex_t *mutex)
  500. {
  501.   if (__gthread_active_p ())
  502.     return pthread_mutex_unlock (mutex);
  503.   else
  504.     return 0;
  505. }
  506.  
  507. #endif /* _LIBOBJC */
  508.  
  509. #endif /* ! _GLIBCPP_GCC_GTHR_POSIX_H */
  510.