systhr.cpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. /** BEGIN COPYRIGHT BLOCK
  2. * This Program is free software; you can redistribute it and/or modify it under
  3. * the terms of the GNU General Public License as published by the Free Software
  4. * Foundation; version 2 of the License.
  5. *
  6. * This Program is distributed in the hope that it will be useful, but WITHOUT
  7. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  8. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  9. *
  10. * You should have received a copy of the GNU General Public License along with
  11. * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
  12. * Place, Suite 330, Boston, MA 02111-1307 USA.
  13. *
  14. * In addition, as a special exception, Red Hat, Inc. gives You the additional
  15. * right to link the code of this Program with code not covered under the GNU
  16. * General Public License ("Non-GPL Code") and to distribute linked combinations
  17. * including the two, subject to the limitations in this paragraph. Non-GPL Code
  18. * permitted under this exception must only link to the code of this Program
  19. * through those well defined interfaces identified in the file named EXCEPTION
  20. * found in the source code files (the "Approved Interfaces"). The files of
  21. * Non-GPL Code may instantiate templates or use macros or inline functions from
  22. * the Approved Interfaces without causing the resulting work to be covered by
  23. * the GNU General Public License. Only Red Hat, Inc. may make changes or
  24. * additions to the list of Approved Interfaces. You must obey the GNU General
  25. * Public License in all respects for all of the Program code and other code used
  26. * in conjunction with the Program except the Non-GPL Code covered by this
  27. * exception. If you modify this file, you may extend this exception to your
  28. * version of the file, but you are not obligated to do so. If you do not wish to
  29. * provide this exception without modification, you must delete this exception
  30. * statement from your version and license this file solely under the GPL without
  31. * exception.
  32. *
  33. *
  34. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  35. * Copyright (C) 2005 Red Hat, Inc.
  36. * All rights reserved.
  37. * END COPYRIGHT BLOCK **/
  38. /*
  39. * systhr.c: Abstracted threading mechanisms
  40. *
  41. * Rob McCool
  42. */
  43. #include "systhr.h"
  44. #define USE_NSPR
  45. #ifdef USE_NSPR
  46. #include "nspr.h"
  47. #include "private/prpriv.h"
  48. #ifdef LINUX
  49. # include <sys/time.h>
  50. # include <sys/resource.h>
  51. #else
  52. /* This declaration should be removed when NSPR newer than v4.6 is picked up,
  53. which should have the fix for bug 326110
  54. */
  55. extern "C" {
  56. int32 PR_GetSysfdTableMax(void);
  57. int32 PR_SetSysfdTableSize(int table_size);
  58. }
  59. #endif
  60. #endif
  61. #include "systems.h"
  62. #ifdef THREAD_WIN32
  63. #include <process.h>
  64. typedef struct {
  65. HANDLE hand;
  66. DWORD id;
  67. } sys_thread_s;
  68. #endif
  69. #if defined (USE_NSPR)
  70. #if defined(__hpux) && defined(__ia64)
  71. #define DEFAULT_STACKSIZE (256*1024)
  72. #else
  73. #define DEFAULT_STACKSIZE (64*1024)
  74. #endif
  75. static unsigned long _systhr_stacksize = DEFAULT_STACKSIZE;
  76. NSAPI_PUBLIC
  77. void systhread_set_default_stacksize(unsigned long size)
  78. {
  79. _systhr_stacksize = size;
  80. }
  81. NSPR_BEGIN_EXTERN_C
  82. NSAPI_PUBLIC SYS_THREAD
  83. #ifdef UnixWare /* for ANSI C++ standard, see base/systrh.h */
  84. systhread_start(int prio, int stksz, ArgFn_systhread_start fn, void *arg)
  85. #else
  86. systhread_start(int prio, int stksz, void (*fn)(void *), void *arg)
  87. #endif
  88. {
  89. #if (defined(Linux) || defined(SNI) || defined(UnixWare)) && !defined(USE_PTHREADS)
  90. prio /= 8; /* quick and dirty fix for user thread priority scale problem */
  91. if (prio > 3) prio = 3;
  92. #endif
  93. PRThread *ret = PR_CreateThread(PR_USER_THREAD, (void (*)(void *))fn,
  94. (void *)arg, (PRThreadPriority)prio,
  95. PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD,
  96. stksz ? stksz : _systhr_stacksize);
  97. return (void *) ret;
  98. }
  99. NSPR_END_EXTERN_C
  100. NSAPI_PUBLIC SYS_THREAD systhread_current(void)
  101. {
  102. return PR_GetCurrentThread();
  103. }
  104. NSAPI_PUBLIC void systhread_yield(void)
  105. {
  106. /* PR_Yield(); */
  107. PR_Sleep(PR_INTERVAL_NO_WAIT);
  108. }
  109. NSAPI_PUBLIC void systhread_timerset(int usec)
  110. {
  111. /* This is an interesting problem. If you ever do turn on interrupts
  112. * on the server, you're in for lots of fun with NSPR Threads
  113. PR_StartEvents(usec); */
  114. }
  115. NSAPI_PUBLIC
  116. SYS_THREAD systhread_attach(void)
  117. {
  118. PRThread *ret;
  119. ret = PR_AttachThread(PR_USER_THREAD, PR_PRIORITY_NORMAL, NULL);
  120. return (void *) ret;
  121. }
  122. NSAPI_PUBLIC
  123. void systhread_detach(SYS_THREAD thr)
  124. {
  125. /* XXXMB - this is not correct! */
  126. PR_DetachThread();
  127. }
  128. NSAPI_PUBLIC void systhread_terminate(SYS_THREAD thr)
  129. {
  130. /* Should never be here. PR_DestroyThread is no
  131. * longer used. */
  132. PR_ASSERT(0);
  133. /* PR_DestroyThread((PRThread *) thr); */
  134. }
  135. NSAPI_PUBLIC void systhread_sleep(int milliseconds)
  136. {
  137. PR_Sleep(milliseconds);
  138. }
  139. NSAPI_PUBLIC void systhread_init(char *name)
  140. {
  141. PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 256);
  142. #ifdef XP_UNIX
  143. #ifdef LINUX
  144. /*
  145. * NSPR 4.6 does not export PR_SetSysfdTableSize
  146. * and PR_GetSysfdTableMax by mistake (NSPR Bugzilla
  147. * bug 326110) on platforms that use GCC with symbol
  148. * visibility, so we have to call the system calls
  149. * directly.
  150. */
  151. {
  152. struct rlimit rlim;
  153. if (getrlimit(RLIMIT_NOFILE, &rlim) < 0)
  154. return;
  155. rlim.rlim_cur = rlim.rlim_max;
  156. (void) setrlimit(RLIMIT_NOFILE, &rlim);
  157. }
  158. #else
  159. PR_SetSysfdTableSize(PR_GetSysfdTableMax());
  160. #endif
  161. #endif
  162. }
  163. NSAPI_PUBLIC int systhread_newkey()
  164. {
  165. uintn newkey;
  166. PR_NewThreadPrivateIndex(&newkey, NULL);
  167. return (newkey);
  168. }
  169. NSAPI_PUBLIC void *systhread_getdata(int key)
  170. {
  171. return PR_GetThreadPrivate(key);
  172. }
  173. NSAPI_PUBLIC void systhread_setdata(int key, void *data)
  174. {
  175. PR_SetThreadPrivate(key, data);
  176. }
  177. /*
  178. * Drag in the Java code, so our dynamic library full of it works
  179. * i.e. force these symbols to load.
  180. */
  181. NSAPI_PUBLIC void systhread_dummy(void)
  182. {
  183. #ifndef NSPR20
  184. /* nspr/gc.c */
  185. PR_InitGC(0,0);
  186. /* nspr/prsystem.c */
  187. PR_GetSystemInfo(PR_SI_SYSNAME, 0, 0);
  188. /* nspr/linker.c */
  189. PR_GetLibName(0, 0);
  190. /* nspr/file.c */
  191. PR_Mkdir(0, 0);
  192. /* nspr/prnetdb.c */
  193. PR_gethostbyname(0, 0, 0, 0, 0);
  194. /* nspr/longlong.c */
  195. LL_TO_S(LL_ZERO, 0, NULL, 0);
  196. #endif /* NSPR20 */
  197. }
  198. #elif defined(THREAD_WIN32)
  199. #include <nspr/prthread.h>
  200. #define DEFAULT_STACKSIZE 262144
  201. NSPR_BEGIN_EXTERN_C
  202. NSAPI_PUBLIC
  203. SYS_THREAD systhread_start(int prio, int stksz, void (*fn)(void *), void *arg)
  204. {
  205. sys_thread_s *ret = (sys_thread_s *) MALLOC(sizeof(sys_thread_s));
  206. if ((ret->hand = (HANDLE)_beginthreadex(NULL, stksz, (unsigned (__stdcall *)(void *))fn,
  207. arg, 0, &ret->id)) == 0) {
  208. FREE(ret);
  209. return NULL;
  210. }
  211. return (void *)ret;
  212. }
  213. NSPR_END_EXTERN_C
  214. NSAPI_PUBLIC SYS_THREAD systhread_current(void)
  215. {
  216. /* XXXrobm this is busted.... */
  217. return GetCurrentThread();
  218. }
  219. NSAPI_PUBLIC void systhread_timerset(int usec)
  220. {
  221. }
  222. NSAPI_PUBLIC SYS_THREAD systhread_attach(void)
  223. {
  224. return NULL;
  225. }
  226. NSAPI_PUBLIC void systhread_yield(void)
  227. {
  228. systhread_sleep(0);
  229. }
  230. NSAPI_PUBLIC void systhread_terminate(SYS_THREAD thr)
  231. {
  232. TerminateThread(((sys_thread_s *)thr)->hand, 0);
  233. }
  234. NSAPI_PUBLIC void systhread_sleep(int milliseconds)
  235. {
  236. /* XXXrobm there must be a better way to do this */
  237. HANDLE sem = CreateSemaphore(NULL, 1, 4, "sleeper");
  238. WaitForSingleObject(sem, INFINITE);
  239. WaitForSingleObject(sem, milliseconds);
  240. CloseHandle(sem);
  241. }
  242. NSAPI_PUBLIC void systhread_init(char *name)
  243. {
  244. PR_Init(PR_USER_THREAD, 1, 0);
  245. }
  246. NSAPI_PUBLIC int systhread_newkey()
  247. {
  248. return TlsAlloc();
  249. }
  250. NSAPI_PUBLIC void *systhread_getdata(int key)
  251. {
  252. return (void *)TlsGetValue(key);
  253. }
  254. NSAPI_PUBLIC void systhread_setdata(int key, void *data)
  255. {
  256. TlsSetValue(key, data);
  257. }
  258. #endif