1647f063dSAndrew Rist /**************************************************************
2*18a2cb5fSmseidel *
3647f063dSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4647f063dSAndrew Rist * or more contributor license agreements. See the NOTICE file
5647f063dSAndrew Rist * distributed with this work for additional information
6647f063dSAndrew Rist * regarding copyright ownership. The ASF licenses this file
7647f063dSAndrew Rist * to you under the Apache License, Version 2.0 (the
8647f063dSAndrew Rist * "License"); you may not use this file except in compliance
9647f063dSAndrew Rist * with the License. You may obtain a copy of the License at
10*18a2cb5fSmseidel *
11647f063dSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12*18a2cb5fSmseidel *
13647f063dSAndrew Rist * Unless required by applicable law or agreed to in writing,
14647f063dSAndrew Rist * software distributed under the License is distributed on an
15647f063dSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16647f063dSAndrew Rist * KIND, either express or implied. See the License for the
17647f063dSAndrew Rist * specific language governing permissions and limitations
18647f063dSAndrew Rist * under the License.
19*18a2cb5fSmseidel *
20647f063dSAndrew Rist *************************************************************/
21647f063dSAndrew Rist
22647f063dSAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir #include "system.h"
25cdf0e10cSrcweir #include <string.h>
26cdf0e10cSrcweir #include <osl/diagnose.h>
27cdf0e10cSrcweir #include <osl/thread.h>
28cdf0e10cSrcweir #include <osl/nlsupport.h>
29cdf0e10cSrcweir #ifndef _RTL_TEXTENC_H_
30cdf0e10cSrcweir #include <rtl/textenc.h>
31cdf0e10cSrcweir #endif
32cdf0e10cSrcweir
33cdf0e10cSrcweir #if defined LINUX
34cdf0e10cSrcweir #include <sys/prctl.h>
35cdf0e10cSrcweir #endif
36cdf0e10cSrcweir
37cdf0e10cSrcweir /****************************************************************************
38cdf0e10cSrcweir * @@@ TODO @@@
39cdf0e10cSrcweir *
40cdf0e10cSrcweir * (1) 'osl_thread_priority_init_Impl()'
41cdf0e10cSrcweir * - insane assumption that initializing caller is main thread
42cdf0e10cSrcweir * - use _POSIX_THREAD_PRIORITY_SCHEDULING, not NO_PTHREAD_PRIORITY (?)
43cdf0e10cSrcweir * - POSIX doesn't require defined prio's for SCHED_OTHER (!)
44cdf0e10cSrcweir * - use SCHED_RR instead of SCHED_OTHER for defined behaviour (?)
45cdf0e10cSrcweir * (2) 'oslThreadIdentifier' and '{insert|remove|lookup}ThreadId()'
46cdf0e10cSrcweir * - cannot reliably be applied to 'alien' threads;
47cdf0e10cSrcweir * - memory leak for 'alien' thread 'HashEntry's;
48cdf0e10cSrcweir * - use 'PTHREAD_VALUE(pthread_t)' as identifier instead (?)
49cdf0e10cSrcweir * - if yes, change 'oslThreadIdentifier' to 'intptr_t' or similar
50cdf0e10cSrcweir * (3) 'oslSigAlarmHandler()' (#71232#)
51cdf0e10cSrcweir * - [Under Solaris we get SIGALRM in e.g. pthread_join which terminates
52cdf0e10cSrcweir * the process. So we initialize our signal handling module and do
53cdf0e10cSrcweir * register a SIGALRM Handler which catches and ignores it]
54cdf0e10cSrcweir * - should this still happen, 'signal.c' needs to be fixed instead.
55cdf0e10cSrcweir *
56cdf0e10cSrcweir ****************************************************************************/
57cdf0e10cSrcweir
58cdf0e10cSrcweir /*****************************************************************************/
59cdf0e10cSrcweir /* Internal data structures and functions */
60cdf0e10cSrcweir /*****************************************************************************/
61cdf0e10cSrcweir
62cdf0e10cSrcweir #define THREADIMPL_FLAGS_TERMINATE 0x00001
63cdf0e10cSrcweir #define THREADIMPL_FLAGS_STARTUP 0x00002
64cdf0e10cSrcweir #define THREADIMPL_FLAGS_SUSPENDED 0x00004
65cdf0e10cSrcweir #define THREADIMPL_FLAGS_ACTIVE 0x00008
66cdf0e10cSrcweir #define THREADIMPL_FLAGS_ATTACHED 0x00010
67cdf0e10cSrcweir #define THREADIMPL_FLAGS_DESTROYED 0x00020
68cdf0e10cSrcweir
69cdf0e10cSrcweir typedef struct osl_thread_impl_st
70cdf0e10cSrcweir {
71cdf0e10cSrcweir pthread_t m_hThread;
72cdf0e10cSrcweir sal_uInt16 m_Ident; /* @@@ see TODO @@@ */
73*18a2cb5fSmseidel short m_Flags;
74*18a2cb5fSmseidel oslWorkerFunction m_WorkerFunction;
75cdf0e10cSrcweir void* m_pData;
76cdf0e10cSrcweir pthread_mutex_t m_Lock;
77cdf0e10cSrcweir pthread_cond_t m_Cond;
78cdf0e10cSrcweir } Thread_Impl;
79cdf0e10cSrcweir
80cdf0e10cSrcweir struct osl_thread_priority_st
81cdf0e10cSrcweir {
82cdf0e10cSrcweir int m_Highest;
83cdf0e10cSrcweir int m_Above_Normal;
84cdf0e10cSrcweir int m_Normal;
85cdf0e10cSrcweir int m_Below_Normal;
86cdf0e10cSrcweir int m_Lowest;
87cdf0e10cSrcweir };
88cdf0e10cSrcweir
89cdf0e10cSrcweir #define OSL_THREAD_PRIORITY_INITIALIZER { 127, 96, 64, 32, 0 }
90cdf0e10cSrcweir static void osl_thread_priority_init_Impl (void);
91cdf0e10cSrcweir
92cdf0e10cSrcweir struct osl_thread_textencoding_st
93cdf0e10cSrcweir {
94cdf0e10cSrcweir pthread_key_t m_key; /* key to store thread local text encoding */
95cdf0e10cSrcweir rtl_TextEncoding m_default; /* the default text encoding */
96cdf0e10cSrcweir };
97cdf0e10cSrcweir
98cdf0e10cSrcweir #define OSL_THREAD_TEXTENCODING_INITIALIZER { 0, RTL_TEXTENCODING_DONTKNOW }
99cdf0e10cSrcweir static void osl_thread_textencoding_init_Impl (void);
100cdf0e10cSrcweir
101cdf0e10cSrcweir struct osl_thread_global_st
102cdf0e10cSrcweir {
103cdf0e10cSrcweir pthread_once_t m_once;
104cdf0e10cSrcweir struct osl_thread_priority_st m_priority;
105cdf0e10cSrcweir struct osl_thread_textencoding_st m_textencoding;
106cdf0e10cSrcweir };
107cdf0e10cSrcweir
108cdf0e10cSrcweir static struct osl_thread_global_st g_thread =
109cdf0e10cSrcweir {
110cdf0e10cSrcweir PTHREAD_ONCE_INIT,
111cdf0e10cSrcweir OSL_THREAD_PRIORITY_INITIALIZER,
112cdf0e10cSrcweir OSL_THREAD_TEXTENCODING_INITIALIZER
113cdf0e10cSrcweir };
114cdf0e10cSrcweir
115cdf0e10cSrcweir static void osl_thread_init_Impl (void);
116cdf0e10cSrcweir
117cdf0e10cSrcweir static Thread_Impl* osl_thread_construct_Impl (void);
118cdf0e10cSrcweir static void osl_thread_destruct_Impl (Thread_Impl ** ppImpl);
119cdf0e10cSrcweir
120cdf0e10cSrcweir static void* osl_thread_start_Impl (void * pData);
121cdf0e10cSrcweir static void osl_thread_cleanup_Impl (void * pData);
122cdf0e10cSrcweir
123cdf0e10cSrcweir static oslThread osl_thread_create_Impl (
124cdf0e10cSrcweir oslWorkerFunction pWorker, void * pThreadData, short nFlags);
125cdf0e10cSrcweir
126cdf0e10cSrcweir static void osl_thread_join_cleanup_Impl (void * opaque);
127cdf0e10cSrcweir static void osl_thread_wait_cleanup_Impl (void * opaque);
128cdf0e10cSrcweir
129cdf0e10cSrcweir /* @@@ see TODO @@@ */
130cdf0e10cSrcweir static sal_uInt16 insertThreadId (pthread_t hThread);
131cdf0e10cSrcweir static sal_uInt16 lookupThreadId (pthread_t hThread);
132cdf0e10cSrcweir static void removeThreadId (pthread_t hThread);
133cdf0e10cSrcweir
134cdf0e10cSrcweir /*****************************************************************************/
135cdf0e10cSrcweir /* osl_thread_init_Impl */
136cdf0e10cSrcweir /*****************************************************************************/
osl_thread_init_Impl(void)137cdf0e10cSrcweir static void osl_thread_init_Impl (void)
138cdf0e10cSrcweir {
139cdf0e10cSrcweir osl_thread_priority_init_Impl();
140cdf0e10cSrcweir osl_thread_textencoding_init_Impl();
141cdf0e10cSrcweir }
142cdf0e10cSrcweir
143cdf0e10cSrcweir /*****************************************************************************/
144cdf0e10cSrcweir /* osl_thread_join_cleanup_Impl */
145cdf0e10cSrcweir /*****************************************************************************/
osl_thread_join_cleanup_Impl(void * opaque)146cdf0e10cSrcweir static void osl_thread_join_cleanup_Impl (void * opaque)
147cdf0e10cSrcweir {
148cdf0e10cSrcweir pthread_t hThread = (pthread_t)(opaque);
149cdf0e10cSrcweir pthread_detach (hThread);
150cdf0e10cSrcweir }
151cdf0e10cSrcweir
152cdf0e10cSrcweir /*****************************************************************************/
153cdf0e10cSrcweir /* osl_thread_wait_cleanup_Impl */
154cdf0e10cSrcweir /*****************************************************************************/
osl_thread_wait_cleanup_Impl(void * opaque)155cdf0e10cSrcweir static void osl_thread_wait_cleanup_Impl (void * opaque)
156cdf0e10cSrcweir {
157cdf0e10cSrcweir pthread_mutex_t * pMutex = (pthread_mutex_t*)(opaque);
158cdf0e10cSrcweir pthread_mutex_unlock (pMutex);
159cdf0e10cSrcweir }
160cdf0e10cSrcweir
161cdf0e10cSrcweir /*****************************************************************************/
162cdf0e10cSrcweir /* osl_thread_construct_Impl */
163cdf0e10cSrcweir /*****************************************************************************/
osl_thread_construct_Impl(void)164cdf0e10cSrcweir Thread_Impl* osl_thread_construct_Impl (void)
165cdf0e10cSrcweir {
166cdf0e10cSrcweir Thread_Impl* pImpl = malloc (sizeof(Thread_Impl));
167cdf0e10cSrcweir if (pImpl)
168cdf0e10cSrcweir {
169cdf0e10cSrcweir memset (pImpl, 0, sizeof(Thread_Impl));
170cdf0e10cSrcweir
171cdf0e10cSrcweir pthread_mutex_init (&(pImpl->m_Lock), PTHREAD_MUTEXATTR_DEFAULT);
172cdf0e10cSrcweir pthread_cond_init (&(pImpl->m_Cond), PTHREAD_CONDATTR_DEFAULT);
173cdf0e10cSrcweir }
174cdf0e10cSrcweir return (pImpl);
175cdf0e10cSrcweir }
176cdf0e10cSrcweir
177cdf0e10cSrcweir /*****************************************************************************/
178cdf0e10cSrcweir /* osl_thread_destruct_Impl */
179cdf0e10cSrcweir /*****************************************************************************/
osl_thread_destruct_Impl(Thread_Impl ** ppImpl)180cdf0e10cSrcweir static void osl_thread_destruct_Impl (Thread_Impl ** ppImpl)
181cdf0e10cSrcweir {
182cdf0e10cSrcweir OSL_ASSERT(ppImpl);
183cdf0e10cSrcweir if (*ppImpl)
184cdf0e10cSrcweir {
185cdf0e10cSrcweir pthread_cond_destroy (&((*ppImpl)->m_Cond));
186cdf0e10cSrcweir pthread_mutex_destroy (&((*ppImpl)->m_Lock));
187cdf0e10cSrcweir
188cdf0e10cSrcweir free (*ppImpl);
189509a48ffSpfg (*ppImpl) = NULL;
190cdf0e10cSrcweir }
191cdf0e10cSrcweir }
192cdf0e10cSrcweir
193cdf0e10cSrcweir /*****************************************************************************/
194cdf0e10cSrcweir /* osl_thread_cleanup_Impl */
195cdf0e10cSrcweir /*****************************************************************************/
osl_thread_cleanup_Impl(void * pData)196cdf0e10cSrcweir static void osl_thread_cleanup_Impl (void* pData)
197cdf0e10cSrcweir {
198*18a2cb5fSmseidel pthread_t thread;
199*18a2cb5fSmseidel int attached;
200*18a2cb5fSmseidel int destroyed;
201cdf0e10cSrcweir Thread_Impl* pImpl= (Thread_Impl*)pData;
202cdf0e10cSrcweir
203cdf0e10cSrcweir pthread_mutex_lock (&(pImpl->m_Lock));
204cdf0e10cSrcweir
205*18a2cb5fSmseidel thread = pImpl->m_hThread;
206*18a2cb5fSmseidel attached = (pImpl->m_Flags & THREADIMPL_FLAGS_ATTACHED) != 0;
207*18a2cb5fSmseidel destroyed = (pImpl->m_Flags & THREADIMPL_FLAGS_DESTROYED) != 0;
208*18a2cb5fSmseidel pImpl->m_Flags &= ~(THREADIMPL_FLAGS_ACTIVE | THREADIMPL_FLAGS_ATTACHED);
209cdf0e10cSrcweir
210cdf0e10cSrcweir pthread_mutex_unlock (&(pImpl->m_Lock));
211cdf0e10cSrcweir
212*18a2cb5fSmseidel /* release oslThreadIdentifier @@@ see TODO @@@ */
213*18a2cb5fSmseidel removeThreadId (thread);
214cdf0e10cSrcweir
215*18a2cb5fSmseidel if (attached)
216*18a2cb5fSmseidel {
217*18a2cb5fSmseidel pthread_detach (thread);
218*18a2cb5fSmseidel }
219cdf0e10cSrcweir
220*18a2cb5fSmseidel if (destroyed)
221*18a2cb5fSmseidel {
222cdf0e10cSrcweir osl_thread_destruct_Impl (&pImpl);
223cdf0e10cSrcweir }
224cdf0e10cSrcweir }
225cdf0e10cSrcweir
226cdf0e10cSrcweir /*****************************************************************************/
227cdf0e10cSrcweir /* osl_thread_start_Impl */
228cdf0e10cSrcweir /*****************************************************************************/
osl_thread_start_Impl(void * pData)229cdf0e10cSrcweir static void* osl_thread_start_Impl (void* pData)
230cdf0e10cSrcweir {
231cdf0e10cSrcweir int terminate;
232cdf0e10cSrcweir Thread_Impl* pImpl= (Thread_Impl*)pData;
233cdf0e10cSrcweir
234cdf0e10cSrcweir OSL_ASSERT(pImpl);
235cdf0e10cSrcweir
236*18a2cb5fSmseidel pthread_mutex_lock (&(pImpl->m_Lock));
237cdf0e10cSrcweir
238cdf0e10cSrcweir /* install cleanup handler */
239*18a2cb5fSmseidel pthread_cleanup_push (osl_thread_cleanup_Impl, pData);
240cdf0e10cSrcweir
241cdf0e10cSrcweir /* request oslThreadIdentifier @@@ see TODO @@@ */
242cdf0e10cSrcweir pImpl->m_Ident = insertThreadId (pImpl->m_hThread);
243cdf0e10cSrcweir
244cdf0e10cSrcweir /* signal change from STARTUP to ACTIVE state */
245cdf0e10cSrcweir pImpl->m_Flags &= ~THREADIMPL_FLAGS_STARTUP;
246cdf0e10cSrcweir pImpl->m_Flags |= THREADIMPL_FLAGS_ACTIVE;
247*18a2cb5fSmseidel pthread_cond_signal (&(pImpl->m_Cond));
248cdf0e10cSrcweir
249cdf0e10cSrcweir /* Check if thread is started in SUSPENDED state */
250*18a2cb5fSmseidel while (pImpl->m_Flags & THREADIMPL_FLAGS_SUSPENDED)
251*18a2cb5fSmseidel {
252*18a2cb5fSmseidel /* wait until SUSPENDED flag is cleared */
253cdf0e10cSrcweir pthread_cleanup_push (osl_thread_wait_cleanup_Impl, &(pImpl->m_Lock));
254cdf0e10cSrcweir pthread_cond_wait (&(pImpl->m_Cond), &(pImpl->m_Lock));
255cdf0e10cSrcweir pthread_cleanup_pop (0);
256*18a2cb5fSmseidel }
257cdf0e10cSrcweir
258cdf0e10cSrcweir /* check for SUSPENDED to TERMINATE state change */
259cdf0e10cSrcweir terminate = ((pImpl->m_Flags & THREADIMPL_FLAGS_TERMINATE) > 0);
260cdf0e10cSrcweir
261*18a2cb5fSmseidel pthread_mutex_unlock (&(pImpl->m_Lock));
262cdf0e10cSrcweir
263cdf0e10cSrcweir if (!terminate)
264cdf0e10cSrcweir {
265cdf0e10cSrcweir /* call worker function */
266cdf0e10cSrcweir pImpl->m_WorkerFunction(pImpl->m_pData);
267cdf0e10cSrcweir }
268cdf0e10cSrcweir
269cdf0e10cSrcweir /* call cleanup handler and leave */
270cdf0e10cSrcweir pthread_cleanup_pop (1);
271cdf0e10cSrcweir return (0);
272cdf0e10cSrcweir }
273cdf0e10cSrcweir
274cdf0e10cSrcweir /*****************************************************************************/
275cdf0e10cSrcweir /* osl_thread_create_Impl */
276cdf0e10cSrcweir /*****************************************************************************/
osl_thread_create_Impl(oslWorkerFunction pWorker,void * pThreadData,short nFlags)277cdf0e10cSrcweir static oslThread osl_thread_create_Impl (
278cdf0e10cSrcweir oslWorkerFunction pWorker,
279cdf0e10cSrcweir void* pThreadData,
280cdf0e10cSrcweir short nFlags)
281cdf0e10cSrcweir {
282cdf0e10cSrcweir Thread_Impl* pImpl;
283*18a2cb5fSmseidel int nRet=0;
284cdf0e10cSrcweir
285cdf0e10cSrcweir pImpl = osl_thread_construct_Impl();
286*18a2cb5fSmseidel if (!pImpl)
287*18a2cb5fSmseidel return (0); /* ENOMEM */
288cdf0e10cSrcweir
289cdf0e10cSrcweir pImpl->m_WorkerFunction = pWorker;
290cdf0e10cSrcweir pImpl->m_pData = pThreadData;
291cdf0e10cSrcweir pImpl->m_Flags = nFlags | THREADIMPL_FLAGS_STARTUP;
292cdf0e10cSrcweir
293*18a2cb5fSmseidel pthread_mutex_lock (&(pImpl->m_Lock));
294cdf0e10cSrcweir
295cdf0e10cSrcweir if ((nRet = pthread_create (
296cdf0e10cSrcweir &(pImpl->m_hThread),
297cdf0e10cSrcweir PTHREAD_ATTR_DEFAULT,
298cdf0e10cSrcweir osl_thread_start_Impl,
299cdf0e10cSrcweir (void*)(pImpl))) != 0)
300cdf0e10cSrcweir {
301*18a2cb5fSmseidel OSL_TRACE("osl_thread_create_Impl(): errno: %d, %s\n", nRet, strerror(nRet));
302cdf0e10cSrcweir
303cdf0e10cSrcweir pthread_mutex_unlock (&(pImpl->m_Lock));
304cdf0e10cSrcweir osl_thread_destruct_Impl (&pImpl);
305cdf0e10cSrcweir
306cdf0e10cSrcweir return (0);
307cdf0e10cSrcweir }
308cdf0e10cSrcweir
309cdf0e10cSrcweir /* wait for change from STARTUP to ACTIVE state */
310cdf0e10cSrcweir while (pImpl->m_Flags & THREADIMPL_FLAGS_STARTUP)
311cdf0e10cSrcweir {
312cdf0e10cSrcweir /* wait until STARTUP flag is cleared */
313cdf0e10cSrcweir pthread_cleanup_push (osl_thread_wait_cleanup_Impl, &(pImpl->m_Lock));
314*18a2cb5fSmseidel pthread_cond_wait (&(pImpl->m_Cond), &(pImpl->m_Lock));
315cdf0e10cSrcweir pthread_cleanup_pop (0);
316*18a2cb5fSmseidel }
317cdf0e10cSrcweir
318*18a2cb5fSmseidel pthread_mutex_unlock (&(pImpl->m_Lock));
319cdf0e10cSrcweir
320cdf0e10cSrcweir return ((oslThread)(pImpl));
321cdf0e10cSrcweir }
322cdf0e10cSrcweir
323cdf0e10cSrcweir /*****************************************************************************/
324cdf0e10cSrcweir /* osl_createThread */
325cdf0e10cSrcweir /*****************************************************************************/
osl_createThread(oslWorkerFunction pWorker,void * pThreadData)326cdf0e10cSrcweir oslThread osl_createThread (
327cdf0e10cSrcweir oslWorkerFunction pWorker,
328cdf0e10cSrcweir void * pThreadData)
329cdf0e10cSrcweir {
330*18a2cb5fSmseidel return osl_thread_create_Impl (
331cdf0e10cSrcweir pWorker,
332cdf0e10cSrcweir pThreadData,
333cdf0e10cSrcweir THREADIMPL_FLAGS_ATTACHED);
334cdf0e10cSrcweir }
335cdf0e10cSrcweir
336cdf0e10cSrcweir /*****************************************************************************/
337cdf0e10cSrcweir /* osl_createSuspendedThread */
338cdf0e10cSrcweir /*****************************************************************************/
osl_createSuspendedThread(oslWorkerFunction pWorker,void * pThreadData)339cdf0e10cSrcweir oslThread osl_createSuspendedThread (
340cdf0e10cSrcweir oslWorkerFunction pWorker,
341cdf0e10cSrcweir void * pThreadData)
342cdf0e10cSrcweir {
343*18a2cb5fSmseidel return osl_thread_create_Impl (
344cdf0e10cSrcweir pWorker,
345cdf0e10cSrcweir pThreadData,
346cdf0e10cSrcweir THREADIMPL_FLAGS_ATTACHED |
347cdf0e10cSrcweir THREADIMPL_FLAGS_SUSPENDED );
348cdf0e10cSrcweir }
349cdf0e10cSrcweir
350cdf0e10cSrcweir /*****************************************************************************/
351cdf0e10cSrcweir /* osl_destroyThread */
352cdf0e10cSrcweir /*****************************************************************************/
osl_destroyThread(oslThread Thread)353cdf0e10cSrcweir void SAL_CALL osl_destroyThread(oslThread Thread)
354cdf0e10cSrcweir {
355*18a2cb5fSmseidel if (Thread != NULL) {
356*18a2cb5fSmseidel Thread_Impl * impl = (Thread_Impl *) Thread;
357*18a2cb5fSmseidel int active;
358*18a2cb5fSmseidel pthread_mutex_lock(&impl->m_Lock);
359*18a2cb5fSmseidel active = (impl->m_Flags & THREADIMPL_FLAGS_ACTIVE) != 0;
360*18a2cb5fSmseidel impl->m_Flags |= THREADIMPL_FLAGS_DESTROYED;
361*18a2cb5fSmseidel pthread_mutex_unlock(&impl->m_Lock);
362*18a2cb5fSmseidel if (!active) {
363*18a2cb5fSmseidel osl_thread_destruct_Impl(&impl);
364*18a2cb5fSmseidel }
365*18a2cb5fSmseidel }
366cdf0e10cSrcweir }
367cdf0e10cSrcweir
368cdf0e10cSrcweir /*****************************************************************************/
369cdf0e10cSrcweir /* osl_resumeThread */
370cdf0e10cSrcweir /*****************************************************************************/
osl_resumeThread(oslThread Thread)371cdf0e10cSrcweir void SAL_CALL osl_resumeThread(oslThread Thread)
372cdf0e10cSrcweir {
373cdf0e10cSrcweir Thread_Impl* pImpl= (Thread_Impl*)Thread;
374cdf0e10cSrcweir
375cdf0e10cSrcweir OSL_ASSERT(pImpl);
376cdf0e10cSrcweir if (!pImpl)
377cdf0e10cSrcweir return; /* EINVAL */
378cdf0e10cSrcweir
379cdf0e10cSrcweir pthread_mutex_lock (&(pImpl->m_Lock));
380cdf0e10cSrcweir
381cdf0e10cSrcweir if (pImpl->m_Flags & THREADIMPL_FLAGS_SUSPENDED)
382*18a2cb5fSmseidel {
383cdf0e10cSrcweir /* clear SUSPENDED flag */
384cdf0e10cSrcweir pImpl->m_Flags &= ~THREADIMPL_FLAGS_SUSPENDED;
385cdf0e10cSrcweir pthread_cond_signal (&(pImpl->m_Cond));
386*18a2cb5fSmseidel }
387cdf0e10cSrcweir
388cdf0e10cSrcweir pthread_mutex_unlock (&(pImpl->m_Lock));
389cdf0e10cSrcweir }
390cdf0e10cSrcweir
391cdf0e10cSrcweir /*****************************************************************************/
392cdf0e10cSrcweir /* osl_suspendThread */
393cdf0e10cSrcweir /*****************************************************************************/
osl_suspendThread(oslThread Thread)394cdf0e10cSrcweir void SAL_CALL osl_suspendThread(oslThread Thread)
395cdf0e10cSrcweir {
396*18a2cb5fSmseidel Thread_Impl* pImpl= (Thread_Impl*)Thread;
397cdf0e10cSrcweir
398cdf0e10cSrcweir OSL_ASSERT(pImpl);
399cdf0e10cSrcweir if (!pImpl)
400cdf0e10cSrcweir return; /* EINVAL */
401cdf0e10cSrcweir
402cdf0e10cSrcweir pthread_mutex_lock (&(pImpl->m_Lock));
403cdf0e10cSrcweir
404cdf0e10cSrcweir pImpl->m_Flags |= THREADIMPL_FLAGS_SUSPENDED;
405cdf0e10cSrcweir
406cdf0e10cSrcweir if (pthread_equal (pthread_self(), pImpl->m_hThread))
407*18a2cb5fSmseidel {
408cdf0e10cSrcweir /* self suspend */
409*18a2cb5fSmseidel while (pImpl->m_Flags & THREADIMPL_FLAGS_SUSPENDED)
410*18a2cb5fSmseidel {
411*18a2cb5fSmseidel /* wait until SUSPENDED flag is cleared */
412cdf0e10cSrcweir pthread_cleanup_push (osl_thread_wait_cleanup_Impl, &(pImpl->m_Lock));
413cdf0e10cSrcweir pthread_cond_wait (&(pImpl->m_Cond), &(pImpl->m_Lock));
414cdf0e10cSrcweir pthread_cleanup_pop (0);
415*18a2cb5fSmseidel }
416*18a2cb5fSmseidel }
417cdf0e10cSrcweir
418cdf0e10cSrcweir pthread_mutex_unlock (&(pImpl->m_Lock));
419cdf0e10cSrcweir }
420cdf0e10cSrcweir
421cdf0e10cSrcweir /*****************************************************************************/
422cdf0e10cSrcweir /* osl_isThreadRunning */
423cdf0e10cSrcweir /*****************************************************************************/
osl_isThreadRunning(const oslThread Thread)424cdf0e10cSrcweir sal_Bool SAL_CALL osl_isThreadRunning(const oslThread Thread)
425cdf0e10cSrcweir {
426cdf0e10cSrcweir sal_Bool active;
427cdf0e10cSrcweir Thread_Impl* pImpl= (Thread_Impl*)Thread;
428cdf0e10cSrcweir
429cdf0e10cSrcweir if (!pImpl)
430cdf0e10cSrcweir return sal_False;
431cdf0e10cSrcweir
432cdf0e10cSrcweir pthread_mutex_lock (&(pImpl->m_Lock));
433cdf0e10cSrcweir active = ((pImpl->m_Flags & THREADIMPL_FLAGS_ACTIVE) > 0);
434cdf0e10cSrcweir pthread_mutex_unlock (&(pImpl->m_Lock));
435cdf0e10cSrcweir
436cdf0e10cSrcweir return (active);
437cdf0e10cSrcweir }
438cdf0e10cSrcweir
439cdf0e10cSrcweir /*****************************************************************************/
440cdf0e10cSrcweir /* osl_joinWithThread */
441cdf0e10cSrcweir /*****************************************************************************/
osl_joinWithThread(oslThread Thread)442cdf0e10cSrcweir void SAL_CALL osl_joinWithThread(oslThread Thread)
443cdf0e10cSrcweir {
444*18a2cb5fSmseidel pthread_t thread;
445cdf0e10cSrcweir int attached;
446cdf0e10cSrcweir Thread_Impl* pImpl= (Thread_Impl*)Thread;
447cdf0e10cSrcweir
448cdf0e10cSrcweir if (!pImpl)
449cdf0e10cSrcweir return;
450cdf0e10cSrcweir
451cdf0e10cSrcweir pthread_mutex_lock (&(pImpl->m_Lock));
452cdf0e10cSrcweir
453cdf0e10cSrcweir if (pthread_equal (pthread_self(), pImpl->m_hThread))
454cdf0e10cSrcweir {
455cdf0e10cSrcweir /* self join */
456cdf0e10cSrcweir pthread_mutex_unlock (&(pImpl->m_Lock));
457cdf0e10cSrcweir return; /* EDEADLK */
458cdf0e10cSrcweir }
459cdf0e10cSrcweir
460*18a2cb5fSmseidel thread = pImpl->m_hThread;
461cdf0e10cSrcweir attached = ((pImpl->m_Flags & THREADIMPL_FLAGS_ATTACHED) > 0);
462cdf0e10cSrcweir pImpl->m_Flags &= ~THREADIMPL_FLAGS_ATTACHED;
463cdf0e10cSrcweir
464cdf0e10cSrcweir pthread_mutex_unlock (&(pImpl->m_Lock));
465cdf0e10cSrcweir
466cdf0e10cSrcweir if (attached)
467cdf0e10cSrcweir {
468cdf0e10cSrcweir /* install cleanup handler to ensure consistent flags and state */
469cdf0e10cSrcweir pthread_cleanup_push (
470cdf0e10cSrcweir osl_thread_join_cleanup_Impl, (void*)thread);
471cdf0e10cSrcweir
472cdf0e10cSrcweir /* join */
473cdf0e10cSrcweir pthread_join (thread, NULL);
474cdf0e10cSrcweir
475cdf0e10cSrcweir /* remove cleanup handler */
476cdf0e10cSrcweir pthread_cleanup_pop (0);
477cdf0e10cSrcweir }
478cdf0e10cSrcweir }
479cdf0e10cSrcweir
480cdf0e10cSrcweir /*****************************************************************************/
481cdf0e10cSrcweir /* osl_terminateThread */
482cdf0e10cSrcweir /*****************************************************************************/
osl_terminateThread(oslThread Thread)483cdf0e10cSrcweir void SAL_CALL osl_terminateThread(oslThread Thread)
484cdf0e10cSrcweir {
485cdf0e10cSrcweir Thread_Impl* pImpl= (Thread_Impl*)Thread;
486cdf0e10cSrcweir
487cdf0e10cSrcweir OSL_ASSERT(pImpl);
488cdf0e10cSrcweir if (!pImpl)
489cdf0e10cSrcweir return; /* EINVAL */
490cdf0e10cSrcweir
491cdf0e10cSrcweir pthread_mutex_lock (&(pImpl->m_Lock));
492cdf0e10cSrcweir
493cdf0e10cSrcweir if (pImpl->m_Flags & THREADIMPL_FLAGS_SUSPENDED)
494*18a2cb5fSmseidel {
495cdf0e10cSrcweir /* clear SUSPENDED flag */
496cdf0e10cSrcweir pImpl->m_Flags &= ~THREADIMPL_FLAGS_SUSPENDED;
497cdf0e10cSrcweir pthread_cond_signal (&(pImpl->m_Cond));
498*18a2cb5fSmseidel }
499cdf0e10cSrcweir
500cdf0e10cSrcweir pImpl->m_Flags |= THREADIMPL_FLAGS_TERMINATE;
501cdf0e10cSrcweir
502cdf0e10cSrcweir pthread_mutex_unlock (&(pImpl->m_Lock));
503cdf0e10cSrcweir }
504cdf0e10cSrcweir
505cdf0e10cSrcweir /*****************************************************************************/
506cdf0e10cSrcweir /* osl_scheduleThread */
507cdf0e10cSrcweir /*****************************************************************************/
osl_scheduleThread(oslThread Thread)508cdf0e10cSrcweir sal_Bool SAL_CALL osl_scheduleThread(oslThread Thread)
509cdf0e10cSrcweir {
510cdf0e10cSrcweir int terminate;
511cdf0e10cSrcweir Thread_Impl* pImpl= (Thread_Impl*)Thread;
512cdf0e10cSrcweir
513cdf0e10cSrcweir OSL_ASSERT(pImpl);
514cdf0e10cSrcweir if (!pImpl)
515cdf0e10cSrcweir return sal_False; /* EINVAL */
516cdf0e10cSrcweir
517cdf0e10cSrcweir OSL_ASSERT(pthread_equal (pthread_self(), pImpl->m_hThread));
518cdf0e10cSrcweir if (!(pthread_equal (pthread_self(), pImpl->m_hThread)))
519cdf0e10cSrcweir return sal_False; /* EINVAL */
520cdf0e10cSrcweir
521cdf0e10cSrcweir pthread_testcancel();
522cdf0e10cSrcweir pthread_mutex_lock (&(pImpl->m_Lock));
523cdf0e10cSrcweir
524cdf0e10cSrcweir while (pImpl->m_Flags & THREADIMPL_FLAGS_SUSPENDED)
525*18a2cb5fSmseidel {
526cdf0e10cSrcweir /* wait until SUSPENDED flag is cleared */
527cdf0e10cSrcweir pthread_cleanup_push (osl_thread_wait_cleanup_Impl, &(pImpl->m_Lock));
528cdf0e10cSrcweir pthread_cond_wait (&(pImpl->m_Cond), &(pImpl->m_Lock));
529cdf0e10cSrcweir pthread_cleanup_pop (0);
530*18a2cb5fSmseidel }
531cdf0e10cSrcweir
532cdf0e10cSrcweir terminate = ((pImpl->m_Flags & THREADIMPL_FLAGS_TERMINATE) > 0);
533cdf0e10cSrcweir
534cdf0e10cSrcweir pthread_mutex_unlock(&(pImpl->m_Lock));
535cdf0e10cSrcweir pthread_testcancel();
536cdf0e10cSrcweir
537cdf0e10cSrcweir return (terminate == 0);
538cdf0e10cSrcweir }
539cdf0e10cSrcweir
540cdf0e10cSrcweir /*****************************************************************************/
541cdf0e10cSrcweir /* osl_waitThread */
542cdf0e10cSrcweir /*****************************************************************************/
osl_waitThread(const TimeValue * pDelay)543cdf0e10cSrcweir void SAL_CALL osl_waitThread(const TimeValue* pDelay)
544cdf0e10cSrcweir {
545cdf0e10cSrcweir if (pDelay)
546cdf0e10cSrcweir {
547cdf0e10cSrcweir struct timespec delay;
548cdf0e10cSrcweir
549cdf0e10cSrcweir SET_TIMESPEC(delay, pDelay->Seconds, pDelay->Nanosec);
550cdf0e10cSrcweir
551cdf0e10cSrcweir SLEEP_TIMESPEC(delay);
552cdf0e10cSrcweir }
553cdf0e10cSrcweir }
554cdf0e10cSrcweir
555cdf0e10cSrcweir /*****************************************************************************/
556cdf0e10cSrcweir /* osl_yieldThread */
557cdf0e10cSrcweir /*
558cdf0e10cSrcweir Note that POSIX scheduling _really_ requires threads to call this
559cdf0e10cSrcweir functions, since a thread only reschedules to other thread, when
560*18a2cb5fSmseidel it blocks (sleep, blocking I/O) OR calls sched_yield().
561cdf0e10cSrcweir */
562cdf0e10cSrcweir /*****************************************************************************/
osl_yieldThread()563cdf0e10cSrcweir void SAL_CALL osl_yieldThread()
564cdf0e10cSrcweir {
565*18a2cb5fSmseidel sched_yield();
566cdf0e10cSrcweir }
567cdf0e10cSrcweir
osl_setThreadName(char const * name)568cdf0e10cSrcweir void SAL_CALL osl_setThreadName(char const * name) {
569cdf0e10cSrcweir #if defined LINUX
570*18a2cb5fSmseidel if (prctl(PR_SET_NAME, (unsigned long) name, 0, 0, 0) != 0) {
571*18a2cb5fSmseidel OSL_TRACE(
572*18a2cb5fSmseidel "%s prctl(PR_SET_NAME) failed with errno %d", OSL_LOG_PREFIX,
573*18a2cb5fSmseidel errno);
574*18a2cb5fSmseidel }
575cdf0e10cSrcweir #else
576*18a2cb5fSmseidel (void) name;
577cdf0e10cSrcweir #endif
578cdf0e10cSrcweir }
579cdf0e10cSrcweir
580cdf0e10cSrcweir /*****************************************************************************/
581cdf0e10cSrcweir /* osl_getThreadIdentifier @@@ see TODO @@@ */
582cdf0e10cSrcweir /*****************************************************************************/
583cdf0e10cSrcweir
584cdf0e10cSrcweir #define HASHID(x) ((unsigned int)PTHREAD_VALUE(x) % HashSize)
585cdf0e10cSrcweir
586cdf0e10cSrcweir typedef struct _HashEntry
587cdf0e10cSrcweir {
588cdf0e10cSrcweir pthread_t Handle;
589cdf0e10cSrcweir sal_uInt16 Ident;
590cdf0e10cSrcweir struct _HashEntry *Next;
591cdf0e10cSrcweir } HashEntry;
592cdf0e10cSrcweir
593cdf0e10cSrcweir static HashEntry* HashTable[31];
594cdf0e10cSrcweir static int HashSize = sizeof(HashTable) / sizeof(HashTable[0]);
595cdf0e10cSrcweir
596cdf0e10cSrcweir static pthread_mutex_t HashLock = PTHREAD_MUTEX_INITIALIZER;
597cdf0e10cSrcweir
598cdf0e10cSrcweir static sal_uInt16 LastIdent = 0;
599cdf0e10cSrcweir
lookupThreadId(pthread_t hThread)600cdf0e10cSrcweir static sal_uInt16 lookupThreadId (pthread_t hThread)
601cdf0e10cSrcweir {
602cdf0e10cSrcweir HashEntry *pEntry;
603cdf0e10cSrcweir
604cdf0e10cSrcweir pthread_mutex_lock(&HashLock);
605cdf0e10cSrcweir
606cdf0e10cSrcweir pEntry = HashTable[HASHID(hThread)];
607cdf0e10cSrcweir while (pEntry != NULL)
608cdf0e10cSrcweir {
609cdf0e10cSrcweir if (pthread_equal(pEntry->Handle, hThread))
610cdf0e10cSrcweir {
611cdf0e10cSrcweir pthread_mutex_unlock(&HashLock);
612cdf0e10cSrcweir return (pEntry->Ident);
613cdf0e10cSrcweir }
614cdf0e10cSrcweir pEntry = pEntry->Next;
615cdf0e10cSrcweir }
616cdf0e10cSrcweir
617cdf0e10cSrcweir pthread_mutex_unlock(&HashLock);
618cdf0e10cSrcweir
619cdf0e10cSrcweir return (0);
620cdf0e10cSrcweir }
621cdf0e10cSrcweir
insertThreadId(pthread_t hThread)622cdf0e10cSrcweir static sal_uInt16 insertThreadId (pthread_t hThread)
623cdf0e10cSrcweir {
624cdf0e10cSrcweir HashEntry *pEntry, *pInsert = NULL;
625cdf0e10cSrcweir
626cdf0e10cSrcweir pthread_mutex_lock(&HashLock);
627cdf0e10cSrcweir
628cdf0e10cSrcweir pEntry = HashTable[HASHID(hThread)];
629cdf0e10cSrcweir
630cdf0e10cSrcweir while (pEntry != NULL)
631cdf0e10cSrcweir {
632cdf0e10cSrcweir if (pthread_equal(pEntry->Handle, hThread))
633cdf0e10cSrcweir break;
634cdf0e10cSrcweir
635cdf0e10cSrcweir pInsert = pEntry;
636cdf0e10cSrcweir pEntry = pEntry->Next;
637cdf0e10cSrcweir }
638cdf0e10cSrcweir
639cdf0e10cSrcweir if (pEntry == NULL)
640cdf0e10cSrcweir {
641cdf0e10cSrcweir pEntry = (HashEntry*) calloc(sizeof(HashEntry), 1);
642cdf0e10cSrcweir
643cdf0e10cSrcweir pEntry->Handle = hThread;
644cdf0e10cSrcweir
645cdf0e10cSrcweir ++ LastIdent;
646cdf0e10cSrcweir
647*18a2cb5fSmseidel if ( LastIdent == 0 )
648*18a2cb5fSmseidel LastIdent = 1;
649cdf0e10cSrcweir
650*18a2cb5fSmseidel pEntry->Ident = LastIdent;
651cdf0e10cSrcweir
652cdf0e10cSrcweir if (pInsert)
653cdf0e10cSrcweir pInsert->Next = pEntry;
654cdf0e10cSrcweir else
655cdf0e10cSrcweir HashTable[HASHID(hThread)] = pEntry;
656cdf0e10cSrcweir }
657cdf0e10cSrcweir
658cdf0e10cSrcweir pthread_mutex_unlock(&HashLock);
659cdf0e10cSrcweir
660cdf0e10cSrcweir return (pEntry->Ident);
661cdf0e10cSrcweir }
662cdf0e10cSrcweir
removeThreadId(pthread_t hThread)663cdf0e10cSrcweir static void removeThreadId (pthread_t hThread)
664cdf0e10cSrcweir {
665cdf0e10cSrcweir HashEntry *pEntry, *pRemove = NULL;
666cdf0e10cSrcweir
667cdf0e10cSrcweir pthread_mutex_lock(&HashLock);
668cdf0e10cSrcweir
669cdf0e10cSrcweir pEntry = HashTable[HASHID(hThread)];
670cdf0e10cSrcweir while (pEntry != NULL)
671cdf0e10cSrcweir {
672cdf0e10cSrcweir if (pthread_equal(pEntry->Handle, hThread))
673cdf0e10cSrcweir break;
674cdf0e10cSrcweir
675cdf0e10cSrcweir pRemove = pEntry;
676cdf0e10cSrcweir pEntry = pEntry->Next;
677cdf0e10cSrcweir }
678cdf0e10cSrcweir
679cdf0e10cSrcweir if (pEntry != NULL)
680cdf0e10cSrcweir {
681cdf0e10cSrcweir if (pRemove)
682cdf0e10cSrcweir pRemove->Next = pEntry->Next;
683cdf0e10cSrcweir else
684cdf0e10cSrcweir HashTable[HASHID(hThread)] = pEntry->Next;
685cdf0e10cSrcweir
686cdf0e10cSrcweir free(pEntry);
687cdf0e10cSrcweir }
688cdf0e10cSrcweir
689cdf0e10cSrcweir pthread_mutex_unlock(&HashLock);
690cdf0e10cSrcweir }
691cdf0e10cSrcweir
osl_getThreadIdentifier(oslThread Thread)692cdf0e10cSrcweir oslThreadIdentifier SAL_CALL osl_getThreadIdentifier(oslThread Thread)
693cdf0e10cSrcweir {
694cdf0e10cSrcweir Thread_Impl* pImpl= (Thread_Impl*)Thread;
695cdf0e10cSrcweir sal_uInt16 Ident;
696cdf0e10cSrcweir
697cdf0e10cSrcweir if (pImpl)
698cdf0e10cSrcweir Ident = pImpl->m_Ident;
699cdf0e10cSrcweir else
700cdf0e10cSrcweir {
701cdf0e10cSrcweir /* current thread */
702cdf0e10cSrcweir pthread_t current = pthread_self();
703cdf0e10cSrcweir
704cdf0e10cSrcweir Ident = lookupThreadId (current);
705cdf0e10cSrcweir if (Ident == 0)
706cdf0e10cSrcweir /* @@@ see TODO: alien pthread_self() @@@ */
707cdf0e10cSrcweir Ident = insertThreadId (current);
708cdf0e10cSrcweir }
709cdf0e10cSrcweir
710cdf0e10cSrcweir return ((oslThreadIdentifier)(Ident));
711cdf0e10cSrcweir }
712cdf0e10cSrcweir
713cdf0e10cSrcweir /*****************************************************************************
714*18a2cb5fSmseidel @@@ see TODO @@@
715cdf0e10cSrcweir osl_thread_priority_init_Impl
716cdf0e10cSrcweir
717cdf0e10cSrcweir set the base-priority of the main-thread to
718cdf0e10cSrcweir oslThreadPriorityNormal (64) since 0 (lowest) is
719cdf0e10cSrcweir the system default. This behaviour collides with
720cdf0e10cSrcweir our enum-priority definition (highest..normal..lowest).
721*18a2cb5fSmseidel A normal user will expect the main-thread of an app.
722cdf0e10cSrcweir to have the "normal" priority.
723cdf0e10cSrcweir
724cdf0e10cSrcweir *****************************************************************************/
osl_thread_priority_init_Impl(void)725cdf0e10cSrcweir static void osl_thread_priority_init_Impl (void)
726cdf0e10cSrcweir {
727cdf0e10cSrcweir #ifndef NO_PTHREAD_PRIORITY
728*18a2cb5fSmseidel struct sched_param param;
729*18a2cb5fSmseidel int policy=0;
730*18a2cb5fSmseidel int nRet=0;
731cdf0e10cSrcweir
732cdf0e10cSrcweir /* @@@ see TODO: calling thread may not be main thread @@@ */
733cdf0e10cSrcweir
734*18a2cb5fSmseidel if ((nRet = pthread_getschedparam(pthread_self(), &policy, ¶m)) != 0)
735*18a2cb5fSmseidel {
736*18a2cb5fSmseidel OSL_TRACE("failed to get priority of thread [%s]\n",strerror(nRet));
737*18a2cb5fSmseidel return;
738*18a2cb5fSmseidel }
739cdf0e10cSrcweir
740cdf0e10cSrcweir #if defined (SOLARIS)
741*18a2cb5fSmseidel if ( policy >= _SCHED_NEXT)
742*18a2cb5fSmseidel {
743*18a2cb5fSmseidel /* mfe: pthread_getschedparam on Solaris has a possible Bug */
744*18a2cb5fSmseidel /* one gets 959917873 as the policy */
745*18a2cb5fSmseidel /* so set the policy to a default one */
746*18a2cb5fSmseidel policy=SCHED_OTHER;
747*18a2cb5fSmseidel }
748cdf0e10cSrcweir #endif /* SOLARIS */
749cdf0e10cSrcweir
750*18a2cb5fSmseidel if ((nRet = sched_get_priority_min(policy) ) != -1)
751*18a2cb5fSmseidel {
752*18a2cb5fSmseidel OSL_TRACE("Min Prioriy for policy '%i' == '%i'\n",policy,nRet);
753*18a2cb5fSmseidel g_thread.m_priority.m_Lowest=nRet;
754*18a2cb5fSmseidel }
755cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
756*18a2cb5fSmseidel else
757*18a2cb5fSmseidel {
758*18a2cb5fSmseidel fprintf(stderr,"failed to get min sched param [%s]\n",strerror(errno));
759*18a2cb5fSmseidel }
760cdf0e10cSrcweir #endif /* OSL_DEBUG_LEVEL */
761cdf0e10cSrcweir
762*18a2cb5fSmseidel if ((nRet = sched_get_priority_max(policy) ) != -1)
763*18a2cb5fSmseidel {
764*18a2cb5fSmseidel OSL_TRACE("Max Prioriy for policy '%i' == '%i'\n",policy,nRet);
765*18a2cb5fSmseidel g_thread.m_priority.m_Highest=nRet;
766*18a2cb5fSmseidel }
767cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
768*18a2cb5fSmseidel else
769*18a2cb5fSmseidel {
770*18a2cb5fSmseidel fprintf(stderr,"failed to get max sched param [%s]\n",strerror(errno));
771*18a2cb5fSmseidel }
772cdf0e10cSrcweir #endif /* OSL_DEBUG_LEVEL */
773cdf0e10cSrcweir
774*18a2cb5fSmseidel g_thread.m_priority.m_Normal =
775cdf0e10cSrcweir (g_thread.m_priority.m_Lowest + g_thread.m_priority.m_Highest) / 2;
776*18a2cb5fSmseidel g_thread.m_priority.m_Below_Normal =
777*18a2cb5fSmseidel (g_thread.m_priority.m_Lowest + g_thread.m_priority.m_Normal) / 2;
778*18a2cb5fSmseidel g_thread.m_priority.m_Above_Normal =
779cdf0e10cSrcweir (g_thread.m_priority.m_Normal + g_thread.m_priority.m_Highest) / 2;
780cdf0e10cSrcweir
781cdf0e10cSrcweir /* @@@ set prio of calling (not main) thread (?) @@@ */
782cdf0e10cSrcweir
783*18a2cb5fSmseidel param.sched_priority= g_thread.m_priority.m_Normal;
784cdf0e10cSrcweir
785*18a2cb5fSmseidel if ((nRet = pthread_setschedparam(pthread_self(), policy, ¶m)) != 0)
786*18a2cb5fSmseidel {
787*18a2cb5fSmseidel OSL_TRACE("failed to change base priority of thread [%s]\n",strerror(nRet));
788*18a2cb5fSmseidel OSL_TRACE("Thread ID '%i', Policy '%i', Priority '%i'\n",pthread_self(),policy,param.sched_priority);
789*18a2cb5fSmseidel }
790cdf0e10cSrcweir
791cdf0e10cSrcweir #endif /* NO_PTHREAD_PRIORITY */
792cdf0e10cSrcweir }
793cdf0e10cSrcweir
794cdf0e10cSrcweir /*****************************************************************************/
795cdf0e10cSrcweir /* osl_setThreadPriority */
796cdf0e10cSrcweir /*
797cdf0e10cSrcweir Impl-Notes: contrary to solaris-docu, which claims
798cdf0e10cSrcweir valid priority-levels from 0 .. INT_MAX, only the
799cdf0e10cSrcweir range 0..127 is accepted. (0 lowest, 127 highest)
800cdf0e10cSrcweir */
801cdf0e10cSrcweir /*****************************************************************************/
osl_setThreadPriority(oslThread Thread,oslThreadPriority Priority)802cdf0e10cSrcweir void SAL_CALL osl_setThreadPriority (
803cdf0e10cSrcweir oslThread Thread,
804cdf0e10cSrcweir oslThreadPriority Priority)
805cdf0e10cSrcweir {
806cdf0e10cSrcweir #ifndef NO_PTHREAD_PRIORITY
807cdf0e10cSrcweir
808cdf0e10cSrcweir struct sched_param Param;
809cdf0e10cSrcweir int policy;
810*18a2cb5fSmseidel int nRet;
811cdf0e10cSrcweir
812cdf0e10cSrcweir #endif /* NO_PTHREAD_PRIORITY */
813cdf0e10cSrcweir
814cdf0e10cSrcweir Thread_Impl* pImpl= (Thread_Impl*)Thread;
815cdf0e10cSrcweir
816cdf0e10cSrcweir OSL_ASSERT(pImpl);
817cdf0e10cSrcweir if (!pImpl)
818cdf0e10cSrcweir return; /* EINVAL */
819cdf0e10cSrcweir
820cdf0e10cSrcweir #ifdef NO_PTHREAD_PRIORITY
821*18a2cb5fSmseidel (void) Priority; /* unused */
822cdf0e10cSrcweir #else /* NO_PTHREAD_PRIORITY */
823cdf0e10cSrcweir
824*18a2cb5fSmseidel if (pthread_getschedparam(pImpl->m_hThread, &policy, &Param) != 0)
825cdf0e10cSrcweir return; /* ESRCH */
826cdf0e10cSrcweir
827cdf0e10cSrcweir #if defined (SOLARIS)
828*18a2cb5fSmseidel if ( policy >= _SCHED_NEXT)
829*18a2cb5fSmseidel {
830*18a2cb5fSmseidel /* mfe: pthread_getschedparam on Solaris has a possible Bug */
831*18a2cb5fSmseidel /* one gets 959917873 as the policy */
832*18a2cb5fSmseidel /* so set the policy to a default one */
833*18a2cb5fSmseidel policy=SCHED_OTHER;
834*18a2cb5fSmseidel }
835cdf0e10cSrcweir #endif /* SOLARIS */
836cdf0e10cSrcweir
837cdf0e10cSrcweir pthread_once (&(g_thread.m_once), osl_thread_init_Impl);
838cdf0e10cSrcweir
839*18a2cb5fSmseidel switch(Priority)
840*18a2cb5fSmseidel {
841*18a2cb5fSmseidel case osl_Thread_PriorityHighest:
842*18a2cb5fSmseidel Param.sched_priority= g_thread.m_priority.m_Highest;
843*18a2cb5fSmseidel break;
844cdf0e10cSrcweir
845*18a2cb5fSmseidel case osl_Thread_PriorityAboveNormal:
846*18a2cb5fSmseidel Param.sched_priority= g_thread.m_priority.m_Above_Normal;
847*18a2cb5fSmseidel break;
848cdf0e10cSrcweir
849*18a2cb5fSmseidel case osl_Thread_PriorityNormal:
850*18a2cb5fSmseidel Param.sched_priority= g_thread.m_priority.m_Normal;
851*18a2cb5fSmseidel break;
852cdf0e10cSrcweir
853*18a2cb5fSmseidel case osl_Thread_PriorityBelowNormal:
854*18a2cb5fSmseidel Param.sched_priority= g_thread.m_priority.m_Below_Normal;
855*18a2cb5fSmseidel break;
856cdf0e10cSrcweir
857*18a2cb5fSmseidel case osl_Thread_PriorityLowest:
858*18a2cb5fSmseidel Param.sched_priority= g_thread.m_priority.m_Lowest;
859*18a2cb5fSmseidel break;
860cdf0e10cSrcweir
861*18a2cb5fSmseidel case osl_Thread_PriorityUnknown:
862*18a2cb5fSmseidel OSL_ASSERT(sal_False); /* only fools try this...*/
863cdf0e10cSrcweir
864*18a2cb5fSmseidel /* let release-version behave friendly */
865*18a2cb5fSmseidel return;
866cdf0e10cSrcweir
867*18a2cb5fSmseidel default:
868*18a2cb5fSmseidel /* enum expanded, but forgotten here...*/
869*18a2cb5fSmseidel OSL_ENSURE(sal_False,"osl_setThreadPriority : unknown priority\n");
870cdf0e10cSrcweir
871*18a2cb5fSmseidel /* let release-version behave friendly */
872*18a2cb5fSmseidel return;
873*18a2cb5fSmseidel }
874cdf0e10cSrcweir
875*18a2cb5fSmseidel if ((nRet = pthread_setschedparam(pImpl->m_hThread, policy, &Param)) != 0)
876*18a2cb5fSmseidel {
877*18a2cb5fSmseidel OSL_TRACE("failed to change thread priority [%s]\n",strerror(nRet));
878*18a2cb5fSmseidel }
879cdf0e10cSrcweir
880cdf0e10cSrcweir #endif /* NO_PTHREAD_PRIORITY */
881cdf0e10cSrcweir }
882cdf0e10cSrcweir
883cdf0e10cSrcweir /*****************************************************************************/
884cdf0e10cSrcweir /* osl_getThreadPriority */
885cdf0e10cSrcweir /*****************************************************************************/
osl_getThreadPriority(const oslThread Thread)886cdf0e10cSrcweir oslThreadPriority SAL_CALL osl_getThreadPriority(const oslThread Thread)
887cdf0e10cSrcweir {
888cdf0e10cSrcweir #ifndef NO_PTHREAD_PRIORITY
889cdf0e10cSrcweir
890cdf0e10cSrcweir struct sched_param Param;
891cdf0e10cSrcweir int Policy;
892cdf0e10cSrcweir
893cdf0e10cSrcweir #endif /* NO_PTHREAD_PRIORITY */
894cdf0e10cSrcweir
895cdf0e10cSrcweir oslThreadPriority Priority = osl_Thread_PriorityNormal;
896cdf0e10cSrcweir Thread_Impl* pImpl= (Thread_Impl*)Thread;
897cdf0e10cSrcweir
898cdf0e10cSrcweir OSL_ASSERT(pImpl);
899cdf0e10cSrcweir if (!pImpl)
900cdf0e10cSrcweir return osl_Thread_PriorityUnknown; /* EINVAL */
901cdf0e10cSrcweir
902cdf0e10cSrcweir #ifndef NO_PTHREAD_PRIORITY
903cdf0e10cSrcweir
904cdf0e10cSrcweir if (pthread_getschedparam(pImpl->m_hThread, &Policy, &Param) != 0)
905cdf0e10cSrcweir return osl_Thread_PriorityUnknown; /* ESRCH */
906cdf0e10cSrcweir
907cdf0e10cSrcweir pthread_once (&(g_thread.m_once), osl_thread_init_Impl);
908cdf0e10cSrcweir
909cdf0e10cSrcweir /* map pthread priority to enum */
910cdf0e10cSrcweir if (Param.sched_priority==g_thread.m_priority.m_Highest)
911cdf0e10cSrcweir {
912cdf0e10cSrcweir /* 127 - highest */
913cdf0e10cSrcweir Priority= osl_Thread_PriorityHighest;
914cdf0e10cSrcweir }
915cdf0e10cSrcweir else if (Param.sched_priority > g_thread.m_priority.m_Normal)
916cdf0e10cSrcweir {
917cdf0e10cSrcweir /* 65..126 - above normal */
918cdf0e10cSrcweir Priority= osl_Thread_PriorityAboveNormal;
919cdf0e10cSrcweir }
920cdf0e10cSrcweir else if (Param.sched_priority == g_thread.m_priority.m_Normal)
921cdf0e10cSrcweir {
922cdf0e10cSrcweir /* normal */
923cdf0e10cSrcweir Priority= osl_Thread_PriorityNormal;
924cdf0e10cSrcweir }
925cdf0e10cSrcweir else if (Param.sched_priority > g_thread.m_priority.m_Lowest)
926cdf0e10cSrcweir {
927cdf0e10cSrcweir /* 63..1 -below normal */
928cdf0e10cSrcweir Priority= osl_Thread_PriorityBelowNormal;
929cdf0e10cSrcweir }
930cdf0e10cSrcweir else if (Param.sched_priority == g_thread.m_priority.m_Lowest)
931cdf0e10cSrcweir {
932cdf0e10cSrcweir /* 0 - lowest */
933cdf0e10cSrcweir Priority= osl_Thread_PriorityLowest;
934cdf0e10cSrcweir }
935cdf0e10cSrcweir else
936cdf0e10cSrcweir {
937cdf0e10cSrcweir /* unknown */
938cdf0e10cSrcweir Priority= osl_Thread_PriorityUnknown;
939cdf0e10cSrcweir }
940cdf0e10cSrcweir
941cdf0e10cSrcweir #endif /* NO_PTHREAD_PRIORITY */
942cdf0e10cSrcweir
943cdf0e10cSrcweir return Priority;
944cdf0e10cSrcweir }
945cdf0e10cSrcweir
946cdf0e10cSrcweir /*****************************************************************************/
947cdf0e10cSrcweir /* osl_createThreadKey */
948cdf0e10cSrcweir /*****************************************************************************/
osl_createThreadKey(oslThreadKeyCallbackFunction pCallback)949cdf0e10cSrcweir oslThreadKey SAL_CALL osl_createThreadKey( oslThreadKeyCallbackFunction pCallback )
950cdf0e10cSrcweir {
951cdf0e10cSrcweir pthread_key_t key;
952cdf0e10cSrcweir
953cdf0e10cSrcweir if (pthread_key_create(&key, pCallback) != 0)
954cdf0e10cSrcweir key = 0;
955cdf0e10cSrcweir
956cdf0e10cSrcweir return ((oslThreadKey)key);
957cdf0e10cSrcweir }
958cdf0e10cSrcweir
959cdf0e10cSrcweir /*****************************************************************************/
960cdf0e10cSrcweir /* osl_destroyThreadKey */
961cdf0e10cSrcweir /*****************************************************************************/
osl_destroyThreadKey(oslThreadKey Key)962cdf0e10cSrcweir void SAL_CALL osl_destroyThreadKey(oslThreadKey Key)
963cdf0e10cSrcweir {
964cdf0e10cSrcweir pthread_key_delete((pthread_key_t)Key);
965cdf0e10cSrcweir }
966cdf0e10cSrcweir
967cdf0e10cSrcweir /*****************************************************************************/
968cdf0e10cSrcweir /* osl_getThreadKeyData */
969cdf0e10cSrcweir /*****************************************************************************/
osl_getThreadKeyData(oslThreadKey Key)970cdf0e10cSrcweir void* SAL_CALL osl_getThreadKeyData(oslThreadKey Key)
971cdf0e10cSrcweir {
972cdf0e10cSrcweir return (pthread_getspecific((pthread_key_t)Key));
973cdf0e10cSrcweir }
974cdf0e10cSrcweir
975cdf0e10cSrcweir /*****************************************************************************/
976cdf0e10cSrcweir /* osl_setThreadKeyData */
977cdf0e10cSrcweir /*****************************************************************************/
osl_setThreadKeyData(oslThreadKey Key,void * pData)978cdf0e10cSrcweir sal_Bool SAL_CALL osl_setThreadKeyData(oslThreadKey Key, void *pData)
979cdf0e10cSrcweir {
980cdf0e10cSrcweir return (pthread_setspecific((pthread_key_t)Key, pData) == 0);
981cdf0e10cSrcweir }
982cdf0e10cSrcweir
983cdf0e10cSrcweir /*****************************************************************************/
984cdf0e10cSrcweir /* Thread Local Text Encoding */
985cdf0e10cSrcweir /*****************************************************************************/
osl_thread_textencoding_init_Impl(void)986cdf0e10cSrcweir static void osl_thread_textencoding_init_Impl (void)
987cdf0e10cSrcweir {
988cdf0e10cSrcweir rtl_TextEncoding defaultEncoding;
989cdf0e10cSrcweir const char * pszEncoding;
990cdf0e10cSrcweir
991cdf0e10cSrcweir /* create thread specific data key */
992cdf0e10cSrcweir pthread_key_create (&(g_thread.m_textencoding.m_key), NULL);
993cdf0e10cSrcweir
994cdf0e10cSrcweir /* determine default text encoding */
995cdf0e10cSrcweir pszEncoding = getenv ("SOLAR_USER_RTL_TEXTENCODING");
996cdf0e10cSrcweir if (pszEncoding)
997cdf0e10cSrcweir defaultEncoding = atoi(pszEncoding);
998cdf0e10cSrcweir else
999cdf0e10cSrcweir defaultEncoding = osl_getTextEncodingFromLocale(NULL);
1000cdf0e10cSrcweir
1001cdf0e10cSrcweir OSL_ASSERT(defaultEncoding != RTL_TEXTENCODING_DONTKNOW);
1002cdf0e10cSrcweir
1003cdf0e10cSrcweir /*
1004cdf0e10cSrcweir Tools string functions call abort() on an unknown encoding so ASCII
1005940681c7SMatthias Seidel is a meaningful fallback regardless whether the assertion makes sense.
1006cdf0e10cSrcweir */
1007cdf0e10cSrcweir
1008cdf0e10cSrcweir if ( RTL_TEXTENCODING_DONTKNOW == defaultEncoding )
1009cdf0e10cSrcweir defaultEncoding = RTL_TEXTENCODING_ASCII_US;
1010cdf0e10cSrcweir
1011cdf0e10cSrcweir g_thread.m_textencoding.m_default = defaultEncoding;
1012cdf0e10cSrcweir }
1013cdf0e10cSrcweir
1014cdf0e10cSrcweir /*****************************************************************************/
1015cdf0e10cSrcweir /* osl_getThreadTextEncoding */
1016cdf0e10cSrcweir /*****************************************************************************/
osl_getThreadTextEncoding()1017cdf0e10cSrcweir rtl_TextEncoding SAL_CALL osl_getThreadTextEncoding()
1018cdf0e10cSrcweir {
1019*18a2cb5fSmseidel rtl_TextEncoding threadEncoding;
1020cdf0e10cSrcweir
1021cdf0e10cSrcweir pthread_once (&(g_thread.m_once), osl_thread_init_Impl);
1022cdf0e10cSrcweir
1023*18a2cb5fSmseidel /* check for thread specific encoding, use default if not set */
1024cdf0e10cSrcweir threadEncoding = SAL_INT_CAST(
1025*18a2cb5fSmseidel rtl_TextEncoding,
1026*18a2cb5fSmseidel (sal_uIntPtr) pthread_getspecific(g_thread.m_textencoding.m_key));
1027cdf0e10cSrcweir if (0 == threadEncoding)
1028cdf0e10cSrcweir threadEncoding = g_thread.m_textencoding.m_default;
1029cdf0e10cSrcweir
1030*18a2cb5fSmseidel return threadEncoding;
1031cdf0e10cSrcweir }
1032cdf0e10cSrcweir
1033cdf0e10cSrcweir /*****************************************************************************/
1034cdf0e10cSrcweir /* osl_setThreadTextEncoding */
1035cdf0e10cSrcweir /*****************************************************************************/
osl_setThreadTextEncoding(rtl_TextEncoding Encoding)1036cdf0e10cSrcweir rtl_TextEncoding osl_setThreadTextEncoding(rtl_TextEncoding Encoding)
1037cdf0e10cSrcweir {
1038*18a2cb5fSmseidel rtl_TextEncoding oldThreadEncoding = osl_getThreadTextEncoding();
1039cdf0e10cSrcweir
1040*18a2cb5fSmseidel /* save encoding in thread local storage */
1041*18a2cb5fSmseidel pthread_setspecific (
1042*18a2cb5fSmseidel g_thread.m_textencoding.m_key,
1043*18a2cb5fSmseidel (void*) SAL_INT_CAST(sal_uIntPtr, Encoding));
1044cdf0e10cSrcweir
1045*18a2cb5fSmseidel return oldThreadEncoding;
1046cdf0e10cSrcweir }
1047