home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / nsprpub / pr / src / md / os2 / os2thred.c < prev   
Encoding:
C/C++ Source or Header  |  1998-04-08  |  6.4 KB  |  246 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /*
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  * 
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  * 
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. #include "primpl.h"
  20. #include <process.h>  /* for _beginthread() */
  21.  
  22. APIRET (* APIENTRY QueryThreadContext)(TID, ULONG, PCONTEXTRECORD);
  23.  
  24. /* --- globals ------------------------------------------------ */
  25. _NSPR_TLS*        pThreadLocalStorage = 0;
  26. _PRInterruptTable             _pr_interruptTable[] = { { 0 } };
  27.  
  28. PR_IMPLEMENT(void)
  29. _PR_MD_ENSURE_TLS()
  30. {
  31.    if(!pThreadLocalStorage)
  32.    {
  33.       /* Allocate thread local storage (TLS).  Note, that only 32 bytes can
  34.        * be allocated at a time. 
  35.        */
  36.       int rc = DosAllocThreadLocalMemory(sizeof(_NSPR_TLS) / 4, (PULONG*)&pThreadLocalStorage);
  37.       PR_ASSERT(rc == NO_ERROR);
  38.       memset(pThreadLocalStorage, 0, sizeof(_NSPR_TLS));
  39.    }
  40. }
  41.  
  42. PR_IMPLEMENT(void)
  43. _PR_MD_EARLY_INIT()
  44. {
  45.    HMODULE hmod;
  46.  
  47.    if (DosLoadModule(NULL, 0, "DOSCALL1.DLL", &hmod) == 0)
  48.        DosQueryProcAddr(hmod, 877, "DOSQUERYTHREADCONTEXT",
  49.                         (PFN *)&QueryThreadContext);
  50. }
  51.  
  52. PR_IMPLEMENT(void)
  53. _PR_MD_INIT_PRIMORDIAL_THREAD(PRThread *thread)
  54. {
  55.    PTIB ptib;
  56.    PPIB ppib;
  57.    PRUword rc;
  58.  
  59.    rc = DosGetInfoBlocks(&ptib, &ppib);
  60.  
  61.    thread->md.handle = ptib->tib_ptib2->tib2_ultid;
  62. }
  63.  
  64.  
  65. PR_IMPLEMENT(PRStatus)
  66. _PR_MD_INIT_THREAD(PRThread *thread)
  67. {
  68.    APIRET rc;
  69.  
  70.    if (thread->flags & _PR_PRIMORDIAL)
  71.       _PR_MD_INIT_PRIMORDIAL_THREAD(thread);
  72.  
  73.    /* Create the blocking IO semaphore */
  74.    _PR_MD_NEW_SEM(&thread->md.blocked_sema, 1);
  75.    return (thread->md.blocked_sema.sem != NULL) ? PR_SUCCESS : PR_FAILURE;
  76. }
  77.  
  78. PR_IMPLEMENT(PRStatus) 
  79. _PR_MD_CREATE_THREAD(PRThread *thread, 
  80.                   void (*start)(void *), 
  81.                   PRThreadPriority priority, 
  82.                   PRThreadScope scope, 
  83.                   PRThreadState state, 
  84.                   PRUint32 stackSize)
  85. {
  86.     thread->md.handle = thread->id = (TID) _beginthread(
  87.                     (void(* _Optlink)(void*))start,
  88.                     NULL, 
  89.                     thread->stack->stackSize,
  90.                     thread);
  91.     if(thread->md.handle == -1) {
  92.         return PR_FAILURE;
  93.     }
  94.     _PR_MD_SET_PRIORITY(&(thread->md), priority);
  95.  
  96.     return PR_SUCCESS;
  97. }
  98.  
  99. PR_IMPLEMENT(void)    
  100. _PR_MD_YIELD(void)
  101. {
  102.     /* Isn't there some problem with DosSleep(0) on OS/2? */
  103.     DosSleep(0);
  104. }
  105.  
  106. PR_IMPLEMENT(void)     
  107. _PR_MD_SET_PRIORITY(_MDThread *thread, PRThreadPriority newPri)
  108. {
  109.     int nativePri;
  110.     BOOL rv;
  111.  
  112.     if (newPri < PR_PRIORITY_FIRST) {
  113.         newPri = PR_PRIORITY_FIRST;
  114.     } else if (newPri > PR_PRIORITY_LAST) {
  115.         newPri = PR_PRIORITY_LAST;
  116.     }
  117.     switch (newPri) {
  118.         case PR_PRIORITY_LOW:
  119.             nativePri = PRTYC_IDLETIME;
  120.             break;
  121.         case PR_PRIORITY_NORMAL:
  122.             nativePri = PRTYC_REGULAR;
  123.             break;
  124.         case PR_PRIORITY_HIGH:
  125.             nativePri = PRTYC_FOREGROUNDSERVER;
  126.             break;
  127.         case PR_PRIORITY_URGENT:
  128.             nativePri = PRTYC_TIMECRITICAL;
  129.     }
  130.     rv = DosSetPriority(PRTYS_THREAD, nativePri, 0, thread->handle);
  131.     PR_ASSERT(rv == NO_ERROR);
  132.     if (rv != NO_ERROR) {
  133.     PR_LOG(_pr_thread_lm, PR_LOG_MIN,
  134.                 ("PR_SetThreadPriority: can't set thread priority\n"));
  135.     }
  136.     return;
  137. }
  138.  
  139. PR_IMPLEMENT(void)
  140. _PR_MD_CLEAN_THREAD(PRThread *thread)
  141. {
  142.    /* Just call _PR_MD_EXIT_THREAD for now */
  143.    _PR_MD_EXIT_THREAD(thread);
  144. }
  145.  
  146. PR_IMPLEMENT(void)
  147. _PR_MD_EXIT_THREAD(PRThread *thread)
  148. {
  149.     _PR_MD_DESTROY_SEM(&thread->md.blocked_sema);
  150.  
  151.     if (thread->md.handle) {
  152.        /* DosKillThread will not kill a suspended thread, but it will mark it
  153.         * for death; we must resume it after killing it to make sure it knows
  154.         * it is about to die (pretty wicked, huh?).
  155.         *
  156.         * DosKillThread will not kill the current thread, instead we must use
  157.         * DosExit.
  158.         */
  159.        if ( thread != _MD_CURRENT_THREAD() ) {
  160.            DosKillThread( thread->md.handle );
  161.            DosResumeThread( thread->md.handle );
  162.        } else {
  163.            _endthread();
  164.        }
  165.        thread->md.handle = 0;
  166.     }
  167.  
  168.     _PR_MD_SET_CURRENT_THREAD(NULL);
  169. }
  170.  
  171.  
  172. PR_IMPLEMENT(void)
  173. _PR_MD_EXIT(PRIntn status)
  174. {
  175.     _exit(status);
  176. }
  177.  
  178. #ifdef HAVE_THREAD_AFFINITY
  179. PR_EXTERN(PRInt32) 
  180. _PR_MD_SETTHREADAFFINITYMASK(PRThread *thread, PRUint32 mask )
  181. {
  182.    /* Can we do this on OS/2?  Only on SMP versions? */
  183.    PR_ASSERT(!"Not implemented");
  184.    return 0;
  185.  
  186.  /* This is what windows does:
  187.     int rv;
  188.  
  189.     rv = SetThreadAffinityMask(thread->md.handle, mask);
  190.  
  191.     return rv?0:-1;
  192.   */
  193. }
  194.  
  195. PR_EXTERN(PRInt32)
  196. _PR_MD_GETTHREADAFFINITYMASK(PRThread *thread, PRUint32 *mask)
  197. {
  198.    /* Can we do this on OS/2?  Only on SMP versions? */
  199.    PR_ASSERT(!"Not implemented");
  200.    return 0;
  201.  
  202.  /* This is what windows does:
  203.     PRInt32 rv, system_mask;
  204.  
  205.     rv = GetProcessAffinityMask(GetCurrentProcess(), mask, &system_mask);
  206.     
  207.     return rv?0:-1;
  208.   */
  209. }
  210. #endif /* HAVE_THREAD_AFFINITY */
  211.  
  212. PR_IMPLEMENT(void) 
  213. _PR_MD_SUSPEND_CPU(_PRCPU *cpu) 
  214. {
  215.     _PR_MD_SUSPEND_THREAD(cpu->thread);
  216. }
  217.  
  218. PR_IMPLEMENT(void)
  219. _PR_MD_RESUME_CPU(_PRCPU *cpu)
  220. {
  221.     _PR_MD_RESUME_THREAD(cpu->thread);
  222. }
  223.  
  224. PR_IMPLEMENT(void)
  225. _PR_MD_SUSPEND_THREAD(PRThread *thread)
  226. {
  227.     if (_PR_IS_NATIVE_THREAD(thread)) {
  228.        APIRET rc;
  229.  
  230.         /* XXXMB - DosSuspendThread() is not a blocking call; how do we
  231.          * know when the thread is *REALLY* suspended?
  232.          */
  233.        rc = DosSuspendThread(thread->md.handle);
  234.        PR_ASSERT(rc == NO_ERROR);
  235.     }
  236. }
  237.  
  238. PR_IMPLEMENT(void)
  239. _PR_MD_RESUME_THREAD(PRThread *thread)
  240. {
  241.     if (_PR_IS_NATIVE_THREAD(thread)) {
  242.         DosResumeThread(thread->md.handle);
  243.     }
  244. }
  245.  
  246.