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

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

Issue 200653003: Update to NSPR 4.10.4. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/nss/
Patch Set: Created 6 years, 9 months 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/ptsynch.c ('k') | nspr/pr/src/threads/combined/prucv.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 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 ts->stackBottom = ts->allocBase - ts->stackSize; 115 ts->stackBottom = ts->allocBase - ts->stackSize;
116 #endif 116 #endif
117 } 117 }
118 } 118 }
119 119
120 static void *_pt_root(void *arg) 120 static void *_pt_root(void *arg)
121 { 121 {
122 PRIntn rv; 122 PRIntn rv;
123 PRThread *thred = (PRThread*)arg; 123 PRThread *thred = (PRThread*)arg;
124 PRBool detached = (thred->state & PT_THREAD_DETACHED) ? PR_TRUE : PR_FALSE; 124 PRBool detached = (thred->state & PT_THREAD_DETACHED) ? PR_TRUE : PR_FALSE;
125 pthread_t id = pthread_self();
125 #ifdef _PR_NICE_PRIORITY_SCHEDULING 126 #ifdef _PR_NICE_PRIORITY_SCHEDULING
126 pid_t tid; 127 pid_t tid;
127 #endif 128 #endif
128 129
129 /*
130 * Both the parent thread and this new thread set thred->id.
131 * The new thread must ensure that thred->id is set before
132 * it executes its startFunc. The parent thread must ensure
133 * that thred->id is set before PR_CreateThread() returns.
134 * Both threads set thred->id without holding a lock. Since
135 * they are writing the same value, this unprotected double
136 * write should be safe.
137 */
138 thred->id = pthread_self();
139
140 #ifdef _PR_NICE_PRIORITY_SCHEDULING 130 #ifdef _PR_NICE_PRIORITY_SCHEDULING
141 /* 131 /*
142 * We need to know the kernel thread ID of each thread in order to 132 * We need to know the kernel thread ID of each thread in order to
143 * set its nice value hence we do it here instead of at creation time. 133 * set its nice value hence we do it here instead of at creation time.
144 */ 134 */
145 tid = gettid(); 135 tid = gettid();
146 errno = 0; 136 errno = 0;
147 rv = getpriority(PRIO_PROCESS, 0); 137 rv = getpriority(PRIO_PROCESS, 0);
148 138
149 /* If we cannot read the main thread's nice value don't try to change the 139 /* If we cannot read the main thread's nice value don't try to change the
150 * new thread's nice value. */ 140 * new thread's nice value. */
151 if (errno == 0) { 141 if (errno == 0) {
152 setpriority(PRIO_PROCESS, tid, 142 setpriority(PRIO_PROCESS, tid,
153 pt_RelativePriority(rv, thred->priority)); 143 pt_RelativePriority(rv, thred->priority));
154 } 144 }
155
156 PR_Lock(pt_book.ml);
157 thred->tid = tid;
158 PR_NotifyAllCondVar(pt_book.cv);
159 PR_Unlock(pt_book.ml);
160 #endif 145 #endif
161 146
162 /* 147 /*
163 ** DCE Threads can't detach during creation, so do it late. 148 ** DCE Threads can't detach during creation, so do it late.
164 ** I would like to do it only here, but that doesn't seem 149 ** I would like to do it only here, but that doesn't seem
165 ** to work. 150 ** to work.
166 */ 151 */
167 #if defined(_PR_DCETHREADS) 152 #if defined(_PR_DCETHREADS)
168 if (detached) 153 if (detached)
169 { 154 {
170 /* pthread_detach() modifies its argument, so we must pass a copy */ 155 /* pthread_detach() modifies its argument, so we must pass a copy */
171 pthread_t self = thred->id; 156 pthread_t self = id;
172 rv = pthread_detach(&self); 157 rv = pthread_detach(&self);
173 PR_ASSERT(0 == rv); 158 PR_ASSERT(0 == rv);
174 } 159 }
175 #endif /* defined(_PR_DCETHREADS) */ 160 #endif /* defined(_PR_DCETHREADS) */
176 161
177 /* Set up the thread stack information */ 162 /* Set up the thread stack information */
178 _PR_InitializeStack(thred->stack); 163 _PR_InitializeStack(thred->stack);
179 164
180 /* 165 /*
181 * Set within the current thread the pointer to our object. 166 * Set within the current thread the pointer to our object.
182 * This object will be deleted when the thread termintates, 167 * This object will be deleted when the thread termintates,
183 * whether in a join or detached (see _PR_InitThreads()). 168 * whether in a join or detached (see _PR_InitThreads()).
184 */ 169 */
185 rv = pthread_setspecific(pt_book.key, thred); 170 rv = pthread_setspecific(pt_book.key, thred);
186 PR_ASSERT(0 == rv); 171 PR_ASSERT(0 == rv);
187 172
188 /* make the thread visible to the rest of the runtime */ 173 /* make the thread visible to the rest of the runtime */
189 PR_Lock(pt_book.ml); 174 PR_Lock(pt_book.ml);
175 /*
176 * Both the parent thread and this new thread set thred->id.
177 * The new thread must ensure that thred->id is set before
178 * it executes its startFunc. The parent thread must ensure
179 * that thred->id is set before PR_CreateThread() returns.
180 * Both threads set thred->id while holding pt_book.ml and
181 * use thred->idSet to ensure thred->id is written only once.
182 */
183 if (!thred->idSet)
184 {
185 thred->id = id;
186 thred->idSet = PR_TRUE;
187 }
188 else
189 {
190 PR_ASSERT(pthread_equal(thred->id, id));
191 }
192
193 #ifdef _PR_NICE_PRIORITY_SCHEDULING
194 thred->tid = tid;
195 PR_NotifyAllCondVar(pt_book.cv);
196 #endif
190 197
191 /* If this is a GCABLE thread, set its state appropriately */ 198 /* If this is a GCABLE thread, set its state appropriately */
192 if (thred->suspend & PT_THREAD_SETGCABLE) 199 if (thred->suspend & PT_THREAD_SETGCABLE)
193 thred->state |= PT_THREAD_GCABLE; 200 thred->state |= PT_THREAD_GCABLE;
194 thred->suspend = 0; 201 thred->suspend = 0;
195 202
196 thred->prev = pt_book.last; 203 thred->prev = pt_book.last;
197 if (pt_book.last) 204 if (pt_book.last)
198 pt_book.last->next = thred; 205 pt_book.last->next = thred;
199 else 206 else
200 pt_book.first = thred; 207 pt_book.first = thred;
201 thred->next = NULL; 208 thred->next = NULL;
202 pt_book.last = thred; 209 pt_book.last = thred;
203 PR_Unlock(pt_book.ml); 210 PR_Unlock(pt_book.ml);
204 211
205 thred->startFunc(thred->arg); /* make visible to the client */ 212 thred->startFunc(thred->arg); /* make visible to the client */
206 213
207 /* unhook the thread from the runtime */ 214 /* unhook the thread from the runtime */
208 PR_Lock(pt_book.ml); 215 PR_Lock(pt_book.ml);
209 /* 216 /*
210 * At this moment, PR_CreateThread() may not have set thred->id yet. 217 * At this moment, PR_CreateThread() may not have set thred->id yet.
211 * It is safe for a detached thread to free thred only after 218 * It is safe for a detached thread to free thred only after
212 * PR_CreateThread() has set thred->id. 219 * PR_CreateThread() has accessed thred->id and thred->idSet.
213 */ 220 */
214 if (detached) 221 if (detached)
215 { 222 {
216 while (!thred->okToDelete) 223 while (!thred->okToDelete)
217 PR_WaitCondVar(pt_book.cv, PR_INTERVAL_NO_TIMEOUT); 224 PR_WaitCondVar(pt_book.cv, PR_INTERVAL_NO_TIMEOUT);
218 } 225 }
219 226
220 if (thred->state & PT_THREAD_SYSTEM) 227 if (thred->state & PT_THREAD_SYSTEM)
221 pt_book.system -= 1; 228 pt_book.system -= 1;
222 else if (--pt_book.user == pt_book.this_many) 229 else if (--pt_book.user == pt_book.this_many)
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 if (!_pr_initialized) return NULL; 273 if (!_pr_initialized) return NULL;
267 274
268 /* PR_NEWZAP must not call PR_GetCurrentThread() */ 275 /* PR_NEWZAP must not call PR_GetCurrentThread() */
269 thred = PR_NEWZAP(PRThread); 276 thred = PR_NEWZAP(PRThread);
270 if (NULL != thred) 277 if (NULL != thred)
271 { 278 {
272 int rv; 279 int rv;
273 280
274 thred->priority = PR_PRIORITY_NORMAL; 281 thred->priority = PR_PRIORITY_NORMAL;
275 thred->id = pthread_self(); 282 thred->id = pthread_self();
283 thred->idSet = PR_TRUE;
276 #ifdef _PR_NICE_PRIORITY_SCHEDULING 284 #ifdef _PR_NICE_PRIORITY_SCHEDULING
277 thred->tid = gettid(); 285 thred->tid = gettid();
278 #endif 286 #endif
279 rv = pthread_setspecific(pt_book.key, thred); 287 rv = pthread_setspecific(pt_book.key, thred);
280 PR_ASSERT(0 == rv); 288 PR_ASSERT(0 == rv);
281 289
282 thred->state = PT_THREAD_GLOBAL | PT_THREAD_FOREIGN; 290 thred->state = PT_THREAD_GLOBAL | PT_THREAD_FOREIGN;
283 PR_Lock(pt_book.ml); 291 PR_Lock(pt_book.ml);
284 292
285 /* then put it into the list */ 293 /* then put it into the list */
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 PR_NotifyAllCondVar(pt_book.cv); 494 PR_NotifyAllCondVar(pt_book.cv);
487 PR_Unlock(pt_book.ml); 495 PR_Unlock(pt_book.ml);
488 496
489 PR_Free(thred->stack); 497 PR_Free(thred->stack);
490 PR_Free(thred); /* all that work ... poof! */ 498 PR_Free(thred); /* all that work ... poof! */
491 PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, oserr); 499 PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, oserr);
492 thred = NULL; /* and for what? */ 500 thred = NULL; /* and for what? */
493 goto done; 501 goto done;
494 } 502 }
495 503
504 PR_Lock(pt_book.ml);
496 /* 505 /*
497 * Both the parent thread and this new thread set thred->id. 506 * Both the parent thread and this new thread set thred->id.
498 * The parent thread must ensure that thred->id is set before 507 * The parent thread must ensure that thred->id is set before
499 * PR_CreateThread() returns. (See comments in _pt_root().) 508 * PR_CreateThread() returns. (See comments in _pt_root().)
500 */ 509 */
501 thred->id = id; 510 if (!thred->idSet)
511 {
512 thred->id = id;
513 thred->idSet = PR_TRUE;
514 }
515 else
516 {
517 PR_ASSERT(pthread_equal(thred->id, id));
518 }
502 519
503 /* 520 /*
504 * If the new thread is detached, tell it that PR_CreateThread() 521 * If the new thread is detached, tell it that PR_CreateThread() has
505 * has set thred->id so it's ok to delete thred. 522 * accessed thred->id and thred->idSet so it's ok to delete thred.
506 */ 523 */
507 if (PR_UNJOINABLE_THREAD == state) 524 if (PR_UNJOINABLE_THREAD == state)
508 { 525 {
509 PR_Lock(pt_book.ml);
510 thred->okToDelete = PR_TRUE; 526 thred->okToDelete = PR_TRUE;
511 PR_NotifyAllCondVar(pt_book.cv); 527 PR_NotifyAllCondVar(pt_book.cv);
512 PR_Unlock(pt_book.ml);
513 } 528 }
529 PR_Unlock(pt_book.ml);
514 } 530 }
515 531
516 done: 532 done:
517 rv = _PT_PTHREAD_ATTR_DESTROY(&tattr); 533 rv = _PT_PTHREAD_ATTR_DESTROY(&tattr);
518 PR_ASSERT(0 == rv); 534 PR_ASSERT(0 == rv);
519 535
520 return thred; 536 return thred;
521 } /* _PR_CreateThread */ 537 } /* _PR_CreateThread */
522 538
523 PR_IMPLEMENT(PRThread*) PR_CreateThread( 539 PR_IMPLEMENT(PRThread*) PR_CreateThread(
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after
933 pt_book.ml = PR_NewLock(); 949 pt_book.ml = PR_NewLock();
934 PR_ASSERT(NULL != pt_book.ml); 950 PR_ASSERT(NULL != pt_book.ml);
935 pt_book.cv = PR_NewCondVar(pt_book.ml); 951 pt_book.cv = PR_NewCondVar(pt_book.ml);
936 PR_ASSERT(NULL != pt_book.cv); 952 PR_ASSERT(NULL != pt_book.cv);
937 thred = PR_NEWZAP(PRThread); 953 thred = PR_NEWZAP(PRThread);
938 PR_ASSERT(NULL != thred); 954 PR_ASSERT(NULL != thred);
939 thred->arg = NULL; 955 thred->arg = NULL;
940 thred->startFunc = NULL; 956 thred->startFunc = NULL;
941 thred->priority = priority; 957 thred->priority = priority;
942 thred->id = pthread_self(); 958 thred->id = pthread_self();
959 thred->idSet = PR_TRUE;
943 #ifdef _PR_NICE_PRIORITY_SCHEDULING 960 #ifdef _PR_NICE_PRIORITY_SCHEDULING
944 thred->tid = gettid(); 961 thred->tid = gettid();
945 #endif 962 #endif
946 963
947 thred->state = (PT_THREAD_DETACHED | PT_THREAD_PRIMORD); 964 thred->state = (PT_THREAD_DETACHED | PT_THREAD_PRIMORD);
948 if (PR_SYSTEM_THREAD == type) 965 if (PR_SYSTEM_THREAD == type)
949 { 966 {
950 thred->state |= PT_THREAD_SYSTEM; 967 thred->state |= PT_THREAD_SYSTEM;
951 pt_book.system += 1; 968 pt_book.system += 1;
952 pt_book.this_many = 0; 969 pt_book.this_many = 0;
(...skipping 835 matching lines...) Expand 10 before | Expand all | Expand 10 after
1788 PR_IMPLEMENT(const char *) PR_GetThreadName(const PRThread *thread) 1805 PR_IMPLEMENT(const char *) PR_GetThreadName(const PRThread *thread)
1789 { 1806 {
1790 if (!thread) 1807 if (!thread)
1791 return NULL; 1808 return NULL;
1792 return thread->name; 1809 return thread->name;
1793 } 1810 }
1794 1811
1795 #endif /* defined(_PR_PTHREADS) || defined(_PR_DCETHREADS) */ 1812 #endif /* defined(_PR_PTHREADS) || defined(_PR_DCETHREADS) */
1796 1813
1797 /* ptthread.c */ 1814 /* ptthread.c */
OLDNEW
« no previous file with comments | « nspr/pr/src/pthreads/ptsynch.c ('k') | nspr/pr/src/threads/combined/prucv.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698