Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(180)

Side by Side Diff: nspr/pr/src/pthreads/ptthread.c

Issue 68173008: Update to NSPR 4.10.2. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/nss/
Patch Set: Update README.chromium Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « nspr/pr/src/pthreads/ptio.c ('k') | nspr/pr/src/threads/combined/pruthr.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public 2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 5
6 /* 6 /*
7 ** File: ptthread.c 7 ** File: ptthread.c
8 ** Descritpion: Implemenation for threds using pthreds 8 ** Descritpion: Implemenation for threds using pthreds
9 ** Exports: ptthread.h 9 ** Exports: ptthread.h
10 */ 10 */
(...skipping 10 matching lines...) Expand all
21 #include <signal.h> 21 #include <signal.h>
22 #include <dlfcn.h> 22 #include <dlfcn.h>
23 23
24 #ifdef SYMBIAN 24 #ifdef SYMBIAN
25 /* In Open C sched_get_priority_min/max do not work properly, so we undefine 25 /* In Open C sched_get_priority_min/max do not work properly, so we undefine
26 * _POSIX_THREAD_PRIORITY_SCHEDULING here. 26 * _POSIX_THREAD_PRIORITY_SCHEDULING here.
27 */ 27 */
28 #undef _POSIX_THREAD_PRIORITY_SCHEDULING 28 #undef _POSIX_THREAD_PRIORITY_SCHEDULING
29 #endif 29 #endif
30 30
31 #ifdef _PR_NICE_PRIORITY_SCHEDULING
32 #undef _POSIX_THREAD_PRIORITY_SCHEDULING
33 #include <sys/resource.h>
34 #ifndef HAVE_GETTID
35 #define gettid() (syscall(SYS_gettid))
36 #endif
37 #endif
38
31 /* 39 /*
32 * Record whether or not we have the privilege to set the scheduling 40 * Record whether or not we have the privilege to set the scheduling
33 * policy and priority of threads. 0 means that privilege is available. 41 * policy and priority of threads. 0 means that privilege is available.
34 * EPERM means that privilege is not available. 42 * EPERM means that privilege is not available.
35 */ 43 */
36 44
37 static PRIntn pt_schedpriv = 0; 45 static PRIntn pt_schedpriv = 0;
38 extern PRLock *_pr_sleeplock; 46 extern PRLock *_pr_sleeplock;
39 47
40 static struct _PT_Bookeeping 48 static struct _PT_Bookeeping
(...skipping 21 matching lines...) Expand all
62 * for now I have just hard coded everything to run at priority 10 70 * for now I have just hard coded everything to run at priority 10
63 * until I can come up with a new algorithm. 71 * until I can come up with a new algorithm.
64 * Jerry.Kirk@Nexwarecorp.com 72 * Jerry.Kirk@Nexwarecorp.com
65 */ 73 */
66 return 10; 74 return 10;
67 #else 75 #else
68 return pt_book.minPrio + 76 return pt_book.minPrio +
69 pri * (pt_book.maxPrio - pt_book.minPrio) / PR_PRIORITY_LAST; 77 pri * (pt_book.maxPrio - pt_book.minPrio) / PR_PRIORITY_LAST;
70 #endif 78 #endif
71 } 79 }
80 #elif defined(_PR_NICE_PRIORITY_SCHEDULING)
81 /*
82 * This functions maps higher priorities to lower nice values relative to the
83 * nice value specified in the |nice| parameter. The corresponding relative
84 * adjustments are:
85 *
86 * PR_PRIORITY_LOW +1
87 * PR_PRIORITY_NORMAL 0
88 * PR_PRIORITY_HIGH -1
89 * PR_PRIORITY_URGENT -2
90 */
91 static int pt_RelativePriority(int nice, PRThreadPriority pri)
92 {
93 return nice + (1 - pri);
94 }
72 #endif 95 #endif
73 96
74 /* 97 /*
75 ** Initialize a stack for a native pthread thread 98 ** Initialize a stack for a native pthread thread
76 */ 99 */
77 static void _PR_InitializeStack(PRThreadStack *ts) 100 static void _PR_InitializeStack(PRThreadStack *ts)
78 { 101 {
79 if( ts && (ts->stackTop == 0) ) { 102 if( ts && (ts->stackTop == 0) ) {
80 ts->allocBase = (char *) &ts; 103 ts->allocBase = (char *) &ts;
81 ts->allocSize = ts->stackSize; 104 ts->allocSize = ts->stackSize;
82 105
83 /* 106 /*
84 ** Setup stackTop and stackBottom values. 107 ** Setup stackTop and stackBottom values.
85 */ 108 */
86 #ifdef HAVE_STACK_GROWING_UP 109 #ifdef HAVE_STACK_GROWING_UP
87 ts->stackBottom = ts->allocBase + ts->stackSize; 110 ts->stackBottom = ts->allocBase + ts->stackSize;
88 ts->stackTop = ts->allocBase; 111 ts->stackTop = ts->allocBase;
89 #else 112 #else
90 ts->stackTop = ts->allocBase; 113 ts->stackTop = ts->allocBase;
91 ts->stackBottom = ts->allocBase - ts->stackSize; 114 ts->stackBottom = ts->allocBase - ts->stackSize;
92 #endif 115 #endif
93 } 116 }
94 } 117 }
95 118
96 static void *_pt_root(void *arg) 119 static void *_pt_root(void *arg)
97 { 120 {
98 PRIntn rv; 121 PRIntn rv;
99 PRThread *thred = (PRThread*)arg; 122 PRThread *thred = (PRThread*)arg;
100 PRBool detached = (thred->state & PT_THREAD_DETACHED) ? PR_TRUE : PR_FALSE; 123 PRBool detached = (thred->state & PT_THREAD_DETACHED) ? PR_TRUE : PR_FALSE;
124 #ifdef _PR_NICE_PRIORITY_SCHEDULING
125 pid_t tid;
126 #endif
101 127
102 /* 128 /*
103 * Both the parent thread and this new thread set thred->id. 129 * Both the parent thread and this new thread set thred->id.
104 * The new thread must ensure that thred->id is set before 130 * The new thread must ensure that thred->id is set before
105 * it executes its startFunc. The parent thread must ensure 131 * it executes its startFunc. The parent thread must ensure
106 * that thred->id is set before PR_CreateThread() returns. 132 * that thred->id is set before PR_CreateThread() returns.
107 * Both threads set thred->id without holding a lock. Since 133 * Both threads set thred->id without holding a lock. Since
108 * they are writing the same value, this unprotected double 134 * they are writing the same value, this unprotected double
109 * write should be safe. 135 * write should be safe.
110 */ 136 */
111 thred->id = pthread_self(); 137 thred->id = pthread_self();
112 138
139 #ifdef _PR_NICE_PRIORITY_SCHEDULING
140 /*
141 * We need to know the kernel thread ID of each thread in order to
142 * set its nice value hence we do it here instead of at creation time.
143 */
144 tid = gettid();
145 errno = 0;
146 rv = getpriority(PRIO_PROCESS, 0);
147
148 /* If we cannot read the main thread's nice value don't try to change the
149 * new thread's nice value. */
150 if (errno == 0) {
151 setpriority(PRIO_PROCESS, tid,
152 pt_RelativePriority(rv, thred->priority));
153 }
154
155 PR_Lock(pt_book.ml);
156 thred->tid = tid;
157 PR_NotifyAllCondVar(pt_book.cv);
158 PR_Unlock(pt_book.ml);
159 #endif
160
113 /* 161 /*
114 ** DCE Threads can't detach during creation, so do it late. 162 ** DCE Threads can't detach during creation, so do it late.
115 ** I would like to do it only here, but that doesn't seem 163 ** I would like to do it only here, but that doesn't seem
116 ** to work. 164 ** to work.
117 */ 165 */
118 #if defined(_PR_DCETHREADS) 166 #if defined(_PR_DCETHREADS)
119 if (detached) 167 if (detached)
120 { 168 {
121 /* pthread_detach() modifies its argument, so we must pass a copy */ 169 /* pthread_detach() modifies its argument, so we must pass a copy */
122 pthread_t self = thred->id; 170 pthread_t self = thred->id;
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 if (!_pr_initialized) return NULL; 265 if (!_pr_initialized) return NULL;
218 266
219 /* PR_NEWZAP must not call PR_GetCurrentThread() */ 267 /* PR_NEWZAP must not call PR_GetCurrentThread() */
220 thred = PR_NEWZAP(PRThread); 268 thred = PR_NEWZAP(PRThread);
221 if (NULL != thred) 269 if (NULL != thred)
222 { 270 {
223 int rv; 271 int rv;
224 272
225 thred->priority = PR_PRIORITY_NORMAL; 273 thred->priority = PR_PRIORITY_NORMAL;
226 thred->id = pthread_self(); 274 thred->id = pthread_self();
275 #ifdef _PR_NICE_PRIORITY_SCHEDULING
276 thred->tid = gettid();
277 #endif
227 rv = pthread_setspecific(pt_book.key, thred); 278 rv = pthread_setspecific(pt_book.key, thred);
228 PR_ASSERT(0 == rv); 279 PR_ASSERT(0 == rv);
229 280
230 thred->state = PT_THREAD_GLOBAL | PT_THREAD_FOREIGN; 281 thred->state = PT_THREAD_GLOBAL | PT_THREAD_FOREIGN;
231 PR_Lock(pt_book.ml); 282 PR_Lock(pt_book.ml);
232 283
233 /* then put it into the list */ 284 /* then put it into the list */
234 thred->prev = pt_book.last; 285 thred->prev = pt_book.last;
235 if (pt_book.last) 286 if (pt_book.last)
236 pt_book.last->next = thred; 287 pt_book.last->next = thred;
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after
637 if (EPERM == rv) 688 if (EPERM == rv)
638 { 689 {
639 pt_schedpriv = EPERM; 690 pt_schedpriv = EPERM;
640 PR_LOG(_pr_thread_lm, PR_LOG_MIN, 691 PR_LOG(_pr_thread_lm, PR_LOG_MIN,
641 ("PR_SetThreadPriority: no thread schedu ling privilege")); 692 ("PR_SetThreadPriority: no thread schedu ling privilege"));
642 } 693 }
643 } 694 }
644 if (rv != 0) 695 if (rv != 0)
645 rv = -1; 696 rv = -1;
646 } 697 }
698 #elif defined(_PR_NICE_PRIORITY_SCHEDULING)
699 PR_Lock(pt_book.ml);
700 while (thred->tid == 0)
701 PR_WaitCondVar(pt_book.cv, PR_INTERVAL_NO_TIMEOUT);
702 PR_Unlock(pt_book.ml);
703
704 errno = 0;
705 rv = getpriority(PRIO_PROCESS, 0);
706
707 /* Do not proceed unless we know the main thread's nice value. */
708 if (errno == 0) {
709 rv = setpriority(PRIO_PROCESS, thred->tid,
710 pt_RelativePriority(rv, newPri));
711
712 if (rv == -1)
713 {
714 /* We don't set pt_schedpriv to EPERM in case errno == EPERM
715 * because adjusting the nice value might be permitted for certain
716 * ranges but not for others. */
717 PR_LOG(_pr_thread_lm, PR_LOG_MIN,
718 ("PR_SetThreadPriority: setpriority failed with error %d",
719 errno));
720 }
721 }
647 #endif 722 #endif
648 723
649 thred->priority = newPri; 724 thred->priority = newPri;
650 } /* PR_SetThreadPriority */ 725 } /* PR_SetThreadPriority */
651 726
652 PR_IMPLEMENT(PRStatus) PR_Interrupt(PRThread *thred) 727 PR_IMPLEMENT(PRStatus) PR_Interrupt(PRThread *thred)
653 { 728 {
654 /* 729 /*
655 ** If the target thread indicates that it's waiting, 730 ** If the target thread indicates that it's waiting,
656 ** find the condition and broadcast to it. Broadcast 731 ** find the condition and broadcast to it. Broadcast
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
809 #endif /* defined(DEBUG) */ 884 #endif /* defined(DEBUG) */
810 PR_Free(thred); 885 PR_Free(thred);
811 } /* _pt_thread_death */ 886 } /* _pt_thread_death */
812 887
813 void _PR_InitThreads( 888 void _PR_InitThreads(
814 PRThreadType type, PRThreadPriority priority, PRUintn maxPTDs) 889 PRThreadType type, PRThreadPriority priority, PRUintn maxPTDs)
815 { 890 {
816 int rv; 891 int rv;
817 PRThread *thred; 892 PRThread *thred;
818 893
894 PR_ASSERT(priority == PR_PRIORITY_NORMAL);
895
819 #ifdef _PR_NEED_PTHREAD_INIT 896 #ifdef _PR_NEED_PTHREAD_INIT
820 /* 897 /*
821 * On BSD/OS (3.1 and 4.0), the pthread subsystem is lazily 898 * On BSD/OS (3.1 and 4.0), the pthread subsystem is lazily
822 * initialized, but pthread_self() fails to initialize 899 * initialized, but pthread_self() fails to initialize
823 * pthreads and hence returns a null thread ID if invoked 900 * pthreads and hence returns a null thread ID if invoked
824 * by the primordial thread before any other pthread call. 901 * by the primordial thread before any other pthread call.
825 * So we explicitly initialize pthreads here. 902 * So we explicitly initialize pthreads here.
826 */ 903 */
827 pthread_init(); 904 pthread_init();
828 #endif 905 #endif
(...skipping 26 matching lines...) Expand all
855 pt_book.ml = PR_NewLock(); 932 pt_book.ml = PR_NewLock();
856 PR_ASSERT(NULL != pt_book.ml); 933 PR_ASSERT(NULL != pt_book.ml);
857 pt_book.cv = PR_NewCondVar(pt_book.ml); 934 pt_book.cv = PR_NewCondVar(pt_book.ml);
858 PR_ASSERT(NULL != pt_book.cv); 935 PR_ASSERT(NULL != pt_book.cv);
859 thred = PR_NEWZAP(PRThread); 936 thred = PR_NEWZAP(PRThread);
860 PR_ASSERT(NULL != thred); 937 PR_ASSERT(NULL != thred);
861 thred->arg = NULL; 938 thred->arg = NULL;
862 thred->startFunc = NULL; 939 thred->startFunc = NULL;
863 thred->priority = priority; 940 thred->priority = priority;
864 thred->id = pthread_self(); 941 thred->id = pthread_self();
942 #ifdef _PR_NICE_PRIORITY_SCHEDULING
943 thred->tid = gettid();
944 #endif
865 945
866 thred->state = (PT_THREAD_DETACHED | PT_THREAD_PRIMORD); 946 thred->state = (PT_THREAD_DETACHED | PT_THREAD_PRIMORD);
867 if (PR_SYSTEM_THREAD == type) 947 if (PR_SYSTEM_THREAD == type)
868 { 948 {
869 thred->state |= PT_THREAD_SYSTEM; 949 thred->state |= PT_THREAD_SYSTEM;
870 pt_book.system += 1; 950 pt_book.system += 1;
871 pt_book.this_many = 0; 951 pt_book.this_many = 0;
872 } 952 }
873 else 953 else
874 { 954 {
(...skipping 20 matching lines...) Expand all
895 * More info - the problem is that pthreads calls the destructor 975 * More info - the problem is that pthreads calls the destructor
896 * eagerly as the thread returns from its root, rather than lazily 976 * eagerly as the thread returns from its root, rather than lazily
897 * after the thread is joined. Therefore, threads that are joining 977 * after the thread is joined. Therefore, threads that are joining
898 * and holding PRThread references are actually holding pointers to 978 * and holding PRThread references are actually holding pointers to
899 * nothing. 979 * nothing.
900 */ 980 */
901 rv = _PT_PTHREAD_KEY_CREATE(&pt_book.key, _pt_thread_death); 981 rv = _PT_PTHREAD_KEY_CREATE(&pt_book.key, _pt_thread_death);
902 PR_ASSERT(0 == rv); 982 PR_ASSERT(0 == rv);
903 rv = pthread_setspecific(pt_book.key, thred); 983 rv = pthread_setspecific(pt_book.key, thred);
904 PR_ASSERT(0 == rv); 984 PR_ASSERT(0 == rv);
905 PR_SetThreadPriority(thred, priority);
906 } /* _PR_InitThreads */ 985 } /* _PR_InitThreads */
907 986
908 #ifdef __GNUC__ 987 #ifdef __GNUC__
909 /* 988 /*
910 * GCC supports the constructor and destructor attributes as of 989 * GCC supports the constructor and destructor attributes as of
911 * version 2.5. 990 * version 2.5.
912 */ 991 */
913 static void _PR_Fini(void) __attribute__ ((destructor)); 992 static void _PR_Fini(void) __attribute__ ((destructor));
914 #elif defined(__SUNPRO_C) 993 #elif defined(__SUNPRO_C)
915 /* 994 /*
(...skipping 779 matching lines...) Expand 10 before | Expand all | Expand 10 after
1695 PR_IMPLEMENT(const char *) PR_GetThreadName(const PRThread *thread) 1774 PR_IMPLEMENT(const char *) PR_GetThreadName(const PRThread *thread)
1696 { 1775 {
1697 if (!thread) 1776 if (!thread)
1698 return NULL; 1777 return NULL;
1699 return thread->name; 1778 return thread->name;
1700 } 1779 }
1701 1780
1702 #endif /* defined(_PR_PTHREADS) || defined(_PR_DCETHREADS) */ 1781 #endif /* defined(_PR_PTHREADS) || defined(_PR_DCETHREADS) */
1703 1782
1704 /* ptthread.c */ 1783 /* ptthread.c */
OLDNEW
« no previous file with comments | « nspr/pr/src/pthreads/ptio.c ('k') | nspr/pr/src/threads/combined/pruthr.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698