Beispiel #1
0
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);
   }
}
Beispiel #2
0
MXUserRecLock *
MXUser_CreateRecLock(const char *userName,  // IN:
                     MX_Rank rank)          // IN:
{
   uint32 statsMode;
   char *properName;
   MXUserRecLock *lock = Util_SafeCalloc(1, sizeof *lock);

   if (userName == NULL) {
      properName = Str_SafeAsprintf(NULL, "R-%p", GetReturnAddress());
   } else {
      properName = Util_SafeStrdup(userName);
   }

   if (!MXRecLockInit(&lock->recursiveLock)) {
      free(properName);
      free(lock);

      return NULL;
   }

   lock->vmmLock = NULL;
   Atomic_Write(&lock->refCount, 1);

   lock->header.signature = MXUserGetSignature(MXUSER_TYPE_REC);
   lock->header.name = properName;
   lock->header.rank = rank;
   lock->header.bits.serialNumber = MXUserAllocSerialNumber();
   lock->header.dumpFunc = MXUserDumpRecLock;

   statsMode = MXUserStatsMode();

   switch (statsMode) {
   case 0:
      MXUserDisableStats(&lock->acquireStatsMem, &lock->heldStatsMem);
      lock->header.statsFunc = NULL;
      break;

   case 1:
      MXUserEnableStats(&lock->acquireStatsMem, NULL);
      lock->header.statsFunc = MXUserStatsActionRec;
      break;

   case 2:
      MXUserEnableStats(&lock->acquireStatsMem, &lock->heldStatsMem);
      lock->header.statsFunc = MXUserStatsActionRec;
      break;

   default:
      Panic("%s: unknown stats mode: %d!\n", __FUNCTION__, statsMode);
   }

   MXUserAddToList(&lock->header);

   return lock;
}
Beispiel #3
0
Bool
MXUser_DisableStatsRecLock(MXUserRecLock *lock)  // IN/OUT:
{
   ASSERT(lock);
   MXUserValidateHeader(&lock->header, MXUSER_TYPE_REC);

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

   return vmx86_stats;
}
Beispiel #4
0
void
MXUser_DestroyRWLock(MXUserRWLock *lock)  // IN:
{
   if (LIKELY(lock != NULL)) {
      MXUserValidateHeader(&lock->header, MXUSER_TYPE_RW);

      if (Atomic_Read(&lock->holderCount) != 0) {
         MXUserDumpAndPanic(&lock->header,
                            "%s: Destroy on an acquired read-write lock\n",
                            __FUNCTION__);
      }

      if (LIKELY(lock->useNative)) {
         int err = MXUserNativeRWDestroy(&lock->nativeLock);

         if (UNLIKELY(err != 0)) {
            MXUserDumpAndPanic(&lock->header, "%s: Internal error (%d)\n",
                               __FUNCTION__, err);
         }
      }

      MXRecLockDestroy(&lock->recursiveLock);

      MXUserRemoveFromList(&lock->header);

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

      HashTable_FreeUnsafe(lock->holderTable);

      lock->header.signature = 0;  // just in case...
      free(lock->header.name);
      lock->header.name = NULL;
      free(lock);
   }
}
Beispiel #5
0
MXUserRWLock *
MXUser_CreateRWLock(const char *userName,  // IN:
                    MX_Rank rank)          // IN:
{
   Bool lockInited;
   char *properName;
   Bool useNative = MXUserNativeRWSupported();
   MXUserRWLock *lock = Util_SafeCalloc(1, sizeof *lock);

   if (userName == NULL) {
      if (LIKELY(useNative)) {
         properName = Str_SafeAsprintf(NULL, "RW-%p", GetReturnAddress());
      } else {
         /* emulated */
         properName = Str_SafeAsprintf(NULL, "RWemul-%p", GetReturnAddress());
      }
   } else {
      properName = Util_SafeStrdup(userName);
   }

   lock->header.signature = MXUserGetSignature(MXUSER_TYPE_RW);
   lock->header.name = properName;
   lock->header.rank = rank;
   lock->header.bits.serialNumber = MXUserAllocSerialNumber();
   lock->header.dumpFunc = MXUserDumpRWLock;

   /*
    * Always attempt to use native locks when they are available. If, for some
    * reason, a native lock should be available but isn't, fall back to using
    * an internal recursive lock - something is better than nothing.
    */

   lock->useNative = useNative && MXUserNativeRWInit(&lock->nativeLock);

   lockInited = MXRecLockInit(&lock->recursiveLock);

   if (LIKELY(lockInited)) {
      uint32 statsMode;

      lock->holderTable = HashTable_Alloc(256,
                                          HASH_INT_KEY | HASH_FLAG_ATOMIC,
                                          MXUserFreeHashEntry);

      statsMode = MXUserStatsMode();

      switch (MXUserStatsMode()) {
      case 0:
         MXUserDisableStats(&lock->acquireStatsMem, &lock->heldStatsMem);
         lock->header.statsFunc = NULL;
         break;

      case 1:
         MXUserEnableStats(&lock->acquireStatsMem, NULL);
         lock->header.statsFunc = MXUserStatsActionRW;
         break;

      case 2:
         MXUserEnableStats(&lock->acquireStatsMem, &lock->heldStatsMem);
         lock->header.statsFunc = MXUserStatsActionRW;
         break;

      default:
         Panic("%s: unknown stats mode: %d!\n", __FUNCTION__, statsMode);
      }

      MXUserAddToList(&lock->header);
   } else {
      Panic("%s: native lock initialization routine failed\n", __FUNCTION__);
   }

   return lock;
}