xref: /trunk/main/sal/osl/os2/thread.c (revision 647f063d49501903f1667b75f5634541fc603283)
1*647f063dSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*647f063dSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*647f063dSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*647f063dSAndrew Rist  * distributed with this work for additional information
6*647f063dSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*647f063dSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*647f063dSAndrew Rist  * "License"); you may not use this file except in compliance
9*647f063dSAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11*647f063dSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*647f063dSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*647f063dSAndrew Rist  * software distributed under the License is distributed on an
15*647f063dSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*647f063dSAndrew Rist  * KIND, either express or implied.  See the License for the
17*647f063dSAndrew Rist  * specific language governing permissions and limitations
18*647f063dSAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20*647f063dSAndrew Rist  *************************************************************/
21*647f063dSAndrew Rist 
22*647f063dSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir 
25cdf0e10cSrcweir #include "system.h"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <osl/diagnose.h>
28cdf0e10cSrcweir #include <osl/thread.h>
29cdf0e10cSrcweir #include <osl/time.h>
30cdf0e10cSrcweir #include <rtl/alloc.h>
31cdf0e10cSrcweir #include <rtl/tencinfo.h>
32cdf0e10cSrcweir 
33cdf0e10cSrcweir /*
34cdf0e10cSrcweir     Thread-data structure hidden behind oslThread:
35cdf0e10cSrcweir */
36cdf0e10cSrcweir typedef struct _osl_TThreadImpl
37cdf0e10cSrcweir {
38cdf0e10cSrcweir 
39cdf0e10cSrcweir     TID                  m_ThreadId;        /* identifier for this thread */
40cdf0e10cSrcweir     sal_Int32            m_Flags;
41cdf0e10cSrcweir     HEV                  m_hEvent;
42cdf0e10cSrcweir     sal_uInt32           m_Timeout;
43cdf0e10cSrcweir     oslWorkerFunction    m_WorkerFunction;
44cdf0e10cSrcweir     void*                m_pData;
45cdf0e10cSrcweir     sal_Bool             m_StartSuspended;
46cdf0e10cSrcweir     HAB                  m_hab;
47cdf0e10cSrcweir     HMQ                  m_hmq;
48cdf0e10cSrcweir 
49cdf0e10cSrcweir } osl_TThreadImpl;
50cdf0e10cSrcweir 
51cdf0e10cSrcweir #define THREADIMPL_FLAGS_TERMINATE    0x0001
52cdf0e10cSrcweir #define THREADIMPL_FLAGS_SLEEP        0x0002
53cdf0e10cSrcweir 
54cdf0e10cSrcweir 
55cdf0e10cSrcweir // static mutex to control access to private members of oslMutexImpl
56cdf0e10cSrcweir static HMTX MutexLock = NULL;
57cdf0e10cSrcweir 
58cdf0e10cSrcweir /*****************************************************************************/
59cdf0e10cSrcweir 
60cdf0e10cSrcweir HAB osl_getPMinternal_HAB(oslThread hThread)
61cdf0e10cSrcweir {
62cdf0e10cSrcweir     osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)hThread;
63cdf0e10cSrcweir 
64cdf0e10cSrcweir     if(pThreadImpl == NULL) /* valid ptr? */
65cdf0e10cSrcweir     {
66cdf0e10cSrcweir         return NULL;
67cdf0e10cSrcweir     }
68cdf0e10cSrcweir     else
69cdf0e10cSrcweir     {
70cdf0e10cSrcweir         return pThreadImpl->m_hab;
71cdf0e10cSrcweir     }
72cdf0e10cSrcweir }
73cdf0e10cSrcweir 
74cdf0e10cSrcweir HMQ osl_getPMinternal_HMQ(oslThread hThread)
75cdf0e10cSrcweir {
76cdf0e10cSrcweir     osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)hThread;
77cdf0e10cSrcweir 
78cdf0e10cSrcweir     if(pThreadImpl == NULL) /* valid ptr? */
79cdf0e10cSrcweir     {
80cdf0e10cSrcweir         return NULL;
81cdf0e10cSrcweir     }
82cdf0e10cSrcweir     else
83cdf0e10cSrcweir     {
84cdf0e10cSrcweir         return pThreadImpl->m_hmq;
85cdf0e10cSrcweir     }
86cdf0e10cSrcweir }
87cdf0e10cSrcweir 
88cdf0e10cSrcweir 
89cdf0e10cSrcweir /*****************************************************************************/
90cdf0e10cSrcweir /* oslWorkerWrapperFunction */
91cdf0e10cSrcweir /*****************************************************************************/
92cdf0e10cSrcweir static void oslWorkerWrapperFunction(void* pData)
93cdf0e10cSrcweir {
94cdf0e10cSrcweir     BOOL rc;
95cdf0e10cSrcweir     osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)pData;
96cdf0e10cSrcweir 
97cdf0e10cSrcweir #if OSL_DEBUG_LEVEL>0
98cdf0e10cSrcweir printf("oslWorkerWrapperFunction pThreadImpl %x, pThreadImpl->m_ThreadId %d\n", pThreadImpl, pThreadImpl->m_ThreadId);
99cdf0e10cSrcweir #endif
100cdf0e10cSrcweir     /* Inizialize PM for this thread */
101cdf0e10cSrcweir     pThreadImpl->m_hab = WinInitialize( 0 );
102cdf0e10cSrcweir #if OSL_DEBUG_LEVEL>0
103cdf0e10cSrcweir printf("pThreadImpl->m_ThreadId %d, pThreadImpl->m_hab %x\n", pThreadImpl->m_ThreadId,pThreadImpl->m_hab);
104cdf0e10cSrcweir #endif
105cdf0e10cSrcweir     pThreadImpl->m_hmq = WinCreateMsgQueue( pThreadImpl->m_hab, 0 );
106cdf0e10cSrcweir #if OSL_DEBUG_LEVEL>0
107cdf0e10cSrcweir printf("pThreadImpl->m_ThreadId %d, pThreadImpl->m_hmq %x\n", pThreadImpl->m_ThreadId,pThreadImpl->m_hmq);
108cdf0e10cSrcweir #endif
109cdf0e10cSrcweir 
110cdf0e10cSrcweir     /* call worker-function with data */
111cdf0e10cSrcweir     pThreadImpl->m_WorkerFunction( pThreadImpl->m_pData );
112cdf0e10cSrcweir 
113cdf0e10cSrcweir     /* Free all PM-resources for this thread */
114cdf0e10cSrcweir #if OSL_DEBUG_LEVEL>0
115cdf0e10cSrcweir printf("pThreadImpl->m_ThreadId %d, about to destroy queue\n", pThreadImpl->m_ThreadId);
116cdf0e10cSrcweir #endif
117cdf0e10cSrcweir     rc = WinDestroyMsgQueue( pThreadImpl->m_hmq );
118cdf0e10cSrcweir #if OSL_DEBUG_LEVEL>0
119cdf0e10cSrcweir printf("pThreadImpl->m_ThreadId %d, WinDestroyMsgQueue rc=%d (should be 1)\n", pThreadImpl->m_ThreadId, rc);
120cdf0e10cSrcweir printf("pThreadImpl->m_ThreadId %d, about to terminate hab\n", pThreadImpl->m_ThreadId);
121cdf0e10cSrcweir #endif
122cdf0e10cSrcweir     rc = WinTerminate( pThreadImpl->m_hab );
123cdf0e10cSrcweir #if OSL_DEBUG_LEVEL>0
124cdf0e10cSrcweir printf("pThreadImpl->m_ThreadId %d, WinTerminate rc=%d (should be 1)\n", pThreadImpl->m_ThreadId, rc);
125cdf0e10cSrcweir #endif
126cdf0e10cSrcweir }
127cdf0e10cSrcweir 
128cdf0e10cSrcweir 
129cdf0e10cSrcweir /*****************************************************************************/
130cdf0e10cSrcweir /* oslCreateThread */
131cdf0e10cSrcweir /*****************************************************************************/
132cdf0e10cSrcweir static oslThread oslCreateThread(oslWorkerFunction pWorker,
133cdf0e10cSrcweir                                  void* pThreadData,
134cdf0e10cSrcweir                                  sal_Bool nFlags)
135cdf0e10cSrcweir {
136cdf0e10cSrcweir     osl_TThreadImpl* pThreadImpl;
137cdf0e10cSrcweir 
138cdf0e10cSrcweir     /* alloc mem. for our internal data structure */
139cdf0e10cSrcweir     pThreadImpl = (osl_TThreadImpl*)malloc(sizeof(osl_TThreadImpl));
140cdf0e10cSrcweir 
141cdf0e10cSrcweir     OSL_ASSERT(pThreadImpl);
142cdf0e10cSrcweir 
143cdf0e10cSrcweir     pThreadImpl->m_WorkerFunction= pWorker;
144cdf0e10cSrcweir     pThreadImpl->m_pData= pThreadData;
145cdf0e10cSrcweir 
146cdf0e10cSrcweir     pThreadImpl->m_Flags   = 0;
147cdf0e10cSrcweir     pThreadImpl->m_hEvent  = 0;
148cdf0e10cSrcweir     pThreadImpl->m_Timeout = 0;
149cdf0e10cSrcweir     pThreadImpl->m_StartSuspended = nFlags;
150cdf0e10cSrcweir     pThreadImpl->m_hab = 0;
151cdf0e10cSrcweir     pThreadImpl->m_hmq = 0;
152cdf0e10cSrcweir 
153cdf0e10cSrcweir     if ( nFlags == sal_True )
154cdf0e10cSrcweir     {
155cdf0e10cSrcweir         DosRequestMutexSem( MutexLock, SEM_INDEFINITE_WAIT );
156cdf0e10cSrcweir     }
157cdf0e10cSrcweir 
158cdf0e10cSrcweir     pThreadImpl->m_ThreadId = (TID) _beginthread( oslWorkerWrapperFunction,    /* worker-function */
159cdf0e10cSrcweir                                                   NULL,                        /* unused parameter */
160cdf0e10cSrcweir                                                   1024*1024,                   /* max. Stacksize */
161cdf0e10cSrcweir                                                   pThreadImpl );
162cdf0e10cSrcweir     if ( nFlags == sal_True )
163cdf0e10cSrcweir     {
164cdf0e10cSrcweir         if( pThreadImpl->m_ThreadId != -1 )
165cdf0e10cSrcweir             DosSuspendThread( pThreadImpl->m_ThreadId );
166cdf0e10cSrcweir         DosReleaseMutexSem( MutexLock);
167cdf0e10cSrcweir     }
168cdf0e10cSrcweir #if OSL_DEBUG_LEVEL>0
169cdf0e10cSrcweir printf("oslCreateThread pThreadImpl %x, pThreadImpl->m_ThreadId %d\n", pThreadImpl, pThreadImpl->m_ThreadId);
170cdf0e10cSrcweir #endif
171cdf0e10cSrcweir     if(pThreadImpl->m_ThreadId == -1)
172cdf0e10cSrcweir     {
173cdf0e10cSrcweir         /* create failed */
174cdf0e10cSrcweir         if (pThreadImpl->m_hEvent != 0)
175cdf0e10cSrcweir             DosCloseEventSem(pThreadImpl->m_hEvent);
176cdf0e10cSrcweir 
177cdf0e10cSrcweir         free(pThreadImpl);
178cdf0e10cSrcweir         return 0;
179cdf0e10cSrcweir     }
180cdf0e10cSrcweir 
181cdf0e10cSrcweir     pThreadImpl->m_hEvent= 0;
182cdf0e10cSrcweir 
183cdf0e10cSrcweir     return pThreadImpl;
184cdf0e10cSrcweir 
185cdf0e10cSrcweir }
186cdf0e10cSrcweir 
187cdf0e10cSrcweir /*****************************************************************************/
188cdf0e10cSrcweir /* osl_createThread */
189cdf0e10cSrcweir /*****************************************************************************/
190cdf0e10cSrcweir oslThread SAL_CALL osl_createThread(oslWorkerFunction pWorker,
191cdf0e10cSrcweir                                  void* pThreadData)
192cdf0e10cSrcweir {
193cdf0e10cSrcweir     return oslCreateThread(pWorker,pThreadData,sal_False);
194cdf0e10cSrcweir }
195cdf0e10cSrcweir 
196cdf0e10cSrcweir /*****************************************************************************/
197cdf0e10cSrcweir /* osl_createSuspendedThread */
198cdf0e10cSrcweir /*****************************************************************************/
199cdf0e10cSrcweir oslThread SAL_CALL osl_createSuspendedThread(oslWorkerFunction pWorker,
200cdf0e10cSrcweir                                           void* pThreadData)
201cdf0e10cSrcweir {
202cdf0e10cSrcweir     return oslCreateThread(pWorker,pThreadData,sal_True);
203cdf0e10cSrcweir }
204cdf0e10cSrcweir 
205cdf0e10cSrcweir /*****************************************************************************/
206cdf0e10cSrcweir /* osl_getThreadIdentifier */
207cdf0e10cSrcweir /*****************************************************************************/
208cdf0e10cSrcweir oslThreadIdentifier SAL_CALL osl_getThreadIdentifier(oslThread Thread)
209cdf0e10cSrcweir {
210cdf0e10cSrcweir     osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread;
211cdf0e10cSrcweir 
212cdf0e10cSrcweir     if (pThreadImpl != NULL)
213cdf0e10cSrcweir         return ((oslThreadIdentifier)pThreadImpl->m_ThreadId);
214cdf0e10cSrcweir     else
215cdf0e10cSrcweir         {
216cdf0e10cSrcweir         PTIB pptib = NULL;
217cdf0e10cSrcweir         PPIB pppib = NULL;
218cdf0e10cSrcweir 
219cdf0e10cSrcweir         DosGetInfoBlocks( &pptib, &pppib );
220cdf0e10cSrcweir         return ((oslThreadIdentifier) pptib->tib_ptib2->tib2_ultid );
221cdf0e10cSrcweir         }
222cdf0e10cSrcweir }
223cdf0e10cSrcweir 
224cdf0e10cSrcweir /*****************************************************************************/
225cdf0e10cSrcweir /* osl_destroyThread */
226cdf0e10cSrcweir /*****************************************************************************/
227cdf0e10cSrcweir void SAL_CALL osl_destroyThread(oslThread Thread)
228cdf0e10cSrcweir {
229cdf0e10cSrcweir     osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread;
230cdf0e10cSrcweir 
231cdf0e10cSrcweir     if(Thread == 0) /* valid ptr? */
232cdf0e10cSrcweir     {
233cdf0e10cSrcweir         /* thread already destroyed or not created */
234cdf0e10cSrcweir         return;
235cdf0e10cSrcweir     }
236cdf0e10cSrcweir 
237cdf0e10cSrcweir     if(pThreadImpl->m_ThreadId != -1)    /* valid handle ? */
238cdf0e10cSrcweir     {
239cdf0e10cSrcweir         /* cancel thread  */
240cdf0e10cSrcweir         DosKillThread( pThreadImpl->m_ThreadId );
241cdf0e10cSrcweir     }
242cdf0e10cSrcweir }
243cdf0e10cSrcweir 
244cdf0e10cSrcweir /*****************************************************************************/
245cdf0e10cSrcweir /* osl_freeThreadHandle */
246cdf0e10cSrcweir /*****************************************************************************/
247cdf0e10cSrcweir void SAL_CALL osl_freeThreadHandle(oslThread Thread)
248cdf0e10cSrcweir {
249cdf0e10cSrcweir     osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread;
250cdf0e10cSrcweir 
251cdf0e10cSrcweir     if(Thread == 0)        /* valid ptr? */
252cdf0e10cSrcweir     {
253cdf0e10cSrcweir         /* thread already destroyed or not created */
254cdf0e10cSrcweir         return;
255cdf0e10cSrcweir     }
256cdf0e10cSrcweir 
257cdf0e10cSrcweir     if (pThreadImpl->m_hEvent != 0)
258cdf0e10cSrcweir         DosCloseEventSem(pThreadImpl->m_hEvent);
259cdf0e10cSrcweir 
260cdf0e10cSrcweir     /* free memory */
261cdf0e10cSrcweir     free(Thread);
262cdf0e10cSrcweir }
263cdf0e10cSrcweir 
264cdf0e10cSrcweir /*****************************************************************************/
265cdf0e10cSrcweir /* osl_resumeThread */
266cdf0e10cSrcweir /*****************************************************************************/
267cdf0e10cSrcweir void SAL_CALL osl_resumeThread(oslThread Thread)
268cdf0e10cSrcweir {
269cdf0e10cSrcweir     osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread;
270cdf0e10cSrcweir 
271cdf0e10cSrcweir     OSL_ASSERT(pThreadImpl);        /* valid ptr? */
272cdf0e10cSrcweir 
273cdf0e10cSrcweir     DosResumeThread( pThreadImpl->m_ThreadId );
274cdf0e10cSrcweir }
275cdf0e10cSrcweir 
276cdf0e10cSrcweir /*****************************************************************************/
277cdf0e10cSrcweir /* osl_suspendThread */
278cdf0e10cSrcweir /*****************************************************************************/
279cdf0e10cSrcweir void SAL_CALL osl_suspendThread(oslThread Thread)
280cdf0e10cSrcweir {
281cdf0e10cSrcweir     osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread;
282cdf0e10cSrcweir 
283cdf0e10cSrcweir     OSL_ASSERT(pThreadImpl);        /* valid ptr? */
284cdf0e10cSrcweir 
285cdf0e10cSrcweir     DosSuspendThread( pThreadImpl->m_ThreadId );
286cdf0e10cSrcweir }
287cdf0e10cSrcweir 
288cdf0e10cSrcweir /*****************************************************************************/
289cdf0e10cSrcweir /* osl_setThreadPriority */
290cdf0e10cSrcweir /*****************************************************************************/
291cdf0e10cSrcweir void SAL_CALL osl_setThreadPriority(oslThread Thread,
292cdf0e10cSrcweir                            oslThreadPriority Priority)
293cdf0e10cSrcweir {
294cdf0e10cSrcweir     ULONG nOs2PriorityClass;
295cdf0e10cSrcweir     ULONG nOs2PriorityDelta;
296cdf0e10cSrcweir     osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread;
297cdf0e10cSrcweir 
298cdf0e10cSrcweir     OSL_ASSERT(pThreadImpl);        /* valid ptr? */
299cdf0e10cSrcweir 
300cdf0e10cSrcweir     switch(Priority) {
301cdf0e10cSrcweir 
302cdf0e10cSrcweir     case osl_Thread_PriorityHighest:
303cdf0e10cSrcweir 
304cdf0e10cSrcweir         nOs2PriorityClass = PRTYC_REGULAR;
305cdf0e10cSrcweir         nOs2PriorityDelta = PRTYD_MAXIMUM;
306cdf0e10cSrcweir         break;
307cdf0e10cSrcweir 
308cdf0e10cSrcweir     case osl_Thread_PriorityAboveNormal:
309cdf0e10cSrcweir 
310cdf0e10cSrcweir         nOs2PriorityClass = PRTYC_REGULAR;
311cdf0e10cSrcweir         nOs2PriorityDelta = 16;
312cdf0e10cSrcweir         break;
313cdf0e10cSrcweir 
314cdf0e10cSrcweir     case osl_Thread_PriorityNormal:
315cdf0e10cSrcweir 
316cdf0e10cSrcweir         nOs2PriorityClass = PRTYC_REGULAR;
317cdf0e10cSrcweir         nOs2PriorityDelta = 0;
318cdf0e10cSrcweir         break;
319cdf0e10cSrcweir 
320cdf0e10cSrcweir     case osl_Thread_PriorityBelowNormal:
321cdf0e10cSrcweir 
322cdf0e10cSrcweir         nOs2PriorityClass = PRTYC_REGULAR;
323cdf0e10cSrcweir         nOs2PriorityDelta = -16;
324cdf0e10cSrcweir         break;
325cdf0e10cSrcweir 
326cdf0e10cSrcweir     case osl_Thread_PriorityLowest:
327cdf0e10cSrcweir 
328cdf0e10cSrcweir         nOs2PriorityClass = PRTYC_REGULAR;
329cdf0e10cSrcweir         nOs2PriorityDelta = PRTYD_MINIMUM;
330cdf0e10cSrcweir         break;
331cdf0e10cSrcweir 
332cdf0e10cSrcweir     case osl_Thread_PriorityUnknown:
333cdf0e10cSrcweir         OSL_ASSERT(FALSE);        /* only fools try this...*/
334cdf0e10cSrcweir 
335cdf0e10cSrcweir         /* let release-version behave friendly */
336cdf0e10cSrcweir         return;
337cdf0e10cSrcweir 
338cdf0e10cSrcweir     default:
339cdf0e10cSrcweir         OSL_ASSERT(FALSE);        /* enum expanded, but forgotten here...*/
340cdf0e10cSrcweir 
341cdf0e10cSrcweir         /* let release-version behave friendly */
342cdf0e10cSrcweir         return;
343cdf0e10cSrcweir     }
344cdf0e10cSrcweir 
345cdf0e10cSrcweir     DosSetPriority( PRTYS_THREAD,
346cdf0e10cSrcweir                     nOs2PriorityClass, nOs2PriorityDelta,
347cdf0e10cSrcweir                     pThreadImpl->m_ThreadId );
348cdf0e10cSrcweir 
349cdf0e10cSrcweir }
350cdf0e10cSrcweir 
351cdf0e10cSrcweir /*****************************************************************************/
352cdf0e10cSrcweir /* osl_getThreadPriority  */
353cdf0e10cSrcweir /*****************************************************************************/
354cdf0e10cSrcweir 
355cdf0e10cSrcweir #define BYTE1FROMULONG(ul) ((UCHAR) (ul))
356cdf0e10cSrcweir #define BYTE2FROMULONG(ul) ((UCHAR) ((ULONG) ul >> 8))
357cdf0e10cSrcweir 
358cdf0e10cSrcweir oslThreadPriority  SAL_CALL osl_getThreadPriority(const oslThread Thread)
359cdf0e10cSrcweir {
360cdf0e10cSrcweir     ULONG nOs2PriorityClass;
361cdf0e10cSrcweir     ULONG nOs2PriorityDelta;
362cdf0e10cSrcweir 
363cdf0e10cSrcweir     oslThreadPriority Priority;
364cdf0e10cSrcweir 
365cdf0e10cSrcweir     osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread;
366cdf0e10cSrcweir 
367cdf0e10cSrcweir     /* invalid arguments ?*/
368cdf0e10cSrcweir     if(pThreadImpl==0 || pThreadImpl->m_ThreadId==-1)
369cdf0e10cSrcweir     {
370cdf0e10cSrcweir         return osl_Thread_PriorityUnknown;
371cdf0e10cSrcweir     }
372cdf0e10cSrcweir 
373cdf0e10cSrcweir     /* get current priorities */
374cdf0e10cSrcweir     {
375cdf0e10cSrcweir     PTIB pptib = NULL;
376cdf0e10cSrcweir     PPIB pppib = NULL;
377cdf0e10cSrcweir 
378cdf0e10cSrcweir     DosGetInfoBlocks( &pptib, &pppib );
379cdf0e10cSrcweir     nOs2PriorityClass = BYTE1FROMULONG( pptib->tib_ptib2->tib2_ulpri );
380cdf0e10cSrcweir     nOs2PriorityDelta = BYTE2FROMULONG( pptib->tib_ptib2->tib2_ulpri );
381cdf0e10cSrcweir     }
382cdf0e10cSrcweir 
383cdf0e10cSrcweir     /* map OS2 priority to enum */
384cdf0e10cSrcweir     switch(nOs2PriorityClass)
385cdf0e10cSrcweir     {
386cdf0e10cSrcweir     case PRTYC_TIMECRITICAL:
387cdf0e10cSrcweir         Priority= osl_Thread_PriorityHighest;
388cdf0e10cSrcweir         break;
389cdf0e10cSrcweir 
390cdf0e10cSrcweir     case PRTYC_REGULAR:
391cdf0e10cSrcweir 
392cdf0e10cSrcweir         if( nOs2PriorityDelta == 0 )
393cdf0e10cSrcweir         {
394cdf0e10cSrcweir             Priority= osl_Thread_PriorityNormal;
395cdf0e10cSrcweir             break;
396cdf0e10cSrcweir         }
397cdf0e10cSrcweir 
398cdf0e10cSrcweir         if( nOs2PriorityDelta < -16 )
399cdf0e10cSrcweir         {
400cdf0e10cSrcweir             Priority= osl_Thread_PriorityLowest;
401cdf0e10cSrcweir             break;
402cdf0e10cSrcweir         }
403cdf0e10cSrcweir 
404cdf0e10cSrcweir         if( nOs2PriorityDelta < 0 )
405cdf0e10cSrcweir         {
406cdf0e10cSrcweir             Priority= osl_Thread_PriorityBelowNormal;
407cdf0e10cSrcweir             break;
408cdf0e10cSrcweir         }
409cdf0e10cSrcweir 
410cdf0e10cSrcweir         if( nOs2PriorityDelta > 0 )
411cdf0e10cSrcweir         {
412cdf0e10cSrcweir             Priority= osl_Thread_PriorityAboveNormal;
413cdf0e10cSrcweir             break;
414cdf0e10cSrcweir         }
415cdf0e10cSrcweir 
416cdf0e10cSrcweir         Priority= osl_Thread_PriorityHighest;
417cdf0e10cSrcweir         break;
418cdf0e10cSrcweir 
419cdf0e10cSrcweir     case PRTYC_IDLETIME:
420cdf0e10cSrcweir         Priority= osl_Thread_PriorityLowest;
421cdf0e10cSrcweir         break;
422cdf0e10cSrcweir 
423cdf0e10cSrcweir     default:
424cdf0e10cSrcweir         OSL_ASSERT(FALSE);        /* OS/2 API changed, incorporate new prio-level! */
425cdf0e10cSrcweir 
426cdf0e10cSrcweir         /* release-version behaves friendly */
427cdf0e10cSrcweir         Priority= osl_Thread_PriorityUnknown;
428cdf0e10cSrcweir     }
429cdf0e10cSrcweir 
430cdf0e10cSrcweir     return Priority;
431cdf0e10cSrcweir }
432cdf0e10cSrcweir 
433cdf0e10cSrcweir /*****************************************************************************/
434cdf0e10cSrcweir /* osl_isThreadRunning */
435cdf0e10cSrcweir /*****************************************************************************/
436cdf0e10cSrcweir sal_Bool SAL_CALL osl_isThreadRunning(const oslThread Thread)
437cdf0e10cSrcweir {
438cdf0e10cSrcweir     osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread;
439cdf0e10cSrcweir     APIRET rc;
440cdf0e10cSrcweir 
441cdf0e10cSrcweir     /* invalid arguments ?*/
442cdf0e10cSrcweir     if(pThreadImpl==0 || pThreadImpl->m_ThreadId==-1)
443cdf0e10cSrcweir     {
444cdf0e10cSrcweir         return sal_False;
445cdf0e10cSrcweir     }
446cdf0e10cSrcweir 
447cdf0e10cSrcweir     if( osl_getThreadIdentifier( 0 ) == osl_getThreadIdentifier( Thread ) )
448cdf0e10cSrcweir         return sal_True;
449cdf0e10cSrcweir 
450cdf0e10cSrcweir     rc = DosWaitThread( &pThreadImpl->m_ThreadId, DCWW_NOWAIT );
451cdf0e10cSrcweir 
452cdf0e10cSrcweir     return( rc != ERROR_INVALID_THREADID );
453cdf0e10cSrcweir }
454cdf0e10cSrcweir 
455cdf0e10cSrcweir /*****************************************************************************/
456cdf0e10cSrcweir /* osl_joinWithThread */
457cdf0e10cSrcweir /*****************************************************************************/
458cdf0e10cSrcweir void SAL_CALL osl_joinWithThread(oslThread Thread)
459cdf0e10cSrcweir {
460cdf0e10cSrcweir     osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread;
461cdf0e10cSrcweir 
462cdf0e10cSrcweir     /* invalid arguments?*/
463cdf0e10cSrcweir     if(pThreadImpl==0 || pThreadImpl->m_ThreadId==-1)
464cdf0e10cSrcweir     {
465cdf0e10cSrcweir         /* assume thread is not running */
466cdf0e10cSrcweir         return;
467cdf0e10cSrcweir     }
468cdf0e10cSrcweir 
469cdf0e10cSrcweir     DosWaitThread( &pThreadImpl->m_ThreadId, DCWW_WAIT );
470cdf0e10cSrcweir }
471cdf0e10cSrcweir 
472cdf0e10cSrcweir /*****************************************************************************/
473cdf0e10cSrcweir /* osl_waitThread */
474cdf0e10cSrcweir /*****************************************************************************/
475cdf0e10cSrcweir void SAL_CALL osl_waitThread(const TimeValue* pDelay)
476cdf0e10cSrcweir {
477cdf0e10cSrcweir     int millisecs;
478cdf0e10cSrcweir 
479cdf0e10cSrcweir     OSL_ASSERT(pDelay);
480cdf0e10cSrcweir 
481cdf0e10cSrcweir     millisecs = pDelay->Seconds * 1000 + pDelay->Nanosec / 1000000;
482cdf0e10cSrcweir 
483cdf0e10cSrcweir     DosSleep(millisecs);
484cdf0e10cSrcweir }
485cdf0e10cSrcweir 
486cdf0e10cSrcweir /*****************************************************************************/
487cdf0e10cSrcweir /* osl_terminateThread */
488cdf0e10cSrcweir /*****************************************************************************/
489cdf0e10cSrcweir void SAL_CALL osl_terminateThread(oslThread Thread)
490cdf0e10cSrcweir {
491cdf0e10cSrcweir     osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread;
492cdf0e10cSrcweir 
493cdf0e10cSrcweir     /* invalid arguments?*/
494cdf0e10cSrcweir     if (pThreadImpl==0 || pThreadImpl->m_ThreadId==-1)
495cdf0e10cSrcweir     {
496cdf0e10cSrcweir         /* assume thread is not running */
497cdf0e10cSrcweir         return;
498cdf0e10cSrcweir     }
499cdf0e10cSrcweir 
500cdf0e10cSrcweir     DosRequestMutexSem( MutexLock, SEM_INDEFINITE_WAIT );
501cdf0e10cSrcweir     pThreadImpl->m_Flags |= THREADIMPL_FLAGS_TERMINATE;
502cdf0e10cSrcweir     DosReleaseMutexSem( MutexLock);
503cdf0e10cSrcweir }
504cdf0e10cSrcweir 
505cdf0e10cSrcweir 
506cdf0e10cSrcweir /*****************************************************************************/
507cdf0e10cSrcweir /* osl_scheduleThread */
508cdf0e10cSrcweir /*****************************************************************************/
509cdf0e10cSrcweir sal_Bool SAL_CALL osl_scheduleThread(oslThread Thread)
510cdf0e10cSrcweir {
511cdf0e10cSrcweir     osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread;
512cdf0e10cSrcweir 
513cdf0e10cSrcweir     osl_yieldThread();
514cdf0e10cSrcweir 
515cdf0e10cSrcweir     /* invalid arguments?*/
516cdf0e10cSrcweir     if (pThreadImpl==0 || pThreadImpl->m_ThreadId==-1)
517cdf0e10cSrcweir     {
518cdf0e10cSrcweir         /* assume thread is not running */
519cdf0e10cSrcweir         return sal_False;
520cdf0e10cSrcweir     }
521cdf0e10cSrcweir 
522cdf0e10cSrcweir     if (pThreadImpl->m_Flags & THREADIMPL_FLAGS_SLEEP)
523cdf0e10cSrcweir     {
524cdf0e10cSrcweir         OSL_ASSERT (pThreadImpl->m_hEvent != 0);
525cdf0e10cSrcweir 
526cdf0e10cSrcweir         DosWaitEventSem(pThreadImpl->m_hEvent, pThreadImpl->m_Timeout);
527cdf0e10cSrcweir 
528cdf0e10cSrcweir         DosRequestMutexSem( MutexLock, SEM_INDEFINITE_WAIT );
529cdf0e10cSrcweir 
530cdf0e10cSrcweir         pThreadImpl->m_Timeout = 0;
531cdf0e10cSrcweir 
532cdf0e10cSrcweir         pThreadImpl->m_Flags &= ~THREADIMPL_FLAGS_SLEEP;
533cdf0e10cSrcweir 
534cdf0e10cSrcweir         DosReleaseMutexSem( MutexLock);
535cdf0e10cSrcweir     }
536cdf0e10cSrcweir 
537cdf0e10cSrcweir     return ((pThreadImpl->m_Flags & THREADIMPL_FLAGS_TERMINATE) == 0);
538cdf0e10cSrcweir }
539cdf0e10cSrcweir 
540cdf0e10cSrcweir /*****************************************************************************/
541cdf0e10cSrcweir /* osl_yieldThread */
542cdf0e10cSrcweir /*****************************************************************************/
543cdf0e10cSrcweir void SAL_CALL osl_yieldThread()
544cdf0e10cSrcweir {
545cdf0e10cSrcweir     DosSleep(0);
546cdf0e10cSrcweir }
547cdf0e10cSrcweir 
548cdf0e10cSrcweir void osl_setThreadName(char const * name) {
549cdf0e10cSrcweir     (void) name;
550cdf0e10cSrcweir }
551cdf0e10cSrcweir 
552cdf0e10cSrcweir typedef struct _TLS
553cdf0e10cSrcweir {
554cdf0e10cSrcweir     PULONG                          pulPtr;
555cdf0e10cSrcweir     oslThreadKeyCallbackFunction    pfnCallback;
556cdf0e10cSrcweir     struct _TLS                     *pNext, *pPrev;
557cdf0e10cSrcweir } TLS, *PTLS;
558cdf0e10cSrcweir 
559cdf0e10cSrcweir static  PTLS        g_pThreadKeyList = NULL;
560cdf0e10cSrcweir 
561cdf0e10cSrcweir static void AddKeyToList( PTLS pTls )
562cdf0e10cSrcweir {
563cdf0e10cSrcweir     if ( pTls )
564cdf0e10cSrcweir     {
565cdf0e10cSrcweir         DosRequestMutexSem( MutexLock, SEM_INDEFINITE_WAIT );
566cdf0e10cSrcweir 
567cdf0e10cSrcweir         pTls->pNext = g_pThreadKeyList;
568cdf0e10cSrcweir         pTls->pPrev = 0;
569cdf0e10cSrcweir 
570cdf0e10cSrcweir         if ( g_pThreadKeyList )
571cdf0e10cSrcweir             g_pThreadKeyList->pPrev = pTls;
572cdf0e10cSrcweir 
573cdf0e10cSrcweir         g_pThreadKeyList = pTls;
574cdf0e10cSrcweir 
575cdf0e10cSrcweir         DosReleaseMutexSem( MutexLock);
576cdf0e10cSrcweir     }
577cdf0e10cSrcweir }
578cdf0e10cSrcweir 
579cdf0e10cSrcweir static void RemoveKeyFromList( PTLS pTls )
580cdf0e10cSrcweir {
581cdf0e10cSrcweir     if ( pTls )
582cdf0e10cSrcweir     {
583cdf0e10cSrcweir         DosRequestMutexSem( MutexLock, SEM_INDEFINITE_WAIT );
584cdf0e10cSrcweir         if ( pTls->pPrev )
585cdf0e10cSrcweir             pTls->pPrev->pNext = pTls->pNext;
586cdf0e10cSrcweir         else
587cdf0e10cSrcweir         {
588cdf0e10cSrcweir             OSL_ASSERT( pTls == g_pThreadKeyList );
589cdf0e10cSrcweir             g_pThreadKeyList = pTls->pNext;
590cdf0e10cSrcweir         }
591cdf0e10cSrcweir 
592cdf0e10cSrcweir         if ( pTls->pNext )
593cdf0e10cSrcweir             pTls->pNext->pPrev = pTls->pPrev;
594cdf0e10cSrcweir         DosReleaseMutexSem( MutexLock);
595cdf0e10cSrcweir     }
596cdf0e10cSrcweir }
597cdf0e10cSrcweir 
598cdf0e10cSrcweir void SAL_CALL _osl_callThreadKeyCallbackOnThreadDetach(void)
599cdf0e10cSrcweir {
600cdf0e10cSrcweir     PTLS    pTls;
601cdf0e10cSrcweir 
602cdf0e10cSrcweir     DosRequestMutexSem( MutexLock, SEM_INDEFINITE_WAIT );
603cdf0e10cSrcweir     pTls = g_pThreadKeyList;
604cdf0e10cSrcweir     while ( pTls )
605cdf0e10cSrcweir     {
606cdf0e10cSrcweir         if ( pTls->pfnCallback )
607cdf0e10cSrcweir         {
608cdf0e10cSrcweir             void    *pValue = (void*)*pTls->pulPtr;
609cdf0e10cSrcweir 
610cdf0e10cSrcweir             if ( pValue )
611cdf0e10cSrcweir                 pTls->pfnCallback( pValue );
612cdf0e10cSrcweir         }
613cdf0e10cSrcweir 
614cdf0e10cSrcweir         pTls = pTls->pNext;
615cdf0e10cSrcweir     }
616cdf0e10cSrcweir     DosReleaseMutexSem( MutexLock);
617cdf0e10cSrcweir }
618cdf0e10cSrcweir 
619cdf0e10cSrcweir /*****************************************************************************/
620cdf0e10cSrcweir /* osl_createThreadKey */
621cdf0e10cSrcweir /*****************************************************************************/
622cdf0e10cSrcweir oslThreadKey SAL_CALL osl_createThreadKey(oslThreadKeyCallbackFunction pCallback)
623cdf0e10cSrcweir {
624cdf0e10cSrcweir     PTLS    pTls = (PTLS)rtl_allocateMemory( sizeof(TLS) );
625cdf0e10cSrcweir 
626cdf0e10cSrcweir     if ( pTls )
627cdf0e10cSrcweir     {
628cdf0e10cSrcweir         pTls->pfnCallback = pCallback;
629cdf0e10cSrcweir         if (DosAllocThreadLocalMemory(1, &pTls->pulPtr) != NO_ERROR)
630cdf0e10cSrcweir         {
631cdf0e10cSrcweir             rtl_freeMemory( pTls );
632cdf0e10cSrcweir             pTls = 0;
633cdf0e10cSrcweir         }
634cdf0e10cSrcweir         else
635cdf0e10cSrcweir         {
636cdf0e10cSrcweir             *pTls->pulPtr = 0;
637cdf0e10cSrcweir             AddKeyToList( pTls );
638cdf0e10cSrcweir         }
639cdf0e10cSrcweir     }
640cdf0e10cSrcweir 
641cdf0e10cSrcweir     return ((oslThreadKey)pTls);
642cdf0e10cSrcweir }
643cdf0e10cSrcweir 
644cdf0e10cSrcweir /*****************************************************************************/
645cdf0e10cSrcweir /* osl_destroyThreadKey */
646cdf0e10cSrcweir /*****************************************************************************/
647cdf0e10cSrcweir void SAL_CALL osl_destroyThreadKey(oslThreadKey Key)
648cdf0e10cSrcweir {
649cdf0e10cSrcweir     if (Key != 0)
650cdf0e10cSrcweir     {
651cdf0e10cSrcweir         PTLS    pTls = (PTLS)Key;
652cdf0e10cSrcweir 
653cdf0e10cSrcweir         RemoveKeyFromList( pTls );
654cdf0e10cSrcweir         DosFreeThreadLocalMemory(pTls->pulPtr);
655cdf0e10cSrcweir         rtl_freeMemory( pTls );
656cdf0e10cSrcweir     }
657cdf0e10cSrcweir }
658cdf0e10cSrcweir 
659cdf0e10cSrcweir /*****************************************************************************/
660cdf0e10cSrcweir /* osl_getThreadKeyData */
661cdf0e10cSrcweir /*****************************************************************************/
662cdf0e10cSrcweir void * SAL_CALL osl_getThreadKeyData(oslThreadKey Key)
663cdf0e10cSrcweir {
664cdf0e10cSrcweir     if (Key != 0)
665cdf0e10cSrcweir     {
666cdf0e10cSrcweir         PTLS    pTls = (PTLS)Key;
667cdf0e10cSrcweir 
668cdf0e10cSrcweir         return ((void *) *pTls->pulPtr);
669cdf0e10cSrcweir     }
670cdf0e10cSrcweir 
671cdf0e10cSrcweir     return (NULL);
672cdf0e10cSrcweir }
673cdf0e10cSrcweir 
674cdf0e10cSrcweir /*****************************************************************************/
675cdf0e10cSrcweir /* osl_setThreadKeyData */
676cdf0e10cSrcweir /*****************************************************************************/
677cdf0e10cSrcweir sal_Bool SAL_CALL osl_setThreadKeyData(oslThreadKey Key, void *pData)
678cdf0e10cSrcweir {
679cdf0e10cSrcweir     if (Key != 0)
680cdf0e10cSrcweir     {
681cdf0e10cSrcweir         PTLS    pTls = (PTLS)Key;
682cdf0e10cSrcweir         void*   pOldData = NULL;
683cdf0e10cSrcweir         BOOL    fSuccess = TRUE; //YD cannot fail
684cdf0e10cSrcweir 
685cdf0e10cSrcweir         if ( pTls->pfnCallback )
686cdf0e10cSrcweir             pOldData = (void*)*pTls->pulPtr;
687cdf0e10cSrcweir 
688cdf0e10cSrcweir         *pTls->pulPtr = (ULONG)pData;
689cdf0e10cSrcweir 
690cdf0e10cSrcweir         if ( fSuccess && pTls->pfnCallback && pOldData )
691cdf0e10cSrcweir             pTls->pfnCallback( pOldData );
692cdf0e10cSrcweir 
693cdf0e10cSrcweir         return (sal_Bool)(fSuccess != FALSE);
694cdf0e10cSrcweir     }
695cdf0e10cSrcweir 
696cdf0e10cSrcweir     return (sal_False);
697cdf0e10cSrcweir }
698cdf0e10cSrcweir 
699cdf0e10cSrcweir 
700cdf0e10cSrcweir 
701cdf0e10cSrcweir /*****************************************************************************/
702cdf0e10cSrcweir /* osl_getThreadTextEncoding */
703cdf0e10cSrcweir /*****************************************************************************/
704cdf0e10cSrcweir 
705cdf0e10cSrcweir ULONG   g_dwTLSTextEncodingIndex = (ULONG)-1;
706cdf0e10cSrcweir 
707cdf0e10cSrcweir sal_uInt32 SAL_CALL _GetACP( void)
708cdf0e10cSrcweir {
709cdf0e10cSrcweir     APIRET  rc;
710cdf0e10cSrcweir     ULONG   aulCpList[8]  = {0};
711cdf0e10cSrcweir     ULONG   ulListSize;
712cdf0e10cSrcweir 
713cdf0e10cSrcweir     rc = DosQueryCp( sizeof( aulCpList), aulCpList, &ulListSize);
714cdf0e10cSrcweir     if (rc)
715cdf0e10cSrcweir         return 437; // in case of error, return codepage EN_US
716cdf0e10cSrcweir     // current codepage is first of list, others are the prepared codepages.
717cdf0e10cSrcweir     return aulCpList[0];
718cdf0e10cSrcweir }
719cdf0e10cSrcweir 
720cdf0e10cSrcweir rtl_TextEncoding SAL_CALL osl_getThreadTextEncoding(void)
721cdf0e10cSrcweir {
722cdf0e10cSrcweir     rtl_TextEncoding    _encoding;
723cdf0e10cSrcweir 
724cdf0e10cSrcweir     if ( (ULONG)-1 == g_dwTLSTextEncodingIndex ) {
725cdf0e10cSrcweir         rtl_TextEncoding defaultEncoding;
726cdf0e10cSrcweir         const char *     pszEncoding;
727cdf0e10cSrcweir 
728cdf0e10cSrcweir         /* create thread specific data key */
729cdf0e10cSrcweir         g_dwTLSTextEncodingIndex = osl_createThreadKey( NULL);
730cdf0e10cSrcweir 
731cdf0e10cSrcweir         /* determine default text encoding */
732cdf0e10cSrcweir         pszEncoding = getenv ("SOLAR_USER_RTL_TEXTENCODING");
733cdf0e10cSrcweir         if (pszEncoding)
734cdf0e10cSrcweir             defaultEncoding = atoi(pszEncoding);
735cdf0e10cSrcweir         else
736cdf0e10cSrcweir             defaultEncoding = rtl_getTextEncodingFromWindowsCodePage( _GetACP());
737cdf0e10cSrcweir 
738cdf0e10cSrcweir         //OSL_ASSERT(defaultEncoding != RTL_TEXTENCODING_DONTKNOW);
739cdf0e10cSrcweir         //g_thread.m_textencoding.m_default = defaultEncoding;
740cdf0e10cSrcweir         osl_setThreadKeyData( g_dwTLSTextEncodingIndex, (void*)defaultEncoding);
741cdf0e10cSrcweir     }
742cdf0e10cSrcweir 
743cdf0e10cSrcweir     _encoding = (rtl_TextEncoding)osl_getThreadKeyData( g_dwTLSTextEncodingIndex );
744cdf0e10cSrcweir     if (0 == _encoding) {
745cdf0e10cSrcweir         const char *     pszEncoding;
746cdf0e10cSrcweir         /* determine default text encoding */
747cdf0e10cSrcweir         pszEncoding = getenv ("SOLAR_USER_RTL_TEXTENCODING");
748cdf0e10cSrcweir         if (pszEncoding)
749cdf0e10cSrcweir             _encoding = atoi(pszEncoding);
750cdf0e10cSrcweir         else
751cdf0e10cSrcweir             _encoding = rtl_getTextEncodingFromWindowsCodePage( _GetACP());
752cdf0e10cSrcweir         /* save for future reference */
753cdf0e10cSrcweir         osl_setThreadKeyData( g_dwTLSTextEncodingIndex, (void*)_encoding);
754cdf0e10cSrcweir     }
755cdf0e10cSrcweir 
756cdf0e10cSrcweir     return _encoding;
757cdf0e10cSrcweir }
758cdf0e10cSrcweir 
759cdf0e10cSrcweir /*****************************************************************************/
760cdf0e10cSrcweir /* osl_getThreadTextEncoding */
761cdf0e10cSrcweir /*****************************************************************************/
762cdf0e10cSrcweir rtl_TextEncoding SAL_CALL osl_setThreadTextEncoding( rtl_TextEncoding Encoding )
763cdf0e10cSrcweir {
764cdf0e10cSrcweir     rtl_TextEncoding oldEncoding = osl_getThreadTextEncoding();
765cdf0e10cSrcweir 
766cdf0e10cSrcweir     osl_setThreadKeyData( g_dwTLSTextEncodingIndex, (void*)Encoding);
767cdf0e10cSrcweir 
768cdf0e10cSrcweir     return oldEncoding;
769cdf0e10cSrcweir }
770cdf0e10cSrcweir 
771cdf0e10cSrcweir 
772cdf0e10cSrcweir 
773