コード例 #1
0
ファイル: ulRec.c プロジェクト: AlissonGiron/open-vm-tools
void
MXUser_ReleaseRecLock(MXUserRecLock *lock)  // IN/OUT:
{
   ASSERT(lock);
   MXUserValidateHeader(&lock->header, MXUSER_TYPE_REC);
   ASSERT(Atomic_Read(&lock->refCount) > 0);

   if (UNLIKELY(lock->vmmLock != NULL)) {
      ASSERT(MXUserMX_UnlockRec);
      (*MXUserMX_UnlockRec)(lock->vmmLock);
   } else {
      if (vmx86_stats) {
         MXUserHeldStats *heldStats = Atomic_ReadPtr(&lock->heldStatsMem);

         if (LIKELY(heldStats != NULL)) {
            if (MXRecLockCount(&lock->recursiveLock) == 1) {
               MXUserHeldStats *heldStats;

               heldStats = Atomic_ReadPtr(&lock->heldStatsMem);

               if (UNLIKELY(heldStats != NULL)) {
                  VmTimeType value;
                  MXUserHisto *histo = Atomic_ReadPtr(&heldStats->histo);

                  value = Hostinfo_SystemTimerNS() - heldStats->holdStart;

                  MXUserBasicStatsSample(&heldStats->data, value);

                  if (UNLIKELY(histo != NULL)) {
                     MXUserHistoSample(histo, value, GetReturnAddress());
                  }
               }
            }
         }
      }

      if (vmx86_debug) {
         if (MXRecLockCount(&lock->recursiveLock) == 0) {
            MXUserDumpAndPanic(&lock->header,
                               "%s: Release of an unacquired recursive lock\n",
                                __FUNCTION__);
         }

         if (!MXRecLockIsOwner(&lock->recursiveLock)) {
            MXUserDumpAndPanic(&lock->header,
                               "%s: Non-owner release of an recursive lock\n",
                               __FUNCTION__);
         }
      }

      MXUserReleaseTracking(&lock->header);

      MXRecLockRelease(&lock->recursiveLock);
   }
}
コード例 #2
0
ファイル: ulExcl.c プロジェクト: angelovescio/open-vm-tools
Bool
MXUser_TryAcquireExclLock(MXUserExclLock *lock)  // IN/OUT:
{
   Bool success;

   ASSERT(lock);
   MXUserValidateHeader(&lock->header, MXUSER_TYPE_EXCL);

   if (MXUserTryAcquireFail(lock->header.name)) {
      return FALSE;
   }

   success = MXRecLockTryAcquire(&lock->recursiveLock);

   if (success) {
      MXUserAcquisitionTracking(&lock->header, FALSE);

      if (vmx86_debug && (MXRecLockCount(&lock->recursiveLock) > 1)) {
         MXUserDumpAndPanic(&lock->header,
                            "%s: Acquire on an acquired exclusive lock\n",
                            __FUNCTION__);
      }
   }

   if (vmx86_stats) {
      MXUserStats *stats = Atomic_ReadPtr(&lock->statsMem);

      if (LIKELY(stats != NULL)) {
         MXUserAcquisitionSample(&stats->acquisitionStats, success, !success,
                                 0ULL);
      }
   }

   return success;
}
コード例 #3
0
ファイル: ulRec.c プロジェクト: AlissonGiron/open-vm-tools
static void
MXUserCondDestroyRecLock(MXUserRecLock *lock)  // IN:
{
   ASSERT(lock);
   MXUserValidateHeader(&lock->header, MXUSER_TYPE_REC);
   ASSERT(Atomic_Read(&lock->refCount) > 0);

   if (Atomic_ReadDec32(&lock->refCount) == 1) {
      if (lock->vmmLock == NULL) {
         if (MXRecLockCount(&lock->recursiveLock) > 0) {
            MXUserDumpAndPanic(&lock->header,
                               "%s: Destroy of an acquired recursive lock\n",
                               __FUNCTION__);
         }

         MXRecLockDestroy(&lock->recursiveLock);

         MXUserRemoveFromList(&lock->header);

         if (vmx86_stats) {
            MXUserDisableStats(&lock->acquireStatsMem, &lock->heldStatsMem);
         }
      }

      lock->header.signature = 0;  // just in case...
      free(lock->header.name);
      lock->header.name = NULL;
      free(lock);
   }
}
コード例 #4
0
static INLINE void
MXUserWaitInternal(MXRecLock *lock,         // IN:
                   MXUserCondVar *condVar,  // IN:
                   uint32 msecWait)         // IN:
{
   int err;
   int lockCount = MXRecLockCount(lock);

   /*
    * When using the native lock found within the MXUser lock, be sure to
    * decrement the count before the wait/sleep and increment it after the
    * wait/sleep - the (native) wait/sleep will perform a lock release before
    * the wait/sleep and a lock acquisition after the wait/sleep. The
    * MXUser internal accounting information must be maintained.
    */

   MXRecLockDecCount(lock, lockCount);

   if (msecWait == MXUSER_WAIT_INFINITE) {
      err = pthread_cond_wait(&condVar->condObject, &lock->nativeLock);
   } else {
      struct timeval curTime;
      struct timespec endTime;
      uint64 endNS;

      /*
       * pthread_cond_timedwait takes an absolute time. Yes, this is
       * beyond ridiculous, and the justifications for this
       * vs. relative time make no sense. But IIWII.
       */
#define A_BILLION (1000 * 1000 * 1000)
      gettimeofday(&curTime, NULL);
      endNS = ((uint64) curTime.tv_sec * A_BILLION) +
              ((uint64) curTime.tv_usec * 1000) +
              ((uint64) msecWait * (1000 * 1000));

      endTime.tv_sec = (time_t) (endNS / A_BILLION);
      endTime.tv_nsec = (long int) (endNS % A_BILLION);
#undef A_BILLION

      err = pthread_cond_timedwait(&condVar->condObject, &lock->nativeLock,
                                   &endTime);
   }

   MXRecLockIncCount(lock, lockCount);

   if (err != 0) {
      if (err != ETIMEDOUT) {
         Panic("%s: failure %d on condVar (0x%p; %s)\n", __FUNCTION__, err,
               condVar, condVar->header->name);
      }
   }
}
コード例 #5
0
ファイル: ulRec.c プロジェクト: AlissonGiron/open-vm-tools
void
MXUser_AcquireRecLock(MXUserRecLock *lock)  // IN/OUT:
{
   ASSERT(lock);
   MXUserValidateHeader(&lock->header, MXUSER_TYPE_REC);
   ASSERT(Atomic_Read(&lock->refCount) > 0);

   if (UNLIKELY(lock->vmmLock != NULL)) {
      ASSERT(MXUserMX_LockRec);
      (*MXUserMX_LockRec)(lock->vmmLock);
   } else {
      /* Rank checking is only done on the first acquisition */
      MXUserAcquisitionTracking(&lock->header, TRUE);

      if (vmx86_stats) {
         VmTimeType value = 0;
         MXUserAcquireStats *acquireStats;

         acquireStats = Atomic_ReadPtr(&lock->acquireStatsMem);

         MXRecLockAcquire(&lock->recursiveLock,
                          (acquireStats == NULL) ? NULL : &value);

         if (LIKELY(acquireStats != NULL)) {
            if (MXRecLockCount(&lock->recursiveLock) == 1) {
               MXUserHeldStats *heldStats;
               MXUserHisto *histo;

               MXUserAcquisitionSample(&acquireStats->data, TRUE,
                            value > acquireStats->data.contentionDurationFloor,
                                       value);

               histo = Atomic_ReadPtr(&acquireStats->histo);

               if (UNLIKELY(histo != NULL)) {
                  MXUserHistoSample(histo, value, GetReturnAddress());
               }

               heldStats = Atomic_ReadPtr(&lock->heldStatsMem);

               if (UNLIKELY(heldStats != NULL)) {
                  heldStats->holdStart = Hostinfo_SystemTimerNS();
               }
            }
         }
      } else {
         MXRecLockAcquire(&lock->recursiveLock,
                          NULL);  // non-stats
      }
   }
}
コード例 #6
0
ファイル: ulExcl.c プロジェクト: angelovescio/open-vm-tools
static void
MXUserDumpExclLock(MXUserHeader *header)  // IN:
{
   MXUserExclLock *lock = (MXUserExclLock *) header;

   Warning("%s: Exclusive lock @ %p\n", __FUNCTION__, lock);

   Warning("\tsignature 0x%X\n", lock->header.signature);
   Warning("\tname %s\n", lock->header.name);
   Warning("\trank 0x%X\n", lock->header.rank);
   Warning("\tserial number %u\n", lock->header.serialNumber);

   Warning("\tcount %d\n", MXRecLockCount(&lock->recursiveLock));

   Warning("\taddress of owner data %p\n",
           &lock->recursiveLock.nativeThreadID);
}
コード例 #7
0
ファイル: ulRW.c プロジェクト: angelovescio/open-vm-tools
void
MXUserDumpRWLock(MXUserHeader *header)  // IN:
{
   MXUserRWLock *lock = (MXUserRWLock *) header;

   Warning("%s: Read-write lock @ 0x%p\n", __FUNCTION__, lock);

   Warning("\tsignature 0x%X\n", lock->header.signature);
   Warning("\tname %s\n", lock->header.name);
   Warning("\trank 0x%X\n", lock->header.rank);
   Warning("\tserial number %u\n", lock->header.serialNumber);

   if (LIKELY(lock->useNative)) {
      Warning("\taddress of native lock 0x%p\n", &lock->nativeLock);
   } else {
      Warning("\tcount %d\n", MXRecLockCount(&lock->recursiveLock));
   }

   Warning("\tholderCount %d\n", Atomic_Read(&lock->holderCount));
}
コード例 #8
0
ファイル: ulExcl.c プロジェクト: angelovescio/open-vm-tools
void
MXUser_AcquireExclLock(MXUserExclLock *lock)  // IN/OUT:
{
   ASSERT(lock);
   MXUserValidateHeader(&lock->header, MXUSER_TYPE_EXCL);

   MXUserAcquisitionTracking(&lock->header, TRUE);

   if (vmx86_stats) {
      VmTimeType value = 0;
      MXUserStats *stats = Atomic_ReadPtr(&lock->statsMem);

      MXRecLockAcquire(&lock->recursiveLock, (stats == NULL) ? NULL : &value);

      if (LIKELY(stats != NULL)) {
         MXUserHisto *histo;

         MXUserAcquisitionSample(&stats->acquisitionStats, TRUE, value != 0,
                                 value);

         histo = Atomic_ReadPtr(&stats->acquisitionHisto);

         if (UNLIKELY(histo != NULL)) {
            MXUserHistoSample(histo, value, GetReturnAddress());
         }

         stats->holdStart = Hostinfo_SystemTimerNS();
      }
   } else {
      MXRecLockAcquire(&lock->recursiveLock,
                       NULL);  // non-stats
   }

   if (vmx86_debug && (MXRecLockCount(&lock->recursiveLock) > 1)) {
      MXUserDumpAndPanic(&lock->header,
                         "%s: Acquire on an acquired exclusive lock\n",
                         __FUNCTION__);
   }
}
コード例 #9
0
ファイル: ulRec.c プロジェクト: AlissonGiron/open-vm-tools
static void
MXUserDumpRecLock(MXUserHeader *header)  // IN:
{
   MXUserRecLock *lock = (MXUserRecLock *) header;

   Warning("%s: Recursive lock @ %p\n", __FUNCTION__, lock);

   Warning("\tsignature 0x%X\n", lock->header.signature);
   Warning("\tname %s\n", lock->header.name);
   Warning("\trank 0x%X\n", lock->header.rank);
   Warning("\tserial number %u\n", lock->header.bits.serialNumber);
   Warning("\treference count %u\n", Atomic_Read(&lock->refCount));

   if (lock->vmmLock == NULL) {
      Warning("\tlock count %d\n", MXRecLockCount(&lock->recursiveLock));

      Warning("\taddress of owner data %p\n",
              &lock->recursiveLock.nativeThreadID);
   } else {
      Warning("\tvmmLock %p\n", lock->vmmLock);
   }
}
コード例 #10
0
ファイル: ulExcl.c プロジェクト: angelovescio/open-vm-tools
void
MXUser_DestroyExclLock(MXUserExclLock *lock)  // IN:
{
   if (lock != NULL) {
      MXUserValidateHeader(&lock->header, MXUSER_TYPE_EXCL);

      if (MXRecLockCount(&lock->recursiveLock) > 0) {
         MXUserDumpAndPanic(&lock->header,
                            "%s: Destroy of an acquired exclusive lock\n",
                            __FUNCTION__);
      }

      lock->header.signature = 0;  // just in case...

      MXRecLockDestroy(&lock->recursiveLock);

      MXUserRemoveFromList(&lock->header);

      if (vmx86_stats) {
         MXUserStats *stats = Atomic_ReadPtr(&lock->statsMem);

         if (LIKELY(stats != NULL)) {
            MXUserAcquisitionStatsTearDown(&stats->acquisitionStats);
            MXUserHistoTearDown(Atomic_ReadPtr(&stats->acquisitionHisto));

            MXUserBasicStatsTearDown(&stats->heldStats);
            MXUserHistoTearDown(Atomic_ReadPtr(&stats->heldHisto));

            free(stats);
         }
      }

      free(lock->header.name);
      lock->header.name = NULL;
      free(lock);
   }
}
コード例 #11
0
ファイル: ulExcl.c プロジェクト: angelovescio/open-vm-tools
void
MXUser_ReleaseExclLock(MXUserExclLock *lock)  // IN/OUT:
{
   ASSERT(lock);
   MXUserValidateHeader(&lock->header, MXUSER_TYPE_EXCL);

   if (vmx86_stats) {
      MXUserStats *stats = Atomic_ReadPtr(&lock->statsMem);

      if (LIKELY(stats != NULL)) {
         MXUserHisto *histo;
         VmTimeType value = Hostinfo_SystemTimerNS() - stats->holdStart;

         MXUserBasicStatsSample(&stats->heldStats, value);

         histo = Atomic_ReadPtr(&stats->heldHisto);

         if (UNLIKELY(histo != NULL)) {
            MXUserHistoSample(histo, value, GetReturnAddress());
         }
      }
   }

   if (vmx86_debug && !MXRecLockIsOwner(&lock->recursiveLock)) {
      int lockCount = MXRecLockCount(&lock->recursiveLock);

      MXUserDumpAndPanic(&lock->header,
                         "%s: Non-owner release of an %s exclusive lock\n",
                         __FUNCTION__,
                         lockCount == 0 ? "unacquired" : "acquired");
   }

   MXUserReleaseTracking(&lock->header);

   MXRecLockRelease(&lock->recursiveLock);
}
コード例 #12
0
static INLINE void
MXUserWaitInternal(MXRecLock *lock,         // IN:
                   MXUserCondVar *condVar,  // IN:
                   uint32 msecWait)         // IN:
{
   int lockCount = MXRecLockCount(lock);
   DWORD waitTime = (msecWait == MXUSER_WAIT_INFINITE) ? INFINITE : msecWait;

   if (pSleepConditionVariableCS) {
      /*
       * When using the native lock found within the MXUser lock, be sure to
       * decrement the count before the wait/sleep and increment it after the
       * wait/sleep - the (native) wait/sleep will perform a lock release
       * before the wait/sleep and a lock acquisition after the wait/sleep.
       * The MXUser internal accounting information must be maintained.
       */

      MXRecLockDecCount(lock, lockCount);
      (*pSleepConditionVariableCS)(&condVar->x.condObject, &lock->nativeLock,
                                   waitTime);
      MXRecLockIncCount(lock, lockCount);
   } else {
      DWORD err;
      Bool done = FALSE;

      EnterCriticalSection(&condVar->x.compat.condVarLock);
      condVar->x.compat.numWaiters++;
      LeaveCriticalSection(&condVar->x.compat.condVarLock);

      MXRecLockDecCount(lock, lockCount - 1);
      MXRecLockRelease(lock);

      do {
         DWORD status = WaitForSingleObject(condVar->x.compat.signalEvent,
                                            waitTime);

         EnterCriticalSection(&condVar->x.compat.condVarLock);

         ASSERT(condVar->x.compat.numWaiters > 0);

         if (status == WAIT_OBJECT_0) {
            if (condVar->x.compat.numForRelease > 0) {
               condVar->x.compat.numWaiters--;

               if (--condVar->x.compat.numForRelease == 0) {
                  ResetEvent(condVar->x.compat.signalEvent);
               }

               err = ERROR_SUCCESS;
               done = TRUE;
            }
         } else {
            condVar->x.compat.numWaiters--;

            if (status == WAIT_TIMEOUT) {
               if (msecWait == MXUSER_WAIT_INFINITE) {
                  err = ERROR_CALL_NOT_IMPLEMENTED;  // ACK! "IMPOSSIBLE"
               } else {
                  err = ERROR_SUCCESS;
               }
            } else if (status == WAIT_ABANDONED) {
               err = ERROR_WAIT_NO_CHILDREN;
            } else {
               ASSERT(status == WAIT_FAILED);
               err = GetLastError();
            }

            done = TRUE;
         }

         LeaveCriticalSection(&condVar->x.compat.condVarLock);
      } while (!done);

      MXRecLockAcquire(lock,
                       NULL);  // non-stats

      MXRecLockIncCount(lock, lockCount - 1);

      if (err != ERROR_SUCCESS) {
         Panic("%s: failure %d on condVar (0x%p; %s)\n", __FUNCTION__, err,
               condVar, condVar->header->name);
      }
   }
}