Mercurial > trustbridge > nss-cmake-static
comparison nss/lib/util/nssilock.c @ 0:1e5118fa0cb1
This is NSS with a Cmake Buildsyste
To compile a static NSS library for Windows we've used the
Chromium-NSS fork and added a Cmake buildsystem to compile
it statically for Windows. See README.chromium for chromium
changes and README.trustbridge for our modifications.
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Mon, 28 Jul 2014 10:47:06 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:1e5118fa0cb1 |
---|---|
1 /* This Source Code Form is subject to the terms of the Mozilla Public | |
2 * License, v. 2.0. If a copy of the MPL was not distributed with this | |
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |
4 | |
5 /* | |
6 * nssilock.c - NSS lock instrumentation wrapper functions | |
7 * | |
8 * NOTE - These are not public interfaces | |
9 * | |
10 * Implementation Notes: | |
11 * I've tried to make the instrumentation relatively non-intrusive. | |
12 * To do this, I have used a single PR_LOG() call in each | |
13 * instrumented function. There's room for improvement. | |
14 * | |
15 * | |
16 */ | |
17 | |
18 #include "prinit.h" | |
19 #include "prerror.h" | |
20 #include "prlock.h" | |
21 #include "prmem.h" | |
22 #include "prenv.h" | |
23 #include "prcvar.h" | |
24 #include "prio.h" | |
25 | |
26 #if defined(NEED_NSS_ILOCK) | |
27 #include "prlog.h" | |
28 #include "nssilock.h" | |
29 | |
30 /* | |
31 ** Declare the instrumented PZLock | |
32 */ | |
33 struct pzlock_s { | |
34 PRLock *lock; /* the PZLock to be instrumented */ | |
35 PRIntervalTime time; /* timestamp when the lock was aquired */ | |
36 nssILockType ltype; | |
37 }; | |
38 | |
39 /* | |
40 ** Declare the instrumented PZMonitor | |
41 */ | |
42 struct pzmonitor_s { | |
43 PRMonitor *mon; /* the PZMonitor to be instrumented */ | |
44 PRIntervalTime time; /* timestamp when the monitor was aquired */ | |
45 nssILockType ltype; | |
46 }; | |
47 | |
48 /* | |
49 ** Declare the instrumented PZCondVar | |
50 */ | |
51 struct pzcondvar_s { | |
52 PRCondVar *cvar; /* the PZCondVar to be instrumented */ | |
53 nssILockType ltype; | |
54 }; | |
55 | |
56 | |
57 /* | |
58 ** Define a CallOnce type to ensure serialized self-initialization | |
59 */ | |
60 static PRCallOnceType coNssILock; /* CallOnce type */ | |
61 static PRIntn nssILockInitialized; /* initialization done when 1 */ | |
62 static PRLogModuleInfo *nssILog; /* Log instrumentation to this handle */ | |
63 | |
64 | |
65 #define NUM_TT_ENTRIES 6000000 | |
66 static PRInt32 traceIndex = -1; /* index into trace table */ | |
67 static struct pzTrace_s *tt; /* pointer to trace table */ | |
68 static PRInt32 ttBufSize = (NUM_TT_ENTRIES * sizeof(struct pzTrace_s )); | |
69 static PRCondVar *ttCVar; | |
70 static PRLock *ttLock; | |
71 static PRFileDesc *ttfd; /* trace table file */ | |
72 | |
73 /* | |
74 ** Vtrace() -- Trace events, write events to external media | |
75 ** | |
76 ** Vtrace() records traced events in an in-memory trace table | |
77 ** when the trace table fills, Vtrace writes the entire table | |
78 ** to a file. | |
79 ** | |
80 ** data can be lost! | |
81 ** | |
82 */ | |
83 static void Vtrace( | |
84 nssILockOp op, | |
85 nssILockType ltype, | |
86 PRIntervalTime callTime, | |
87 PRIntervalTime heldTime, | |
88 void *lock, | |
89 PRIntn line, | |
90 char *file | |
91 ) { | |
92 PRInt32 idx; | |
93 struct pzTrace_s *tp; | |
94 | |
95 RetryTrace: | |
96 idx = PR_ATOMIC_INCREMENT( &traceIndex ); | |
97 while( NUM_TT_ENTRIES <= idx || op == FlushTT ) { | |
98 if( NUM_TT_ENTRIES == idx || op == FlushTT ) { | |
99 int writeSize = idx * sizeof(struct pzTrace_s); | |
100 PR_Lock(ttLock); | |
101 PR_Write( ttfd, tt, writeSize ); | |
102 traceIndex = -1; | |
103 PR_NotifyAllCondVar( ttCVar ); | |
104 PR_Unlock(ttLock); | |
105 goto RetryTrace; | |
106 } else { | |
107 PR_Lock(ttLock); | |
108 while( NUM_TT_ENTRIES < idx ) | |
109 PR_WaitCondVar(ttCVar, PR_INTERVAL_NO_WAIT); | |
110 PR_Unlock(ttLock); | |
111 goto RetryTrace; | |
112 } | |
113 } /* end while() */ | |
114 | |
115 /* create the trace entry */ | |
116 tp = tt + idx; | |
117 tp->threadID = PR_GetThreadID(PR_GetCurrentThread()); | |
118 tp->op = op; | |
119 tp->ltype = ltype; | |
120 tp->callTime = callTime; | |
121 tp->heldTime = heldTime; | |
122 tp->lock = lock; | |
123 tp ->line = line; | |
124 strcpy(tp->file, file ); | |
125 return; | |
126 } /* --- end Vtrace() --- */ | |
127 | |
128 /* | |
129 ** pz_TraceFlush() -- Force trace table write to file | |
130 ** | |
131 */ | |
132 extern void pz_TraceFlush( void ) | |
133 { | |
134 Vtrace( FlushTT, nssILockSelfServ, 0, 0, NULL, 0, "" ); | |
135 return; | |
136 } /* --- end pz_TraceFlush() --- */ | |
137 | |
138 /* | |
139 ** nssILockInit() -- Initialization for nssilock | |
140 ** | |
141 ** This function is called from the CallOnce mechanism. | |
142 */ | |
143 static PRStatus | |
144 nssILockInit( void ) | |
145 { | |
146 int i; | |
147 nssILockInitialized = 1; | |
148 | |
149 /* new log module */ | |
150 nssILog = PR_NewLogModule("nssilock"); | |
151 if ( NULL == nssILog ) { | |
152 return(PR_FAILURE); | |
153 } | |
154 | |
155 tt = PR_Calloc( NUM_TT_ENTRIES, sizeof(struct pzTrace_s)); | |
156 if (NULL == tt ) { | |
157 fprintf(stderr, "nssilock: can't allocate trace table\n"); | |
158 exit(1); | |
159 } | |
160 | |
161 ttfd = PR_Open( "xxxTTLog", PR_CREATE_FILE | PR_WRONLY, 0666 ); | |
162 if ( NULL == ttfd ) { | |
163 fprintf( stderr, "Oh Drat! Can't open 'xxxTTLog'\n"); | |
164 exit(1); | |
165 } | |
166 | |
167 ttLock = PR_NewLock(); | |
168 ttCVar = PR_NewCondVar(ttLock); | |
169 | |
170 return(PR_SUCCESS); | |
171 } /* --- end nssILockInit() --- */ | |
172 | |
173 extern PZLock * pz_NewLock( | |
174 nssILockType ltype, | |
175 char *file, | |
176 PRIntn line ) | |
177 { | |
178 PRStatus rc; | |
179 PZLock *lock; | |
180 | |
181 /* Self Initialize the nssILock feature */ | |
182 if (!nssILockInitialized) { | |
183 rc = PR_CallOnce( &coNssILock, nssILockInit ); | |
184 if ( PR_FAILURE == rc ) { | |
185 PR_SetError( PR_UNKNOWN_ERROR, 0 ); | |
186 return( NULL ); | |
187 } | |
188 } | |
189 | |
190 lock = PR_NEWZAP( PZLock ); | |
191 if ( NULL != lock ) { | |
192 lock->ltype = ltype; | |
193 lock->lock = PR_NewLock(); | |
194 if ( NULL == lock->lock ) { | |
195 PR_DELETE( lock ); | |
196 PORT_SetError(SEC_ERROR_NO_MEMORY); | |
197 } | |
198 } else { | |
199 PORT_SetError(SEC_ERROR_NO_MEMORY); | |
200 } | |
201 | |
202 Vtrace( NewLock, ltype, 0, 0, lock, line, file ); | |
203 return(lock); | |
204 } /* --- end pz_NewLock() --- */ | |
205 | |
206 extern void | |
207 pz_Lock( | |
208 PZLock *lock, | |
209 char *file, | |
210 PRIntn line | |
211 ) | |
212 { | |
213 PRIntervalTime callTime; | |
214 | |
215 callTime = PR_IntervalNow(); | |
216 PR_Lock( lock->lock ); | |
217 lock->time = PR_IntervalNow(); | |
218 callTime = lock->time - callTime; | |
219 | |
220 Vtrace( Lock, lock->ltype, callTime, 0, lock, line, file ); | |
221 return; | |
222 } /* --- end pz_Lock() --- */ | |
223 | |
224 extern PRStatus | |
225 pz_Unlock( | |
226 PZLock *lock, | |
227 char *file, | |
228 PRIntn line | |
229 ) | |
230 { | |
231 PRStatus rc; | |
232 PRIntervalTime callTime, now, heldTime; | |
233 | |
234 callTime = PR_IntervalNow(); | |
235 rc = PR_Unlock( lock->lock ); | |
236 now = PR_IntervalNow(); | |
237 callTime = now - callTime; | |
238 heldTime = now - lock->time; | |
239 Vtrace( Unlock, lock->ltype, callTime, heldTime, lock, line, file ); | |
240 return( rc ); | |
241 } /* --- end pz_Unlock() --- */ | |
242 | |
243 extern void | |
244 pz_DestroyLock( | |
245 PZLock *lock, | |
246 char *file, | |
247 PRIntn line | |
248 ) | |
249 { | |
250 Vtrace( DestroyLock, lock->ltype, 0, 0, lock, line, file ); | |
251 PR_DestroyLock( lock->lock ); | |
252 PR_DELETE( lock ); | |
253 return; | |
254 } /* --- end pz_DestroyLock() --- */ | |
255 | |
256 | |
257 | |
258 extern PZCondVar * | |
259 pz_NewCondVar( | |
260 PZLock *lock, | |
261 char *file, | |
262 PRIntn line | |
263 ) | |
264 { | |
265 PZCondVar *cvar; | |
266 | |
267 cvar = PR_NEWZAP( PZCondVar ); | |
268 if ( NULL == cvar ) { | |
269 PORT_SetError(SEC_ERROR_NO_MEMORY); | |
270 } else { | |
271 cvar->ltype = lock->ltype; | |
272 cvar->cvar = PR_NewCondVar( lock->lock ); | |
273 if ( NULL == cvar->cvar ) { | |
274 PR_DELETE( cvar ); | |
275 PORT_SetError(SEC_ERROR_NO_MEMORY); | |
276 } | |
277 | |
278 } | |
279 Vtrace( NewCondVar, lock->ltype, 0, 0, cvar, line, file ); | |
280 return( cvar ); | |
281 } /* --- end pz_NewCondVar() --- */ | |
282 | |
283 extern void | |
284 pz_DestroyCondVar( | |
285 PZCondVar *cvar, | |
286 char *file, | |
287 PRIntn line | |
288 ) | |
289 { | |
290 Vtrace( DestroyCondVar, cvar->ltype, 0, 0, cvar, line, file ); | |
291 PR_DestroyCondVar( cvar->cvar ); | |
292 PR_DELETE( cvar ); | |
293 } /* --- end pz_DestroyCondVar() --- */ | |
294 | |
295 extern PRStatus | |
296 pz_WaitCondVar( | |
297 PZCondVar *cvar, | |
298 PRIntervalTime timeout, | |
299 char *file, | |
300 PRIntn line | |
301 ) | |
302 { | |
303 PRStatus rc; | |
304 PRIntervalTime callTime; | |
305 | |
306 callTime = PR_IntervalNow(); | |
307 rc = PR_WaitCondVar( cvar->cvar, timeout ); | |
308 callTime = PR_IntervalNow() - callTime; | |
309 | |
310 Vtrace( WaitCondVar, cvar->ltype, callTime, 0, cvar, line, file ); | |
311 return(rc); | |
312 } /* --- end pz_WaitCondVar() --- */ | |
313 | |
314 extern PRStatus | |
315 pz_NotifyCondVar( | |
316 PZCondVar *cvar, | |
317 char *file, | |
318 PRIntn line | |
319 ) | |
320 { | |
321 PRStatus rc; | |
322 | |
323 rc = PR_NotifyCondVar( cvar->cvar ); | |
324 | |
325 Vtrace( NotifyCondVar, cvar->ltype, 0, 0, cvar, line, file ); | |
326 return(rc); | |
327 } /* --- end pz_NotifyCondVar() --- */ | |
328 | |
329 extern PRStatus | |
330 pz_NotifyAllCondVar( | |
331 PZCondVar *cvar, | |
332 char *file, | |
333 PRIntn line | |
334 ) | |
335 { | |
336 PRStatus rc; | |
337 | |
338 rc = PR_NotifyAllCondVar( cvar->cvar ); | |
339 | |
340 Vtrace( NotifyAllCondVar, cvar->ltype, 0, 0, cvar, line, file ); | |
341 return(rc); | |
342 } /* --- end pz_NotifyAllCondVar() --- */ | |
343 | |
344 extern PZMonitor * | |
345 pz_NewMonitor( | |
346 nssILockType ltype, | |
347 char *file, | |
348 PRIntn line | |
349 ) | |
350 { | |
351 PRStatus rc; | |
352 PZMonitor *mon; | |
353 | |
354 /* Self Initialize the nssILock feature */ | |
355 if (!nssILockInitialized) { | |
356 rc = PR_CallOnce( &coNssILock, nssILockInit ); | |
357 if ( PR_FAILURE == rc ) { | |
358 PR_SetError( PR_UNKNOWN_ERROR, 0 ); | |
359 return( NULL ); | |
360 } | |
361 } | |
362 | |
363 mon = PR_NEWZAP( PZMonitor ); | |
364 if ( NULL != mon ) { | |
365 mon->ltype = ltype; | |
366 mon->mon = PR_NewMonitor(); | |
367 if ( NULL == mon->mon ) { | |
368 PR_DELETE( mon ); | |
369 PORT_SetError(SEC_ERROR_NO_MEMORY); | |
370 } | |
371 } else { | |
372 PORT_SetError(SEC_ERROR_NO_MEMORY); | |
373 } | |
374 | |
375 Vtrace( NewMonitor, ltype, 0, 0, mon, line, file ); | |
376 return(mon); | |
377 } /* --- end pz_NewMonitor() --- */ | |
378 | |
379 extern void | |
380 pz_DestroyMonitor( | |
381 PZMonitor *mon, | |
382 char *file, | |
383 PRIntn line | |
384 ) | |
385 { | |
386 Vtrace( DestroyMonitor, mon->ltype, 0, 0, mon, line, file ); | |
387 PR_DestroyMonitor( mon->mon ); | |
388 PR_DELETE( mon ); | |
389 return; | |
390 } /* --- end pz_DestroyMonitor() --- */ | |
391 | |
392 extern void | |
393 pz_EnterMonitor( | |
394 PZMonitor *mon, | |
395 char *file, | |
396 PRIntn line | |
397 ) | |
398 { | |
399 PRIntervalTime callTime, now; | |
400 | |
401 callTime = PR_IntervalNow(); | |
402 PR_EnterMonitor( mon->mon ); | |
403 now = PR_IntervalNow(); | |
404 callTime = now - callTime; | |
405 if ( PR_GetMonitorEntryCount(mon->mon) == 1 ) { | |
406 mon->time = now; | |
407 } | |
408 Vtrace( EnterMonitor, mon->ltype, callTime, 0, mon, line, file ); | |
409 return; | |
410 } /* --- end pz_EnterMonitor() --- */ | |
411 | |
412 extern PRStatus | |
413 pz_ExitMonitor( | |
414 PZMonitor *mon, | |
415 char *file, | |
416 PRIntn line | |
417 ) | |
418 { | |
419 PRStatus rc; | |
420 PRIntervalTime callTime, now, heldTime; | |
421 PRIntn mec = PR_GetMonitorEntryCount( mon->mon ); | |
422 | |
423 heldTime = (PRIntervalTime)-1; | |
424 callTime = PR_IntervalNow(); | |
425 rc = PR_ExitMonitor( mon->mon ); | |
426 now = PR_IntervalNow(); | |
427 callTime = now - callTime; | |
428 if ( mec == 1 ) | |
429 heldTime = now - mon->time; | |
430 Vtrace( ExitMonitor, mon->ltype, callTime, heldTime, mon, line, file ); | |
431 return( rc ); | |
432 } /* --- end pz_ExitMonitor() --- */ | |
433 | |
434 extern PRIntn | |
435 pz_GetMonitorEntryCount( | |
436 PZMonitor *mon, | |
437 char *file, | |
438 PRIntn line | |
439 ) | |
440 { | |
441 return( PR_GetMonitorEntryCount(mon->mon)); | |
442 } /* --- end pz_GetMonitorEntryCount() --- */ | |
443 | |
444 | |
445 extern PRStatus | |
446 pz_Wait( | |
447 PZMonitor *mon, | |
448 PRIntervalTime ticks, | |
449 char *file, | |
450 PRIntn line | |
451 ) | |
452 { | |
453 PRStatus rc; | |
454 PRIntervalTime callTime; | |
455 | |
456 callTime = PR_IntervalNow(); | |
457 rc = PR_Wait( mon->mon, ticks ); | |
458 callTime = PR_IntervalNow() - callTime; | |
459 Vtrace( Wait, mon->ltype, callTime, 0, mon, line, file ); | |
460 return( rc ); | |
461 } /* --- end pz_Wait() --- */ | |
462 | |
463 extern PRStatus | |
464 pz_Notify( | |
465 PZMonitor *mon, | |
466 char *file, | |
467 PRIntn line | |
468 ) | |
469 { | |
470 PRStatus rc; | |
471 PRIntervalTime callTime; | |
472 | |
473 callTime = PR_IntervalNow(); | |
474 rc = PR_Notify( mon->mon ); | |
475 callTime = PR_IntervalNow() - callTime; | |
476 Vtrace( Notify, mon->ltype, callTime, 0, mon, line, file ); | |
477 return( rc ); | |
478 } /* --- end pz_Notify() --- */ | |
479 | |
480 extern PRStatus | |
481 pz_NotifyAll( | |
482 PZMonitor *mon, | |
483 char *file, | |
484 PRIntn line | |
485 ) | |
486 { | |
487 PRStatus rc; | |
488 PRIntervalTime callTime; | |
489 | |
490 callTime = PR_IntervalNow(); | |
491 rc = PR_NotifyAll( mon->mon ); | |
492 callTime = PR_IntervalNow() - callTime; | |
493 Vtrace( NotifyAll, mon->ltype, callTime, 0, mon, line, file ); | |
494 return( rc ); | |
495 } /* --- end pz_NotifyAll() --- */ | |
496 | |
497 #endif /* NEED_NSS_ILOCK */ | |
498 /* --- end nssilock.c --------------------------------- */ |