384
388
*-----------------------------------------------------------------------------
390
* MXUserStatsActionSema --
392
* Perform the statistics action for the specified semaphore.
400
*-----------------------------------------------------------------------------
404
MXUserStatsActionSema(MXUserHeader *header) // IN:
406
MXUserSemaphore *sema = (MXUserSemaphore *) header;
407
MXUserStats *stats = (MXUserStats *) Atomic_ReadPtr(&sema->statsMem);
412
double contentionRatio;
415
* Dump the statistics for the specified semaphore.
418
MXUserDumpAcquisitionStats(&stats->acquisitionStats, header);
420
if (Atomic_ReadPtr(&stats->acquisitionHisto) != NULL) {
421
MXUserHistoDump(Atomic_ReadPtr(&stats->acquisitionHisto), header);
425
* Has the semaphore gone "hot"? If so, implement the hot actions.
428
MXUserKitchen(&stats->acquisitionStats, &contentionRatio, &isHot,
432
MXUserForceHisto(&stats->acquisitionHisto,
433
MXUSER_STAT_CLASS_ACQUISITION,
434
MXUSER_DEFAULT_HISTO_MIN_VALUE_NS,
435
MXUSER_DEFAULT_HISTO_DECADES);
438
Log("HOT SEMAPHORE (%s); contention ratio %f\n",
439
sema->header.name, contentionRatio);
447
*-----------------------------------------------------------------------------
386
449
* MXUserDumpSemaphore --
388
451
* Dump a semaphore.
406
469
Warning("\tsignature 0x%X\n", sema->header.signature);
407
470
Warning("\tname %s\n", sema->header.name);
408
471
Warning("\trank 0x%X\n", sema->header.rank);
472
Warning("\tserial number %u\n", sema->header.serialNumber);
409
474
Warning("\treference count %u\n", Atomic_Read(&sema->activeUserCount));
410
475
Warning("\tnative semaphore 0x%p\n", &sema->nativeSemaphore);
449
514
if (LIKELY(MXUserInit(&sema->nativeSemaphore) == 0)) {
517
sema->header.signature = MXUSER_SEMA_SIGNATURE;
450
518
sema->header.name = properName;
451
sema->header.signature = MXUSER_SEMA_SIGNATURE;
452
519
sema->header.rank = rank;
520
sema->header.serialNumber = MXUserAllocSerialNumber();
453
521
sema->header.dumpFunc = MXUserDumpSemaphore;
455
#if defined(MXUSER_STATS)
456
sema->header.statsFunc = NULL;
457
sema->header.identifier = MXUserAllocID();
523
if (MXUserStatsEnabled()) {
524
sema->header.statsFunc = MXUserStatsActionSema;
526
stats = Util_SafeCalloc(1, sizeof(*stats));
528
MXUserAcquisitionStatsSetUp(&stats->acquisitionStats);
530
Atomic_WritePtr(&sema->statsMem, stats);
532
sema->header.statsFunc = NULL;
533
Atomic_WritePtr(&sema->statsMem, NULL);
459
536
MXUserAddToList(&sema->header);
463
538
free(properName);
506
582
__FUNCTION__, err);
509
#if defined(MXUSER_STATS)
510
585
MXUserRemoveFromList(&sema->header);
587
stats = (MXUserStats *) Atomic_ReadPtr(&sema->statsMem);
590
MXUserAcquisitionStatsTearDown(&stats->acquisitionStats);
591
MXUserHistoTearDown(Atomic_ReadPtr(&stats->acquisitionHisto));
513
596
sema->header.signature = 0; // just in case...
514
free((void *) sema->header.name); // avoid const warnings
597
free(sema->header.name);
515
598
sema->header.name = NULL;
548
632
MXUserAcquisitionTracking(&sema->header, TRUE); // rank checking
550
err = MXUserDown(&sema->nativeSemaphore);
634
stats = (MXUserStats *) Atomic_ReadPtr(&sema->statsMem);
637
Bool tryDownSuccess = FALSE;
638
VmTimeType begin = Hostinfo_SystemTimerNS();
640
err = MXUserTryDown(&sema->nativeSemaphore, &tryDownSuccess);
642
if (LIKELY(err == 0)) {
643
if (!tryDownSuccess) {
644
err = MXUserDown(&sema->nativeSemaphore);
647
if (LIKELY(err == 0)) {
649
VmTimeType value = Hostinfo_SystemTimerNS() - begin;
651
MXUserAcquisitionSample(&stats->acquisitionStats, TRUE,
652
!tryDownSuccess, value);
654
histo = Atomic_ReadPtr(&stats->acquisitionHisto);
656
if (UNLIKELY(histo != NULL)) {
657
MXUserHistoSample(histo, value, GetReturnAddress());
662
err = MXUserDown(&sema->nativeSemaphore);
552
665
if (UNLIKELY(err != 0)) {
553
666
MXUserDumpAndPanic(&sema->header, "%s: Internal error (%d)\n",
593
707
MXUserAcquisitionTracking(&sema->header, TRUE); // rank checking
595
err = MXUserTimedDown(&sema->nativeSemaphore, msecWait, &downOccurred);
709
stats = (MXUserStats *) Atomic_ReadPtr(&sema->statsMem);
712
Bool tryDownSuccess = FALSE;
713
VmTimeType begin = Hostinfo_SystemTimerNS();
715
err = MXUserTryDown(&sema->nativeSemaphore, &tryDownSuccess);
717
if (LIKELY(err == 0)) {
718
if (tryDownSuccess) {
721
err = MXUserTimedDown(&sema->nativeSemaphore, msecWait,
725
if (LIKELY(err == 0)) {
726
VmTimeType value = Hostinfo_SystemTimerNS() - begin;
728
MXUserAcquisitionSample(&stats->acquisitionStats, downOccurred,
729
!tryDownSuccess, value);
732
MXUserHisto *histo = Atomic_ReadPtr(&stats->acquisitionHisto);
734
if (UNLIKELY(histo != NULL)) {
735
MXUserHistoSample(histo, value, GetReturnAddress());
741
err = MXUserTimedDown(&sema->nativeSemaphore, msecWait, &downOccurred);
597
744
if (UNLIKELY(err != 0)) {
598
745
MXUserDumpAndPanic(&sema->header, "%s: Internal error (%d)\n",
721
876
sema = (MXUserSemaphore *) Atomic_ReadPtr(semaStorage);
723
878
if (UNLIKELY(sema == NULL)) {
724
MXUserSemaphore *before;
726
sema = MXUser_CreateSemaphore(name, rank);
728
before = (MXUserSemaphore *) Atomic_ReadIfEqualWritePtr(semaStorage,
733
MXUser_DestroySemaphore(sema);
879
MXUserSemaphore *newSema = MXUser_CreateSemaphore(name, rank);
881
sema = (MXUserSemaphore *) Atomic_ReadIfEqualWritePtr(semaStorage,
886
MXUser_DestroySemaphore(newSema);
888
sema = (MXUserSemaphore *) Atomic_ReadPtr(semaStorage);