1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
34 #include <osl/diagnose.h>
35 #include <osl/thread.h>
36 #include <osl/nlsupport.h>
37 #include <rtl/textenc.h>
38 #include <rtl/alloc.h>
39 #include <sal/macros.h>
42 #include <osl/detail/android-bootstrap.h>
45 #if defined LINUX && ! defined __FreeBSD_kernel__
46 #include <sys/prctl.h>
48 #define PR_SET_NAME 15
52 /****************************************************************************
55 * (1) 'osl_thread_priority_init_Impl()'
56 * - insane assumption that initializing caller is main thread
57 * - use _POSIX_THREAD_PRIORITY_SCHEDULING, not NO_PTHREAD_PRIORITY (?)
58 * - POSIX doesn't require defined prio's for SCHED_OTHER (!)
59 * - use SCHED_RR instead of SCHED_OTHER for defined behaviour (?)
60 * (2) 'oslThreadIdentifier' and '{insert|remove|lookup}ThreadId()'
61 * - cannot reliably be applied to 'alien' threads;
62 * - memory leak for 'alien' thread 'HashEntry's;
63 * - use 'PTHREAD_VALUE(pthread_t)' as identifier instead (?)
64 * - if yes, change 'oslThreadIdentifier' to 'intptr_t' or similar
65 * (3) 'oslSigAlarmHandler()' (#71232#)
66 * - [Under Solaris we get SIGALRM in e.g. pthread_join which terminates
67 * the process. So we initialize our signal handling module and do
68 * register a SIGALRM Handler which catches and ignores it]
69 * - should this still happen, 'signal.c' needs to be fixed instead.
71 ****************************************************************************/
73 /*****************************************************************************/
74 /* Internal data structures and functions */
75 /*****************************************************************************/
77 #define THREADIMPL_FLAGS_TERMINATE 0x00001
78 #define THREADIMPL_FLAGS_STARTUP 0x00002
79 #define THREADIMPL_FLAGS_SUSPENDED 0x00004
80 #define THREADIMPL_FLAGS_ACTIVE 0x00008
81 #define THREADIMPL_FLAGS_ATTACHED 0x00010
82 #define THREADIMPL_FLAGS_DESTROYED 0x00020
84 typedef struct osl_thread_impl_st
87 sal_uInt16 m_Ident
; /* @@@ see TODO @@@ */
89 oslWorkerFunction m_WorkerFunction
;
91 pthread_mutex_t m_Lock
;
92 pthread_cond_t m_Cond
;
95 struct osl_thread_priority_st
104 #define OSL_THREAD_PRIORITY_INITIALIZER { 127, 96, 64, 32, 0 }
105 static void osl_thread_priority_init_Impl (void);
107 struct osl_thread_textencoding_st
109 pthread_key_t m_key
; /* key to store thread local text encoding */
110 rtl_TextEncoding m_default
; /* the default text encoding */
113 #define OSL_THREAD_TEXTENCODING_INITIALIZER { 0, RTL_TEXTENCODING_DONTKNOW }
114 static void osl_thread_textencoding_init_Impl (void);
116 struct osl_thread_global_st
118 pthread_once_t m_once
;
119 struct osl_thread_priority_st m_priority
;
120 struct osl_thread_textencoding_st m_textencoding
;
123 static struct osl_thread_global_st g_thread
=
126 OSL_THREAD_PRIORITY_INITIALIZER
,
127 OSL_THREAD_TEXTENCODING_INITIALIZER
130 static void osl_thread_init_Impl (void);
132 static Thread_Impl
* osl_thread_construct_Impl (void);
133 static void osl_thread_destruct_Impl (Thread_Impl
** ppImpl
);
135 static void* osl_thread_start_Impl (void * pData
);
136 static void osl_thread_cleanup_Impl (Thread_Impl
* pImpl
);
138 static oslThread
osl_thread_create_Impl (
139 oslWorkerFunction pWorker
, void * pThreadData
, short nFlags
);
141 /* @@@ see TODO @@@ */
142 static sal_uInt16
insertThreadId (pthread_t hThread
);
143 static sal_uInt16
lookupThreadId (pthread_t hThread
);
144 static void removeThreadId (pthread_t hThread
);
146 /*****************************************************************************/
147 /* osl_thread_init_Impl */
148 /*****************************************************************************/
149 static void osl_thread_init_Impl (void)
151 osl_thread_priority_init_Impl();
152 osl_thread_textencoding_init_Impl();
155 /*****************************************************************************/
156 /* osl_thread_construct_Impl */
157 /*****************************************************************************/
158 Thread_Impl
* osl_thread_construct_Impl (void)
160 Thread_Impl
* pImpl
= malloc (sizeof(Thread_Impl
));
163 memset (pImpl
, 0, sizeof(Thread_Impl
));
165 pthread_mutex_init (&(pImpl
->m_Lock
), PTHREAD_MUTEXATTR_DEFAULT
);
166 pthread_cond_init (&(pImpl
->m_Cond
), PTHREAD_CONDATTR_DEFAULT
);
171 /*****************************************************************************/
172 /* osl_thread_destruct_Impl */
173 /*****************************************************************************/
174 static void osl_thread_destruct_Impl (Thread_Impl
** ppImpl
)
179 pthread_cond_destroy (&((*ppImpl
)->m_Cond
));
180 pthread_mutex_destroy (&((*ppImpl
)->m_Lock
));
187 /*****************************************************************************/
188 /* osl_thread_cleanup_Impl */
189 /*****************************************************************************/
190 static void osl_thread_cleanup_Impl (Thread_Impl
* pImpl
)
196 pthread_mutex_lock (&(pImpl
->m_Lock
));
198 thread
= pImpl
->m_hThread
;
199 attached
= (pImpl
->m_Flags
& THREADIMPL_FLAGS_ATTACHED
) != 0;
200 destroyed
= (pImpl
->m_Flags
& THREADIMPL_FLAGS_DESTROYED
) != 0;
201 pImpl
->m_Flags
&= ~(THREADIMPL_FLAGS_ACTIVE
| THREADIMPL_FLAGS_ATTACHED
);
203 pthread_mutex_unlock (&(pImpl
->m_Lock
));
205 /* release oslThreadIdentifier @@@ see TODO @@@ */
206 removeThreadId (thread
);
210 pthread_detach (thread
);
215 osl_thread_destruct_Impl (&pImpl
);
219 /*****************************************************************************/
220 /* osl_thread_start_Impl */
221 /*****************************************************************************/
222 static void* osl_thread_start_Impl (void* pData
)
225 Thread_Impl
* pImpl
= (Thread_Impl
*)pData
;
229 pthread_mutex_lock (&(pImpl
->m_Lock
));
231 /* request oslThreadIdentifier @@@ see TODO @@@ */
232 pImpl
->m_Ident
= insertThreadId (pImpl
->m_hThread
);
234 /* signal change from STARTUP to ACTIVE state */
235 pImpl
->m_Flags
&= ~THREADIMPL_FLAGS_STARTUP
;
236 pImpl
->m_Flags
|= THREADIMPL_FLAGS_ACTIVE
;
237 pthread_cond_signal (&(pImpl
->m_Cond
));
239 /* Check if thread is started in SUSPENDED state */
240 while (pImpl
->m_Flags
& THREADIMPL_FLAGS_SUSPENDED
)
242 /* wait until SUSPENDED flag is cleared */
243 pthread_cond_wait (&(pImpl
->m_Cond
), &(pImpl
->m_Lock
));
246 /* check for SUSPENDED to TERMINATE state change */
247 terminate
= ((pImpl
->m_Flags
& THREADIMPL_FLAGS_TERMINATE
) > 0);
249 pthread_mutex_unlock (&(pImpl
->m_Lock
));
256 int res
= (*lo_get_javavm())->AttachCurrentThread(lo_get_javavm(), &env
, NULL
); // res == 0
257 fprintf (stderr
, "new sal thread started and attached %d!\n", res
);
260 /* call worker function */
261 pImpl
->m_WorkerFunction(pImpl
->m_pData
);
265 int res
= (*lo_get_javavm())->DetachCurrentThread(lo_get_javavm());
266 fprintf (stderr
, "detached finished sal thread %d!\n", res
);
271 osl_thread_cleanup_Impl (pImpl
);
275 /*****************************************************************************/
276 /* osl_thread_create_Impl */
277 /*****************************************************************************/
278 static oslThread
osl_thread_create_Impl (
279 oslWorkerFunction pWorker
,
289 pImpl
= osl_thread_construct_Impl();
291 return (0); /* ENOMEM */
293 pImpl
->m_WorkerFunction
= pWorker
;
294 pImpl
->m_pData
= pThreadData
;
295 pImpl
->m_Flags
= nFlags
| THREADIMPL_FLAGS_STARTUP
;
297 pthread_mutex_lock (&(pImpl
->m_Lock
));
300 if (pthread_attr_init(&attr
) != 0)
303 if (pthread_attr_setstacksize(&attr
, 262144) != 0) {
304 pthread_attr_destroy(&attr
);
309 if ((nRet
= pthread_create (
314 PTHREAD_ATTR_DEFAULT
,
316 osl_thread_start_Impl
,
317 (void*)(pImpl
))) != 0)
319 OSL_TRACE("osl_thread_create_Impl(): errno: %d, %s\n",
320 nRet
, strerror(nRet
));
322 pthread_mutex_unlock (&(pImpl
->m_Lock
));
323 osl_thread_destruct_Impl (&pImpl
);
329 pthread_attr_destroy(&attr
);
332 /* wait for change from STARTUP to ACTIVE state */
333 while (pImpl
->m_Flags
& THREADIMPL_FLAGS_STARTUP
)
335 /* wait until STARTUP flag is cleared */
336 pthread_cond_wait (&(pImpl
->m_Cond
), &(pImpl
->m_Lock
));
339 pthread_mutex_unlock (&(pImpl
->m_Lock
));
341 return ((oslThread
)(pImpl
));
344 /*****************************************************************************/
345 /* osl_createThread */
346 /*****************************************************************************/
347 oslThread
osl_createThread (
348 oslWorkerFunction pWorker
,
351 return osl_thread_create_Impl (
354 THREADIMPL_FLAGS_ATTACHED
);
357 /*****************************************************************************/
358 /* osl_createSuspendedThread */
359 /*****************************************************************************/
360 oslThread
osl_createSuspendedThread (
361 oslWorkerFunction pWorker
,
364 return osl_thread_create_Impl (
367 THREADIMPL_FLAGS_ATTACHED
|
368 THREADIMPL_FLAGS_SUSPENDED
);
371 /*****************************************************************************/
372 /* osl_destroyThread */
373 /*****************************************************************************/
374 void SAL_CALL
osl_destroyThread(oslThread Thread
)
376 if (Thread
!= NULL
) {
377 Thread_Impl
* impl
= (Thread_Impl
*) Thread
;
379 pthread_mutex_lock(&impl
->m_Lock
);
380 active
= (impl
->m_Flags
& THREADIMPL_FLAGS_ACTIVE
) != 0;
381 impl
->m_Flags
|= THREADIMPL_FLAGS_DESTROYED
;
382 pthread_mutex_unlock(&impl
->m_Lock
);
384 osl_thread_destruct_Impl(&impl
);
389 /*****************************************************************************/
390 /* osl_resumeThread */
391 /*****************************************************************************/
392 void SAL_CALL
osl_resumeThread(oslThread Thread
)
394 Thread_Impl
* pImpl
= (Thread_Impl
*)Thread
;
400 pthread_mutex_lock (&(pImpl
->m_Lock
));
402 if (pImpl
->m_Flags
& THREADIMPL_FLAGS_SUSPENDED
)
404 /* clear SUSPENDED flag */
405 pImpl
->m_Flags
&= ~THREADIMPL_FLAGS_SUSPENDED
;
406 pthread_cond_signal (&(pImpl
->m_Cond
));
409 pthread_mutex_unlock (&(pImpl
->m_Lock
));
412 /*****************************************************************************/
413 /* osl_suspendThread */
414 /*****************************************************************************/
415 void SAL_CALL
osl_suspendThread(oslThread Thread
)
417 Thread_Impl
* pImpl
= (Thread_Impl
*)Thread
;
423 pthread_mutex_lock (&(pImpl
->m_Lock
));
425 pImpl
->m_Flags
|= THREADIMPL_FLAGS_SUSPENDED
;
427 if (pthread_equal (pthread_self(), pImpl
->m_hThread
))
430 while (pImpl
->m_Flags
& THREADIMPL_FLAGS_SUSPENDED
)
432 /* wait until SUSPENDED flag is cleared */
433 pthread_cond_wait (&(pImpl
->m_Cond
), &(pImpl
->m_Lock
));
437 pthread_mutex_unlock (&(pImpl
->m_Lock
));
440 /*****************************************************************************/
441 /* osl_isThreadRunning */
442 /*****************************************************************************/
443 sal_Bool SAL_CALL
osl_isThreadRunning(const oslThread Thread
)
446 Thread_Impl
* pImpl
= (Thread_Impl
*)Thread
;
451 pthread_mutex_lock (&(pImpl
->m_Lock
));
452 active
= ((pImpl
->m_Flags
& THREADIMPL_FLAGS_ACTIVE
) > 0);
453 pthread_mutex_unlock (&(pImpl
->m_Lock
));
458 /*****************************************************************************/
459 /* osl_joinWithThread */
460 /*****************************************************************************/
461 void SAL_CALL
osl_joinWithThread(oslThread Thread
)
465 Thread_Impl
* pImpl
= (Thread_Impl
*)Thread
;
470 pthread_mutex_lock (&(pImpl
->m_Lock
));
472 if (pthread_equal (pthread_self(), pImpl
->m_hThread
))
475 pthread_mutex_unlock (&(pImpl
->m_Lock
));
476 return; /* EDEADLK */
479 thread
= pImpl
->m_hThread
;
480 attached
= ((pImpl
->m_Flags
& THREADIMPL_FLAGS_ATTACHED
) > 0);
481 pImpl
->m_Flags
&= ~THREADIMPL_FLAGS_ATTACHED
;
483 pthread_mutex_unlock (&(pImpl
->m_Lock
));
487 pthread_join (thread
, NULL
);
491 /*****************************************************************************/
492 /* osl_terminateThread */
493 /*****************************************************************************/
494 void SAL_CALL
osl_terminateThread(oslThread Thread
)
496 Thread_Impl
* pImpl
= (Thread_Impl
*)Thread
;
502 pthread_mutex_lock (&(pImpl
->m_Lock
));
504 if (pImpl
->m_Flags
& THREADIMPL_FLAGS_SUSPENDED
)
506 /* clear SUSPENDED flag */
507 pImpl
->m_Flags
&= ~THREADIMPL_FLAGS_SUSPENDED
;
508 pthread_cond_signal (&(pImpl
->m_Cond
));
511 pImpl
->m_Flags
|= THREADIMPL_FLAGS_TERMINATE
;
513 pthread_mutex_unlock (&(pImpl
->m_Lock
));
516 /*****************************************************************************/
517 /* osl_scheduleThread */
518 /*****************************************************************************/
519 sal_Bool SAL_CALL
osl_scheduleThread(oslThread Thread
)
522 Thread_Impl
* pImpl
= (Thread_Impl
*)Thread
;
526 return sal_False
; /* EINVAL */
528 OSL_ASSERT(pthread_equal (pthread_self(), pImpl
->m_hThread
));
529 if (!(pthread_equal (pthread_self(), pImpl
->m_hThread
)))
530 return sal_False
; /* EINVAL */
532 pthread_mutex_lock (&(pImpl
->m_Lock
));
534 while (pImpl
->m_Flags
& THREADIMPL_FLAGS_SUSPENDED
)
536 /* wait until SUSPENDED flag is cleared */
537 pthread_cond_wait (&(pImpl
->m_Cond
), &(pImpl
->m_Lock
));
540 terminate
= ((pImpl
->m_Flags
& THREADIMPL_FLAGS_TERMINATE
) > 0);
542 pthread_mutex_unlock(&(pImpl
->m_Lock
));
544 return (terminate
== 0);
547 /*****************************************************************************/
549 /*****************************************************************************/
550 void SAL_CALL
osl_waitThread(const TimeValue
* pDelay
)
554 struct timespec delay
;
556 SET_TIMESPEC(delay
, pDelay
->Seconds
, pDelay
->Nanosec
);
558 SLEEP_TIMESPEC(delay
);
562 /*****************************************************************************/
563 /* osl_yieldThread */
565 Note that POSIX scheduling _really_ requires threads to call this
566 functions, since a thread only reschedules to other thread, when
567 it blocks (sleep, blocking I/O) OR calls sched_yield().
569 /*****************************************************************************/
570 void SAL_CALL
osl_yieldThread()
575 void SAL_CALL
osl_setThreadName(char const * name
) {
576 #if defined LINUX && ! defined __FreeBSD_kernel__
577 if (prctl(PR_SET_NAME
, (unsigned long) name
, 0, 0, 0) != 0) {
579 "%s prctl(PR_SET_NAME) failed with errno %d", OSL_LOG_PREFIX
,
587 /*****************************************************************************/
588 /* osl_getThreadIdentifier @@@ see TODO @@@ */
589 /*****************************************************************************/
591 #define HASHID(x) ((unsigned int)PTHREAD_VALUE(x) % HashSize)
593 typedef struct _HashEntry
597 struct _HashEntry
*Next
;
600 static HashEntry
* HashTable
[31];
601 static int HashSize
= SAL_N_ELEMENTS(HashTable
);
603 static pthread_mutex_t HashLock
= PTHREAD_MUTEX_INITIALIZER
;
605 static sal_uInt16 LastIdent
= 0;
607 static sal_uInt16
lookupThreadId (pthread_t hThread
)
611 pthread_mutex_lock(&HashLock
);
613 pEntry
= HashTable
[HASHID(hThread
)];
614 while (pEntry
!= NULL
)
616 if (pthread_equal(pEntry
->Handle
, hThread
))
618 pthread_mutex_unlock(&HashLock
);
619 return (pEntry
->Ident
);
621 pEntry
= pEntry
->Next
;
624 pthread_mutex_unlock(&HashLock
);
629 static sal_uInt16
insertThreadId (pthread_t hThread
)
631 HashEntry
*pEntry
, *pInsert
= NULL
;
633 pthread_mutex_lock(&HashLock
);
635 pEntry
= HashTable
[HASHID(hThread
)];
637 while (pEntry
!= NULL
)
639 if (pthread_equal(pEntry
->Handle
, hThread
))
643 pEntry
= pEntry
->Next
;
648 pEntry
= (HashEntry
*) calloc(sizeof(HashEntry
), 1);
650 pEntry
->Handle
= hThread
;
654 if ( LastIdent
== 0 )
657 pEntry
->Ident
= LastIdent
;
660 pInsert
->Next
= pEntry
;
662 HashTable
[HASHID(hThread
)] = pEntry
;
665 pthread_mutex_unlock(&HashLock
);
667 return (pEntry
->Ident
);
670 static void removeThreadId (pthread_t hThread
)
672 HashEntry
*pEntry
, *pRemove
= NULL
;
674 pthread_mutex_lock(&HashLock
);
676 pEntry
= HashTable
[HASHID(hThread
)];
677 while (pEntry
!= NULL
)
679 if (pthread_equal(pEntry
->Handle
, hThread
))
683 pEntry
= pEntry
->Next
;
689 pRemove
->Next
= pEntry
->Next
;
691 HashTable
[HASHID(hThread
)] = pEntry
->Next
;
696 pthread_mutex_unlock(&HashLock
);
699 oslThreadIdentifier SAL_CALL
osl_getThreadIdentifier(oslThread Thread
)
701 Thread_Impl
* pImpl
= (Thread_Impl
*)Thread
;
705 Ident
= pImpl
->m_Ident
;
709 pthread_t current
= pthread_self();
711 Ident
= lookupThreadId (current
);
713 /* @@@ see TODO: alien pthread_self() @@@ */
714 Ident
= insertThreadId (current
);
717 return ((oslThreadIdentifier
)(Ident
));
720 /*****************************************************************************
722 osl_thread_priority_init_Impl
724 set the base-priority of the main-thread to
725 oslThreadPriorityNormal (64) since 0 (lowest) is
726 the system default. This behaviour collides with
727 our enum-priority definition (highest..normal..lowest).
728 A normaluser will expect the main-thread of an app.
729 to have the "normal" priority.
731 *****************************************************************************/
732 static void osl_thread_priority_init_Impl (void)
734 #ifndef NO_PTHREAD_PRIORITY
735 struct sched_param param
;
739 /* @@@ see TODO: calling thread may not be main thread @@@ */
741 if ((nRet
= pthread_getschedparam(pthread_self(), &policy
, ¶m
)) != 0)
743 OSL_TRACE("failed to get priority of thread [%s]",strerror(nRet
));
747 #if defined (SOLARIS)
748 if ( policy
>= _SCHED_NEXT
)
750 /* mfe: pthread_getschedparam on Solaris has a possible Bug */
751 /* one gets 959917873 as the policy */
752 /* so set the policy to a default one */
757 if ((nRet
= sched_get_priority_min(policy
) ) != -1)
759 OSL_TRACE("Min Prioriy for policy '%i' == '%i'",policy
,nRet
);
760 g_thread
.m_priority
.m_Lowest
=nRet
;
762 #if OSL_DEBUG_LEVEL > 1
765 fprintf(stderr
,"failed to get min sched param [%s]\n",strerror(errno
));
767 #endif /* OSL_DEBUG_LEVEL */
769 if ((nRet
= sched_get_priority_max(policy
) ) != -1)
771 OSL_TRACE("Max Prioriy for policy '%i' == '%i'",policy
,nRet
);
772 g_thread
.m_priority
.m_Highest
=nRet
;
774 #if OSL_DEBUG_LEVEL > 1
777 fprintf(stderr
,"failed to get max sched param [%s]\n",strerror(errno
));
779 #endif /* OSL_DEBUG_LEVEL */
781 g_thread
.m_priority
.m_Normal
=
782 (g_thread
.m_priority
.m_Lowest
+ g_thread
.m_priority
.m_Highest
) / 2;
783 g_thread
.m_priority
.m_Below_Normal
=
784 (g_thread
.m_priority
.m_Lowest
+ g_thread
.m_priority
.m_Normal
) / 2;
785 g_thread
.m_priority
.m_Above_Normal
=
786 (g_thread
.m_priority
.m_Normal
+ g_thread
.m_priority
.m_Highest
) / 2;
788 /* @@@ set prio of calling (not main) thread (?) @@@ */
790 param
.sched_priority
= g_thread
.m_priority
.m_Normal
;
792 if ((nRet
= pthread_setschedparam(pthread_self(), policy
, ¶m
)) != 0)
794 OSL_TRACE("failed to change base priority of thread [%s]",strerror(nRet
));
795 OSL_TRACE("Thread ID '%i', Policy '%i', Priority '%i'\n",pthread_self(),policy
,param
.sched_priority
);
798 #endif /* NO_PTHREAD_PRIORITY */
801 /*****************************************************************************/
802 /* osl_setThreadPriority */
804 Impl-Notes: contrary to solaris-docu, which claims
805 valid priority-levels from 0 .. INT_MAX, only the
806 range 0..127 is accepted. (0 lowest, 127 highest)
808 /*****************************************************************************/
809 void SAL_CALL
osl_setThreadPriority (
811 oslThreadPriority Priority
)
813 #ifndef NO_PTHREAD_PRIORITY
815 struct sched_param Param
;
819 #endif /* NO_PTHREAD_PRIORITY */
821 Thread_Impl
* pImpl
= (Thread_Impl
*)Thread
;
827 #ifdef NO_PTHREAD_PRIORITY
828 (void) Priority
; /* unused */
829 #else /* NO_PTHREAD_PRIORITY */
831 if (pthread_getschedparam(pImpl
->m_hThread
, &policy
, &Param
) != 0)
834 #if defined (SOLARIS)
835 if ( policy
>= _SCHED_NEXT
)
837 /* mfe: pthread_getschedparam on Solaris has a possible Bug */
838 /* one gets 959917873 as the policy */
839 /* so set the policy to a default one */
844 pthread_once (&(g_thread
.m_once
), osl_thread_init_Impl
);
848 case osl_Thread_PriorityHighest
:
849 Param
.sched_priority
= g_thread
.m_priority
.m_Highest
;
852 case osl_Thread_PriorityAboveNormal
:
853 Param
.sched_priority
= g_thread
.m_priority
.m_Above_Normal
;
856 case osl_Thread_PriorityNormal
:
857 Param
.sched_priority
= g_thread
.m_priority
.m_Normal
;
860 case osl_Thread_PriorityBelowNormal
:
861 Param
.sched_priority
= g_thread
.m_priority
.m_Below_Normal
;
864 case osl_Thread_PriorityLowest
:
865 Param
.sched_priority
= g_thread
.m_priority
.m_Lowest
;
868 case osl_Thread_PriorityUnknown
:
869 OSL_ASSERT(sal_False
); /* only fools try this...*/
871 /* let release-version behave friendly */
875 /* enum expanded, but forgotten here...*/
876 OSL_ENSURE(sal_False
,"osl_setThreadPriority : unknown priority\n");
878 /* let release-version behave friendly */
882 if ((nRet
= pthread_setschedparam(pImpl
->m_hThread
, policy
, &Param
)) != 0)
884 OSL_TRACE("failed to change thread priority [%s]",strerror(nRet
));
887 #endif /* NO_PTHREAD_PRIORITY */
890 /*****************************************************************************/
891 /* osl_getThreadPriority */
892 /*****************************************************************************/
893 oslThreadPriority SAL_CALL
osl_getThreadPriority(const oslThread Thread
)
895 #ifndef NO_PTHREAD_PRIORITY
897 struct sched_param Param
;
900 #endif /* NO_PTHREAD_PRIORITY */
902 oslThreadPriority Priority
= osl_Thread_PriorityNormal
;
903 Thread_Impl
* pImpl
= (Thread_Impl
*)Thread
;
907 return osl_Thread_PriorityUnknown
; /* EINVAL */
909 #ifndef NO_PTHREAD_PRIORITY
911 if (pthread_getschedparam(pImpl
->m_hThread
, &Policy
, &Param
) != 0)
912 return osl_Thread_PriorityUnknown
; /* ESRCH */
914 pthread_once (&(g_thread
.m_once
), osl_thread_init_Impl
);
916 /* map pthread priority to enum */
917 if (Param
.sched_priority
==g_thread
.m_priority
.m_Highest
)
920 Priority
= osl_Thread_PriorityHighest
;
922 else if (Param
.sched_priority
> g_thread
.m_priority
.m_Normal
)
924 /* 65..126 - above normal */
925 Priority
= osl_Thread_PriorityAboveNormal
;
927 else if (Param
.sched_priority
== g_thread
.m_priority
.m_Normal
)
930 Priority
= osl_Thread_PriorityNormal
;
932 else if (Param
.sched_priority
> g_thread
.m_priority
.m_Lowest
)
934 /* 63..1 -below normal */
935 Priority
= osl_Thread_PriorityBelowNormal
;
937 else if (Param
.sched_priority
== g_thread
.m_priority
.m_Lowest
)
940 Priority
= osl_Thread_PriorityLowest
;
945 Priority
= osl_Thread_PriorityUnknown
;
948 #endif /* NO_PTHREAD_PRIORITY */
953 typedef struct _wrapper_pthread_key
956 oslThreadKeyCallbackFunction pfnCallback
;
957 } wrapper_pthread_key
;
959 /*****************************************************************************/
960 /* osl_createThreadKey */
961 /*****************************************************************************/
962 oslThreadKey SAL_CALL
osl_createThreadKey( oslThreadKeyCallbackFunction pCallback
)
964 wrapper_pthread_key
*pKey
= (wrapper_pthread_key
*)rtl_allocateMemory(sizeof(wrapper_pthread_key
));
968 pKey
->pfnCallback
= pCallback
;
970 if (pthread_key_create(&(pKey
->m_key
), pKey
->pfnCallback
) != 0)
972 rtl_freeMemory(pKey
);
977 return ((oslThreadKey
)pKey
);
980 /*****************************************************************************/
981 /* osl_destroyThreadKey */
982 /*****************************************************************************/
983 void SAL_CALL
osl_destroyThreadKey(oslThreadKey Key
)
985 wrapper_pthread_key
*pKey
= (wrapper_pthread_key
*)Key
;
988 pthread_key_delete(pKey
->m_key
);
989 rtl_freeMemory(pKey
);
993 /*****************************************************************************/
994 /* osl_getThreadKeyData */
995 /*****************************************************************************/
996 void* SAL_CALL
osl_getThreadKeyData(oslThreadKey Key
)
998 wrapper_pthread_key
*pKey
= (wrapper_pthread_key
*)Key
;
999 return pKey
? pthread_getspecific(pKey
->m_key
) : NULL
;
1002 /*****************************************************************************/
1003 /* osl_setThreadKeyData */
1004 /*****************************************************************************/
1005 sal_Bool SAL_CALL
osl_setThreadKeyData(oslThreadKey Key
, void *pData
)
1008 void *pOldData
= NULL
;
1009 wrapper_pthread_key
*pKey
= (wrapper_pthread_key
*)Key
;
1013 if (pKey
->pfnCallback
)
1014 pOldData
= pthread_getspecific(pKey
->m_key
);
1016 bRet
= (pthread_setspecific(pKey
->m_key
, pData
) == 0);
1018 if (bRet
&& pKey
->pfnCallback
&& pOldData
)
1019 pKey
->pfnCallback(pOldData
);
1024 /*****************************************************************************/
1025 /* Thread Local Text Encoding */
1026 /*****************************************************************************/
1027 static void osl_thread_textencoding_init_Impl (void)
1029 rtl_TextEncoding defaultEncoding
;
1030 const char * pszEncoding
;
1032 /* create thread specific data key */
1033 pthread_key_create (&(g_thread
.m_textencoding
.m_key
), NULL
);
1035 /* determine default text encoding */
1036 pszEncoding
= getenv ("SOLAR_USER_RTL_TEXTENCODING");
1038 defaultEncoding
= atoi(pszEncoding
);
1040 defaultEncoding
= osl_getTextEncodingFromLocale(NULL
);
1042 OSL_ASSERT(defaultEncoding
!= RTL_TEXTENCODING_DONTKNOW
);
1045 Tools string functions call abort() on an unknown encoding so ASCII
1046 is a meaningfull fallback regardless wether the assertion makes sense.
1049 if ( RTL_TEXTENCODING_DONTKNOW
== defaultEncoding
)
1050 defaultEncoding
= RTL_TEXTENCODING_ASCII_US
;
1052 g_thread
.m_textencoding
.m_default
= defaultEncoding
;
1055 /*****************************************************************************/
1056 /* osl_getThreadTextEncoding */
1057 /*****************************************************************************/
1058 rtl_TextEncoding SAL_CALL
osl_getThreadTextEncoding()
1060 rtl_TextEncoding threadEncoding
;
1062 pthread_once (&(g_thread
.m_once
), osl_thread_init_Impl
);
1064 /* check for thread specific encoding, use default if not set */
1065 threadEncoding
= SAL_INT_CAST(
1067 (sal_uIntPtr
) pthread_getspecific(g_thread
.m_textencoding
.m_key
));
1068 if (0 == threadEncoding
)
1069 threadEncoding
= g_thread
.m_textencoding
.m_default
;
1071 return threadEncoding
;
1074 /*****************************************************************************/
1075 /* osl_setThreadTextEncoding */
1076 /*****************************************************************************/
1077 rtl_TextEncoding
osl_setThreadTextEncoding(rtl_TextEncoding Encoding
)
1079 rtl_TextEncoding oldThreadEncoding
= osl_getThreadTextEncoding();
1081 /* save encoding in thread local storage */
1082 pthread_setspecific (
1083 g_thread
.m_textencoding
.m_key
,
1084 (void*) SAL_INT_CAST(sal_uIntPtr
, Encoding
));
1086 return oldThreadEncoding
;
1089 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */