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

Side by Side Diff: nspr/pr/src/threads/prcthr.c

Issue 2078763002: Delete bundled copy of NSS and replace with README. (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/nss@master
Patch Set: Delete bundled copy of NSS and replace with README. Created 4 years, 6 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
« no previous file with comments | « nspr/pr/src/threads/prcmon.c ('k') | nspr/pr/src/threads/prdump.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
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/. */
5
6 #include "primpl.h"
7
8 #if defined(WIN95)
9 /*
10 ** Some local variables report warnings on Win95 because the code paths
11 ** using them are conditioned on HAVE_CUSTOME_USER_THREADS.
12 ** The pragma suppresses the warning.
13 **
14 */
15 #pragma warning(disable : 4101)
16 #endif
17
18
19 extern PRLock *_pr_sleeplock; /* allocated and initialized in prinit */
20 /*
21 ** Routines common to both native and user threads.
22 **
23 **
24 ** Clean up a thread object, releasing all of the attached data. Do not
25 ** free the object itself (it may not have been malloc'd)
26 */
27 void _PR_CleanupThread(PRThread *thread)
28 {
29 /* Free up per-thread-data */
30 _PR_DestroyThreadPrivate(thread);
31
32 /* Free any thread dump procs */
33 if (thread->dumpArg) {
34 PR_DELETE(thread->dumpArg);
35 }
36 thread->dump = 0;
37
38 PR_DELETE(thread->name);
39 PR_DELETE(thread->errorString);
40 thread->errorStringSize = 0;
41 thread->errorStringLength = 0;
42 thread->environment = NULL;
43 }
44
45 PR_IMPLEMENT(PRStatus) PR_Yield()
46 {
47 static PRBool warning = PR_TRUE;
48 if (warning) warning = _PR_Obsolete(
49 "PR_Yield()", "PR_Sleep(PR_INTERVAL_NO_WAIT)");
50 return (PR_Sleep(PR_INTERVAL_NO_WAIT));
51 }
52
53 /*
54 ** Make the current thread sleep until "timeout" ticks amount of time
55 ** has expired. If "timeout" is PR_INTERVAL_NO_WAIT then the call is
56 ** equivalent to a yield. Waiting for an infinite amount of time is
57 ** allowed in the expectation that another thread will interrupt().
58 **
59 ** A single lock is used for all threads calling sleep. Each caller
60 ** does get its own condition variable since each is expected to have
61 ** a unique 'timeout'.
62 */
63 PR_IMPLEMENT(PRStatus) PR_Sleep(PRIntervalTime timeout)
64 {
65 PRStatus rv = PR_SUCCESS;
66
67 if (!_pr_initialized) _PR_ImplicitInitialization();
68
69 if (PR_INTERVAL_NO_WAIT == timeout)
70 {
71 /*
72 ** This is a simple yield, nothing more, nothing less.
73 */
74 PRIntn is;
75 PRThread *me = PR_GetCurrentThread();
76 PRUintn pri = me->priority;
77 _PRCPU *cpu = _PR_MD_CURRENT_CPU();
78
79 if ( _PR_IS_NATIVE_THREAD(me) ) _PR_MD_YIELD();
80 else
81 {
82 _PR_INTSOFF(is);
83 _PR_RUNQ_LOCK(cpu);
84 if (_PR_RUNQREADYMASK(cpu) >> pri) {
85 me->cpu = cpu;
86 me->state = _PR_RUNNABLE;
87 _PR_ADD_RUNQ(me, cpu, pri);
88 _PR_RUNQ_UNLOCK(cpu);
89
90 PR_LOG(_pr_sched_lm, PR_LOG_MIN, ("PR_Yield: yielding"));
91 _PR_MD_SWITCH_CONTEXT(me);
92 PR_LOG(_pr_sched_lm, PR_LOG_MIN, ("PR_Yield: done"));
93
94 _PR_FAST_INTSON(is);
95 }
96 else
97 {
98 _PR_RUNQ_UNLOCK(cpu);
99 _PR_INTSON(is);
100 }
101 }
102 }
103 else
104 {
105 /*
106 ** This is waiting for some finite period of time.
107 ** A thread in this state is interruptible (PR_Interrupt()),
108 ** but the lock and cvar used are local to the implementation
109 ** and not visible to the caller, therefore not notifiable.
110 */
111 PRCondVar *cv;
112 PRIntervalTime timein;
113
114 timein = PR_IntervalNow();
115 cv = PR_NewCondVar(_pr_sleeplock);
116 PR_ASSERT(cv != NULL);
117 PR_Lock(_pr_sleeplock);
118 do
119 {
120 PRIntervalTime delta = PR_IntervalNow() - timein;
121 if (delta > timeout) break;
122 rv = PR_WaitCondVar(cv, timeout - delta);
123 } while (rv == PR_SUCCESS);
124 PR_Unlock(_pr_sleeplock);
125 PR_DestroyCondVar(cv);
126 }
127 return rv;
128 }
129
130 PR_IMPLEMENT(PRUint32) PR_GetThreadID(PRThread *thread)
131 {
132 return thread->id;
133 }
134
135 PR_IMPLEMENT(PRThreadPriority) PR_GetThreadPriority(const PRThread *thread)
136 {
137 return (PRThreadPriority) thread->priority;
138 }
139
140 PR_IMPLEMENT(PRThread *) PR_GetCurrentThread()
141 {
142 if (!_pr_initialized) _PR_ImplicitInitialization();
143 return _PR_MD_CURRENT_THREAD();
144 }
145
146 /*
147 ** Set the interrupt flag for a thread. The thread will be unable to
148 ** block in i/o functions when this happens. Also, any PR_Wait's in
149 ** progress will be undone. The interrupt remains in force until
150 ** PR_ClearInterrupt is called.
151 */
152 PR_IMPLEMENT(PRStatus) PR_Interrupt(PRThread *thread)
153 {
154 #ifdef _PR_GLOBAL_THREADS_ONLY
155 PRCondVar *victim;
156
157 _PR_THREAD_LOCK(thread);
158 thread->flags |= _PR_INTERRUPT;
159 victim = thread->wait.cvar;
160 _PR_THREAD_UNLOCK(thread);
161 if ((NULL != victim) && (!(thread->flags & _PR_INTERRUPT_BLOCKED))) {
162 int haveLock = (victim->lock->owner == _PR_MD_CURRENT_THREAD());
163
164 if (!haveLock) PR_Lock(victim->lock);
165 PR_NotifyAllCondVar(victim);
166 if (!haveLock) PR_Unlock(victim->lock);
167 }
168 return PR_SUCCESS;
169 #else /* ! _PR_GLOBAL_THREADS_ONLY */
170 PRIntn is;
171 PRThread *me = _PR_MD_CURRENT_THREAD();
172
173 if (!_PR_IS_NATIVE_THREAD(me))
174 _PR_INTSOFF(is);
175
176 _PR_THREAD_LOCK(thread);
177 thread->flags |= _PR_INTERRUPT;
178 switch (thread->state) {
179 case _PR_COND_WAIT:
180 /*
181 * call is made with thread locked;
182 * on return lock is released
183 */
184 if (!(thread->flags & _PR_INTERR UPT_BLOCKED))
185 _PR_NotifyLockedThread(thread);
186 break;
187 case _PR_IO_WAIT:
188 /*
189 * Need to hold the thread lock when calling
190 * _PR_Unblock_IO_Wait(). On return lock is
191 * released.
192 */
193 #if defined(XP_UNIX) || defined(WINNT) || defined(WIN16)
194 if (!(thread->flags & _PR_INTERR UPT_BLOCKED))
195 _PR_Unblock_IO_Wait(thread);
196 #else
197 _PR_THREAD_UNLOCK(thread);
198 #endif
199 break;
200 case _PR_RUNNING:
201 case _PR_RUNNABLE:
202 case _PR_LOCK_WAIT:
203 default:
204 _PR_THREAD_UNLOCK(thread);
205 break;
206 }
207 if (!_PR_IS_NATIVE_THREAD(me))
208 _PR_INTSON(is);
209 return PR_SUCCESS;
210 #endif /* _PR_GLOBAL_THREADS_ONLY */
211 }
212
213 /*
214 ** Clear the interrupt flag for self.
215 */
216 PR_IMPLEMENT(void) PR_ClearInterrupt()
217 {
218 PRIntn is;
219 PRThread *me = _PR_MD_CURRENT_THREAD();
220
221 if ( !_PR_IS_NATIVE_THREAD(me)) _PR_INTSOFF(is);
222 _PR_THREAD_LOCK(me);
223 me->flags &= ~_PR_INTERRUPT;
224 _PR_THREAD_UNLOCK(me);
225 if ( !_PR_IS_NATIVE_THREAD(me)) _PR_INTSON(is);
226 }
227
228 PR_IMPLEMENT(void) PR_BlockInterrupt()
229 {
230 PRIntn is;
231 PRThread *me = _PR_MD_CURRENT_THREAD();
232
233 if ( !_PR_IS_NATIVE_THREAD(me)) _PR_INTSOFF(is);
234 _PR_THREAD_LOCK(me);
235 _PR_THREAD_BLOCK_INTERRUPT(me);
236 _PR_THREAD_UNLOCK(me);
237 if ( !_PR_IS_NATIVE_THREAD(me)) _PR_INTSON(is);
238 } /* PR_BlockInterrupt */
239
240 PR_IMPLEMENT(void) PR_UnblockInterrupt()
241 {
242 PRIntn is;
243 PRThread *me = _PR_MD_CURRENT_THREAD();
244
245 if ( !_PR_IS_NATIVE_THREAD(me)) _PR_INTSOFF(is);
246 _PR_THREAD_LOCK(me);
247 _PR_THREAD_UNBLOCK_INTERRUPT(me);
248 _PR_THREAD_UNLOCK(me);
249 if ( !_PR_IS_NATIVE_THREAD(me)) _PR_INTSON(is);
250 } /* PR_UnblockInterrupt */
251
252 /*
253 ** Return the thread stack pointer of the given thread.
254 */
255 PR_IMPLEMENT(void *) PR_GetSP(PRThread *thread)
256 {
257 return (void *)_PR_MD_GET_SP(thread);
258 }
259
260 PR_IMPLEMENT(void*) GetExecutionEnvironment(PRThread *thread)
261 {
262 return thread->environment;
263 }
264
265 PR_IMPLEMENT(void) SetExecutionEnvironment(PRThread *thread, void *env)
266 {
267 thread->environment = env;
268 }
269
270
271 PR_IMPLEMENT(PRInt32) PR_GetThreadAffinityMask(PRThread *thread, PRUint32 *mask)
272 {
273 #ifdef HAVE_THREAD_AFFINITY
274 return _PR_MD_GETTHREADAFFINITYMASK(thread, mask);
275 #else
276 return 0;
277 #endif
278 }
279
280 PR_IMPLEMENT(PRInt32) PR_SetThreadAffinityMask(PRThread *thread, PRUint32 mask )
281 {
282 #ifdef HAVE_THREAD_AFFINITY
283 #ifndef IRIX
284 return _PR_MD_SETTHREADAFFINITYMASK(thread, mask);
285 #else
286 return 0;
287 #endif
288 #else
289 return 0;
290 #endif
291 }
292
293 /* This call is thread unsafe if another thread is calling SetConcurrency()
294 */
295 PR_IMPLEMENT(PRInt32) PR_SetCPUAffinityMask(PRUint32 mask)
296 {
297 #ifdef HAVE_THREAD_AFFINITY
298 PRCList *qp;
299 extern PRUint32 _pr_cpu_affinity_mask;
300
301 if (!_pr_initialized) _PR_ImplicitInitialization();
302
303 _pr_cpu_affinity_mask = mask;
304
305 qp = _PR_CPUQ().next;
306 while(qp != &_PR_CPUQ()) {
307 _PRCPU *cpu;
308
309 cpu = _PR_CPU_PTR(qp);
310 PR_SetThreadAffinityMask(cpu->thread, mask);
311
312 qp = qp->next;
313 }
314 #endif
315
316 return 0;
317 }
318
319 PRUint32 _pr_recycleThreads = 0;
320 PR_IMPLEMENT(void) PR_SetThreadRecycleMode(PRUint32 count)
321 {
322 _pr_recycleThreads = count;
323 }
324
325 PR_IMPLEMENT(PRThread*) PR_CreateThreadGCAble(PRThreadType type,
326 void (*start)(void *arg),
327 void *arg,
328 PRThreadPriority priority,
329 PRThreadScope scope,
330 PRThreadState state,
331 PRUint32 stackSize)
332 {
333 return _PR_CreateThread(type, start, arg, priority, scope, state,
334 stackSize, _PR_GCABLE_THREAD);
335 }
336
337 #ifdef SOLARIS
338 PR_IMPLEMENT(PRThread*) PR_CreateThreadBound(PRThreadType type,
339 void (*start)(void *arg),
340 void *arg,
341 PRUintn priority,
342 PRThreadScope scope,
343 PRThreadState state,
344 PRUint32 stackSize)
345 {
346 return _PR_CreateThread(type, start, arg, priority, scope, state,
347 stackSize, _PR_BOUND_THREAD);
348 }
349 #endif
350
351
352 PR_IMPLEMENT(PRThread*) PR_AttachThreadGCAble(
353 PRThreadType type, PRThreadPriority priority, PRThreadStack *stack)
354 {
355 /* $$$$ not sure how to finese this one */
356 PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
357 return NULL;
358 }
359
360 PR_IMPLEMENT(void) PR_SetThreadGCAble()
361 {
362 if (!_pr_initialized) _PR_ImplicitInitialization();
363 PR_Lock(_pr_activeLock);
364 _PR_MD_CURRENT_THREAD()->flags |= _PR_GCABLE_THREAD;
365 PR_Unlock(_pr_activeLock);
366 }
367
368 PR_IMPLEMENT(void) PR_ClearThreadGCAble()
369 {
370 if (!_pr_initialized) _PR_ImplicitInitialization();
371 PR_Lock(_pr_activeLock);
372 _PR_MD_CURRENT_THREAD()->flags &= (~_PR_GCABLE_THREAD);
373 PR_Unlock(_pr_activeLock);
374 }
375
376 PR_IMPLEMENT(PRThreadScope) PR_GetThreadScope(const PRThread *thread)
377 {
378 if (!_pr_initialized) _PR_ImplicitInitialization();
379
380 if (_PR_IS_NATIVE_THREAD(thread)) {
381 return (thread->flags & _PR_BOUND_THREAD) ? PR_GLOBAL_BOUND_THREAD :
382 PR_GLOBAL_THREAD;
383 } else
384 return PR_LOCAL_THREAD;
385 }
386
387 PR_IMPLEMENT(PRThreadType) PR_GetThreadType(const PRThread *thread)
388 {
389 return (thread->flags & _PR_SYSTEM) ? PR_SYSTEM_THREAD : PR_USER_THREAD;
390 }
391
392 PR_IMPLEMENT(PRThreadState) PR_GetThreadState(const PRThread *thread)
393 {
394 return (NULL == thread->term) ? PR_UNJOINABLE_THREAD : PR_JOINABLE_THREAD;
395 } /* PR_GetThreadState */
OLDNEW
« no previous file with comments | « nspr/pr/src/threads/prcmon.c ('k') | nspr/pr/src/threads/prdump.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698