494
#ifdef DEBUG_THREADS_STATS
495
fflush(stats_logfile);
496
/* XXX Should close if not stderr, in case unloading library but
500
487
krb5int_fini_fac();
503
#ifdef DEBUG_THREADS_STATS
505
k5_mutex_lock_update_stats(k5_debug_mutex_stats *m,
506
k5_mutex_stats_tmp startwait)
509
k5_debug_timediff_t tdiff, tdiff2;
511
now = get_current_time();
512
(void) krb5int_call_thread_support_init();
514
m->time_acquired = now;
515
tdiff = timediff(now, startwait);
516
tdiff2 = tdiff * tdiff;
517
if (m->count == 1 || m->lockwait.valmin > tdiff)
518
m->lockwait.valmin = tdiff;
519
if (m->count == 1 || m->lockwait.valmax < tdiff)
520
m->lockwait.valmax = tdiff;
521
m->lockwait.valsum += tdiff;
522
m->lockwait.valsqsum += tdiff2;
526
krb5int_mutex_unlock_update_stats(k5_debug_mutex_stats *m)
528
k5_debug_time_t now = get_current_time();
529
k5_debug_timediff_t tdiff, tdiff2;
530
tdiff = timediff(now, m->time_acquired);
531
tdiff2 = tdiff * tdiff;
532
if (m->count == 1 || m->lockheld.valmin > tdiff)
533
m->lockheld.valmin = tdiff;
534
if (m->count == 1 || m->lockheld.valmax < tdiff)
535
m->lockheld.valmax = tdiff;
536
m->lockheld.valsum += tdiff;
537
m->lockheld.valsqsum += tdiff2;
542
get_stddev(struct k5_timediff_stats sp, int count)
544
long double mu, mu_squared, rho_squared;
545
mu = (long double) sp.valsum / count;
546
mu_squared = mu * mu;
548
= SUM(x_i^2 - 2*mu*x_i + mu^2)
549
= SUM(x_i^2) - 2*mu*SUM(x_i) + N*mu^2
551
Standard deviation rho^2 = SUM(...) / N. */
552
rho_squared = (sp.valsqsum - 2 * mu * sp.valsum + count * mu_squared) / count;
553
return sqrt(rho_squared);
557
krb5int_mutex_report_stats(k5_mutex_t *m)
561
/* Tweak this to only record data on "interesting" locks. */
562
if (m->stats.count < 10)
564
if (m->stats.lockwait.valsum < 10 * m->stats.count)
567
p = strrchr(m->loc_created.filename, '/');
569
p = m->loc_created.filename;
572
fprintf(stats_logfile, "mutex @%p: created at line %d of %s\n",
573
(void *) m, m->loc_created.lineno, p);
574
if (m->stats.count == 0)
575
fprintf(stats_logfile, "\tnever locked\n");
577
double sd_wait, sd_hold;
578
sd_wait = get_stddev(m->stats.lockwait, m->stats.count);
579
sd_hold = get_stddev(m->stats.lockheld, m->stats.count);
580
fprintf(stats_logfile,
581
"\tlocked %d time%s; wait %lu/%f/%lu/%fus, hold %lu/%f/%lu/%fus\n",
582
m->stats.count, m->stats.count == 1 ? "" : "s",
583
(unsigned long) m->stats.lockwait.valmin,
584
(double) m->stats.lockwait.valsum / m->stats.count,
585
(unsigned long) m->stats.lockwait.valmax,
587
(unsigned long) m->stats.lockheld.valmin,
588
(double) m->stats.lockheld.valsum / m->stats.count,
589
(unsigned long) m->stats.lockheld.valmax,
594
/* On Windows, everything defined in the export list must be defined.
595
The UNIX systems where we're using the export list don't seem to
597
#undef krb5int_mutex_lock_update_stats
599
krb5int_mutex_lock_update_stats(k5_debug_mutex_stats *m,
600
k5_mutex_stats_tmp startwait)
603
#undef krb5int_mutex_unlock_update_stats
605
krb5int_mutex_unlock_update_stats(k5_debug_mutex_stats *m)
608
#undef krb5int_mutex_report_stats
610
krb5int_mutex_report_stats(k5_mutex_t *m)
615
490
/* Mutex allocation functions, for use in plugins that may not know
616
491
what options a given set of libraries was compiled with. */
617
492
int KRB5_CALLCONV