~ubuntu-branches/ubuntu/quantal/open-vm-tools/quantal-201210021442

« back to all changes in this revision

Viewing changes to lib/lock/ulSema.c

  • Committer: Bazaar Package Importer
  • Author(s): Serge Hallyn
  • Date: 2011-03-31 14:20:05 UTC
  • mfrom: (1.4.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20110331142005-3n9red91p7ogkweo
Tags: 2011.03.28-387002-0ubuntu1
* Merge latest upstream git tag.  This has the unlocked_ioctl change
  needed to fix dkms build failures (LP: #727342)
* Changes in debian/rules:
  - work around a bug in toolbox/Makefile, where install-exec-hook is
    not happening.  This needs to get fixed the right way.
  - don't install 'vmware-user' which seems to no longer exist
  - move /etc/xdg into open-vm-toolbox (which should be done using .install)
* debian/open-vm-tools.init: add 'modprobe [-r] vmblock'. (LP: #332323)
* debian/rules and debian/open-vm-toolbox.lintian-overrides:
  - Make vmware-user-suid-wrapper suid-root (LP: #332323)

Show diffs side-by-side

added added

removed removed

Lines of Context:
39
39
#include "util.h"
40
40
#include "userlock.h"
41
41
#include "ulInt.h"
 
42
#include "hostinfo.h"
42
43
#if defined(_WIN32)
43
44
#include "win32u.h"
44
45
#endif
45
 
#if defined(__APPLE__)
46
 
#include "hostinfo.h"
47
 
#endif
48
46
 
49
47
#define MXUSER_SEMA_SIGNATURE 0x414D4553 // 'SEMA' in memory
50
48
#define MXUSER_A_BILLION (1000 * 1000 * 1000)
59
57
#endif
60
58
#endif
61
59
 
 
60
typedef struct
 
61
{
 
62
   MXUserAcquisitionStats  acquisitionStats;
 
63
   Atomic_Ptr              acquisitionHisto;
 
64
} MXUserStats;
 
65
 
62
66
struct MXUserSemaphore
63
67
{
64
68
   MXUserHeader     header;
65
69
   Atomic_uint32    activeUserCount;
66
 
 
67
70
   NativeSemaphore  nativeSemaphore;
 
71
   Atomic_Ptr       statsMem;
68
72
};
69
73
 
70
74
 
383
387
/*
384
388
 *-----------------------------------------------------------------------------
385
389
 *
 
390
 * MXUserStatsActionSema --
 
391
 *
 
392
 *      Perform the statistics action for the specified semaphore.
 
393
 *
 
394
 * Results:
 
395
 *      As above.
 
396
 *
 
397
 * Side effects:
 
398
 *      None
 
399
 *
 
400
 *-----------------------------------------------------------------------------
 
401
 */
 
402
 
 
403
static void
 
404
MXUserStatsActionSema(MXUserHeader *header)  // IN:
 
405
{
 
406
   MXUserSemaphore *sema = (MXUserSemaphore *) header;
 
407
   MXUserStats *stats = (MXUserStats *) Atomic_ReadPtr(&sema->statsMem);
 
408
 
 
409
   if (stats) {
 
410
      Bool isHot;
 
411
      Bool doLog;
 
412
      double contentionRatio;
 
413
 
 
414
      /*
 
415
       * Dump the statistics for the specified semaphore.
 
416
       */
 
417
 
 
418
      MXUserDumpAcquisitionStats(&stats->acquisitionStats, header);
 
419
 
 
420
      if (Atomic_ReadPtr(&stats->acquisitionHisto) != NULL) {
 
421
         MXUserHistoDump(Atomic_ReadPtr(&stats->acquisitionHisto), header);
 
422
      }
 
423
 
 
424
      /*
 
425
       * Has the semaphore gone "hot"? If so, implement the hot actions.
 
426
       */
 
427
 
 
428
      MXUserKitchen(&stats->acquisitionStats, &contentionRatio, &isHot,
 
429
                    &doLog);
 
430
 
 
431
      if (isHot) {
 
432
         MXUserForceHisto(&stats->acquisitionHisto,
 
433
                          MXUSER_STAT_CLASS_ACQUISITION,
 
434
                          MXUSER_DEFAULT_HISTO_MIN_VALUE_NS,
 
435
                          MXUSER_DEFAULT_HISTO_DECADES);
 
436
 
 
437
         if (doLog) {
 
438
            Log("HOT SEMAPHORE (%s); contention ratio %f\n",
 
439
                sema->header.name, contentionRatio);
 
440
         }
 
441
      }
 
442
   }
 
443
}
 
444
 
 
445
 
 
446
/*
 
447
 *-----------------------------------------------------------------------------
 
448
 *
386
449
 * MXUserDumpSemaphore --
387
450
 *
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);
 
473
 
409
474
   Warning("\treference count %u\n", Atomic_Read(&sema->activeUserCount));
410
475
   Warning("\tnative semaphore 0x%p\n", &sema->nativeSemaphore);
411
476
}
447
512
   }
448
513
 
449
514
   if (LIKELY(MXUserInit(&sema->nativeSemaphore) == 0)) {
 
515
      MXUserStats *stats;
 
516
 
 
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;
454
522
 
455
 
#if defined(MXUSER_STATS)
456
 
      sema->header.statsFunc = NULL;
457
 
      sema->header.identifier = MXUserAllocID();
 
523
      if (MXUserStatsEnabled()) {
 
524
         sema->header.statsFunc = MXUserStatsActionSema;
 
525
 
 
526
         stats = Util_SafeCalloc(1, sizeof(*stats));
 
527
 
 
528
         MXUserAcquisitionStatsSetUp(&stats->acquisitionStats);
 
529
 
 
530
         Atomic_WritePtr(&sema->statsMem, stats);
 
531
      } else {
 
532
         sema->header.statsFunc = NULL;
 
533
         Atomic_WritePtr(&sema->statsMem, NULL);
 
534
      }
458
535
 
459
536
      MXUserAddToList(&sema->header);
460
 
#endif
461
 
 
462
537
   } else {
463
538
      free(properName);
464
539
      free(sema);
490
565
{
491
566
   if (LIKELY(sema != NULL)) {
492
567
      int err;
 
568
      MXUserStats *stats;
493
569
 
494
570
      ASSERT(sema->header.signature == MXUSER_SEMA_SIGNATURE);
495
571
 
506
582
                            __FUNCTION__, err);
507
583
      }
508
584
 
509
 
#if defined(MXUSER_STATS)
510
585
      MXUserRemoveFromList(&sema->header);
511
 
#endif
 
586
 
 
587
      stats = (MXUserStats *) Atomic_ReadPtr(&sema->statsMem);
 
588
 
 
589
      if (stats) {
 
590
         MXUserAcquisitionStatsTearDown(&stats->acquisitionStats);
 
591
         MXUserHistoTearDown(Atomic_ReadPtr(&stats->acquisitionHisto));
 
592
 
 
593
         free(stats);
 
594
      }
512
595
 
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;
516
599
      free(sema);
517
600
   }
540
623
MXUser_DownSemaphore(MXUserSemaphore *sema)  // IN/OUT:
541
624
{
542
625
   int err;
 
626
   MXUserStats *stats;
543
627
 
544
628
   ASSERT(sema && (sema->header.signature == MXUSER_SEMA_SIGNATURE));
545
629
 
547
631
 
548
632
   MXUserAcquisitionTracking(&sema->header, TRUE);  // rank checking
549
633
 
550
 
   err = MXUserDown(&sema->nativeSemaphore);
 
634
   stats = (MXUserStats *) Atomic_ReadPtr(&sema->statsMem);
 
635
 
 
636
   if (stats) { 
 
637
      Bool tryDownSuccess = FALSE;
 
638
      VmTimeType begin = Hostinfo_SystemTimerNS();
 
639
 
 
640
      err = MXUserTryDown(&sema->nativeSemaphore, &tryDownSuccess);
 
641
 
 
642
      if (LIKELY(err == 0)) {
 
643
         if (!tryDownSuccess) {
 
644
            err = MXUserDown(&sema->nativeSemaphore);
 
645
         }
 
646
 
 
647
         if (LIKELY(err == 0)) {
 
648
            MXUserHisto *histo;
 
649
            VmTimeType value = Hostinfo_SystemTimerNS() - begin;
 
650
 
 
651
            MXUserAcquisitionSample(&stats->acquisitionStats, TRUE,
 
652
                                    !tryDownSuccess, value);
 
653
 
 
654
            histo = Atomic_ReadPtr(&stats->acquisitionHisto);
 
655
 
 
656
            if (UNLIKELY(histo != NULL)) {
 
657
               MXUserHistoSample(histo, value, GetReturnAddress());
 
658
            }
 
659
         }
 
660
      }
 
661
   } else {
 
662
      err = MXUserDown(&sema->nativeSemaphore);
 
663
   }
551
664
 
552
665
   if (UNLIKELY(err != 0)) {
553
666
      MXUserDumpAndPanic(&sema->header, "%s: Internal error (%d)\n",
584
697
                          uint32 msecWait)        // IN:
585
698
{
586
699
   int err;
 
700
   MXUserStats *stats;
587
701
   Bool downOccurred = FALSE;
588
702
 
589
703
   ASSERT(sema && (sema->header.signature == MXUSER_SEMA_SIGNATURE));
592
706
 
593
707
   MXUserAcquisitionTracking(&sema->header, TRUE);  // rank checking
594
708
 
595
 
   err = MXUserTimedDown(&sema->nativeSemaphore, msecWait, &downOccurred);
 
709
   stats = (MXUserStats *) Atomic_ReadPtr(&sema->statsMem);
 
710
 
 
711
   if (stats) { 
 
712
      Bool tryDownSuccess = FALSE;
 
713
      VmTimeType begin = Hostinfo_SystemTimerNS();
 
714
 
 
715
      err = MXUserTryDown(&sema->nativeSemaphore, &tryDownSuccess);
 
716
 
 
717
      if (LIKELY(err == 0)) {
 
718
         if (tryDownSuccess) {
 
719
            downOccurred = TRUE;
 
720
         } else {
 
721
            err = MXUserTimedDown(&sema->nativeSemaphore, msecWait,
 
722
                                  &downOccurred);
 
723
         }
 
724
 
 
725
         if (LIKELY(err == 0)) {
 
726
            VmTimeType value = Hostinfo_SystemTimerNS() - begin;
 
727
 
 
728
            MXUserAcquisitionSample(&stats->acquisitionStats, downOccurred,
 
729
                                    !tryDownSuccess, value);
 
730
 
 
731
            if (downOccurred) {
 
732
               MXUserHisto *histo = Atomic_ReadPtr(&stats->acquisitionHisto);
 
733
 
 
734
               if (UNLIKELY(histo != NULL)) {
 
735
                  MXUserHistoSample(histo, value, GetReturnAddress());
 
736
               }
 
737
            }
 
738
         }
 
739
      }
 
740
   } else {
 
741
      err = MXUserTimedDown(&sema->nativeSemaphore, msecWait, &downOccurred);
 
742
   }
596
743
 
597
744
   if (UNLIKELY(err != 0)) {
598
745
      MXUserDumpAndPanic(&sema->header, "%s: Internal error (%d)\n",
633
780
MXUser_TryDownSemaphore(MXUserSemaphore *sema)  // IN/OUT:
634
781
{
635
782
   int err;
 
783
   MXUserStats *stats;
636
784
   Bool downOccurred = FALSE;
637
785
 
638
786
   ASSERT(sema && (sema->header.signature == MXUSER_SEMA_SIGNATURE));
646
794
                         __FUNCTION__, err);
647
795
   }
648
796
 
 
797
   stats = (MXUserStats *) Atomic_ReadPtr(&sema->statsMem);
 
798
 
 
799
   if (stats) {
 
800
      MXUserAcquisitionSample(&stats->acquisitionStats, downOccurred,
 
801
                              !downOccurred, 0ULL);
 
802
   }
 
803
 
649
804
   Atomic_Dec(&sema->activeUserCount);
650
805
 
651
806
   return downOccurred;
658
813
 * MXUser_UpSemaphore --
659
814
 *
660
815
 *      Perform an up (V; verhogen; "increase") operation on a semaphore.
661
 
 *
 
816
 * 
662
817
 * Results:
663
818
 *      The semaphore count is incremented. Any thread waiting on the
664
819
 *      semaphore is awoken.
721
876
   sema = (MXUserSemaphore *) Atomic_ReadPtr(semaStorage);
722
877
 
723
878
   if (UNLIKELY(sema == NULL)) {
724
 
      MXUserSemaphore *before;
725
 
 
726
 
      sema = MXUser_CreateSemaphore(name, rank);
727
 
 
728
 
      before = (MXUserSemaphore *) Atomic_ReadIfEqualWritePtr(semaStorage,
729
 
                                                              NULL,
730
 
                                                              (void *) sema);
731
 
 
732
 
      if (before) {
733
 
         MXUser_DestroySemaphore(sema);
734
 
 
735
 
         sema = before;
 
879
      MXUserSemaphore *newSema = MXUser_CreateSemaphore(name, rank);
 
880
 
 
881
      sema = (MXUserSemaphore *) Atomic_ReadIfEqualWritePtr(semaStorage,
 
882
                                                            NULL,
 
883
                                                            (void *) newSema);
 
884
 
 
885
      if (sema) {
 
886
         MXUser_DestroySemaphore(newSema);
 
887
      } else {
 
888
         sema = (MXUserSemaphore *) Atomic_ReadPtr(semaStorage);
736
889
      }
737
890
   }
738
891