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 --------------------------------- */
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)