void
MXUserWaitCondVar(MXUserHeader *header,    // IN:
                  MXRecLock *lock,         // IN:
                  MXUserCondVar *condVar,  // IN:
                  uint32 msecWait)         // IN:
{
   ASSERT(header);
   ASSERT(lock);
   ASSERT(condVar);
   ASSERT(condVar->signature == MXUserGetSignature(MXUSER_TYPE_CONDVAR));

   if (condVar->ownerLock != lock) {
      Panic("%s: invalid use of lock %s with condVar (0x%p; %s)\n",
             __FUNCTION__, header->name, condVar, condVar->header->name);
   }

   if (vmx86_debug && !MXRecLockIsOwner(lock)) {
      Panic("%s: lock %s for condVar (0x%p) not owned\n",
            __FUNCTION__, condVar->header->name, condVar);
   }

   Atomic_Inc(&condVar->referenceCount);
   MXUserWaitInternal(lock, condVar, msecWait);
   Atomic_Dec(&condVar->referenceCount);
}
Exemple #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;
}
Exemple #3
0
MXUserRecLock *
MXUser_BindMXMutexRec(struct MX_MutexRec *mutex,  // IN:
                      MX_Rank rank)               // IN:
{
   char *name;
   MXUserRecLock *lock;

   ASSERT(mutex);

   /*
    * Cannot perform a binding unless MX_Init has been called. As a side
    * effect it registers these hook functions.
    */

   if ((MXUserMX_LockRec == NULL) ||
       (MXUserMX_UnlockRec == NULL) ||
       (MXUserMX_TryLockRec == NULL) ||
       (MXUserMX_IsLockedByCurThreadRec == NULL) ||
       (MXUserMX_NameRec == NULL)) {
       return NULL;
    }

   /*
    * Initialize the header (so it looks correct in memory) but don't connect
    * this lock to the MXUser statistics or debugging tracking - the MX lock
    * system will take care of this.
    */

   lock = Util_SafeCalloc(1, sizeof *lock);

   lock->header.signature = MXUserGetSignature(MXUSER_TYPE_REC);

   name = (*MXUserMX_NameRec)(mutex);

   if (name == NULL) {
      lock->header.name = Str_SafeAsprintf(NULL, "MX_%p", mutex);
   } else {
      lock->header.name = Str_SafeAsprintf(NULL, "%s *", name);
   }

   lock->header.rank = rank;
   lock->header.bits.serialNumber = MXUserAllocSerialNumber();
   lock->header.dumpFunc = NULL;
   lock->header.statsFunc = NULL;

   Atomic_WritePtr(&lock->acquireStatsMem, NULL);
   Atomic_WritePtr(&lock->heldStatsMem, NULL);
   Atomic_Write(&lock->refCount, 1);

   lock->vmmLock = mutex;

   return lock;
}
void
MXUser_BroadcastCondVar(MXUserCondVar *condVar)  // IN:
{
   int err;

   ASSERT(condVar);
   ASSERT(condVar->signature == MXUserGetSignature(MXUSER_TYPE_CONDVAR));

   err = MXUserBroadcastInternal(condVar);

   if (err != 0) {
      Panic("%s: failure %d on condVar (0x%p; %s) \n", __FUNCTION__, err,
            condVar, condVar->header->name);
   }
}
Exemple #5
0
MXUserCondVar *
MXUserCreateCondVar(MXUserHeader *header,  // IN:
                    MXRecLock *lock)       // IN:
{
   MXUserCondVar *condVar = Util_SafeCalloc(1, sizeof *condVar);

   if (UNLIKELY(!MXUserCreateInternal(condVar))) {
      Panic("%s: native lock initialization routine failed\n", __FUNCTION__);
   }

   condVar->signature = MXUserGetSignature(MXUSER_TYPE_CONDVAR);
   condVar->header = header;
   condVar->ownerLock = lock;

   return condVar;
}
Exemple #6
0
MXUserExclLock *
MXUser_CreateExclLock(const char *userName,  // IN:
                      MX_Rank rank)          // IN:
{
   Bool doStats;
   char *properName;
   MXUserExclLock *lock;

   lock = Util_SafeCalloc(1, sizeof(*lock));

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

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

      return NULL;
   }

   lock->header.signature = MXUserGetSignature(MXUSER_TYPE_EXCL);
   lock->header.name = properName;
   lock->header.rank = rank;
   lock->header.serialNumber = MXUserAllocSerialNumber();
   lock->header.dumpFunc = MXUserDumpExclLock;

   if (vmx86_stats) {
      doStats = MXUserStatsEnabled();
   } else {
      doStats = FALSE;
   }

   if (doStats) {
      MXUser_ControlExclLock(lock, MXUSER_CONTROL_ENABLE_STATS);
   } else {
      lock->header.statsFunc = NULL;
      Atomic_WritePtr(&lock->statsMem, NULL);
   }

   MXUserAddToList(&lock->header);

   return lock;
}
MXUserCondVar *
MXUserCreateCondVar(MXUserHeader *header,  // IN:
                    MXRecLock *lock)       // IN:
{
   MXUserCondVar *condVar = Util_SafeCalloc(1, sizeof(*condVar));

   if (MXUserCreateInternal(condVar)) {
      condVar->signature = MXUserGetSignature(MXUSER_TYPE_CONDVAR);
      condVar->header = header;
      condVar->ownerLock = lock;
   } else {
      free(condVar);
      condVar = NULL;
   }

   return condVar;
}
Exemple #8
0
MXUserSemaphore *
MXUser_CreateSemaphore(const char *userName,  // IN:
                       MX_Rank rank)          // IN:
{
   char *properName;
   MXUserSemaphore *sema;

   sema = Util_SafeCalloc(1, sizeof(*sema));

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

   if (LIKELY(MXUserInit(&sema->nativeSemaphore) == 0)) {
      sema->header.signature = MXUserGetSignature(MXUSER_TYPE_SEMA);
      sema->header.name = properName;
      sema->header.rank = rank;
      sema->header.serialNumber = MXUserAllocSerialNumber();
      sema->header.dumpFunc = MXUserDumpSemaphore;

      if (MXUserStatsMode() == 0) {
         sema->header.statsFunc = NULL;
         Atomic_WritePtr(&sema->acquireStatsMem, NULL);
      } else {
         MXUserAcquireStats *acquireStats;

         acquireStats = Util_SafeCalloc(1, sizeof(*acquireStats));

         MXUserAcquisitionStatsSetUp(&acquireStats->data);

         sema->header.statsFunc = MXUserStatsActionSema;
         Atomic_WritePtr(&sema->acquireStatsMem, acquireStats);
      }

      MXUserAddToList(&sema->header);
   } else {
      free(properName);
      free(sema);
      sema = NULL;
   }

   return sema;
}
void
MXUser_DestroyCondVar(MXUserCondVar *condVar)  // IN:
{
   if (condVar != NULL) {
      ASSERT(condVar->signature == MXUserGetSignature(MXUSER_TYPE_CONDVAR));

      if (Atomic_Read(&condVar->referenceCount) != 0) {
         Panic("%s: Attempted destroy on active condVar (0x%p; %s)\n",
               __FUNCTION__, condVar, condVar->header->name);
      }

      condVar->signature = 0;  // just in case...

      MXUserDestroyInternal(condVar);

      condVar->header = NULL;
      condVar->ownerLock = NULL;

      free(condVar);
   }
}
Exemple #10
0
MXUserRWLock *
MXUser_CreateRWLock(const char *userName,  // IN:
                    MX_Rank rank)          // IN:
{
   Bool lockInited;
   char *properName;
   MXUserRWLock *lock;
   Bool useNative = MXUserNativeRWSupported();

   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.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)) {
      Bool doStats;

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

      if (vmx86_stats) {
         doStats = MXUserStatsEnabled();
      } else {
         doStats = FALSE;
      }

      if (doStats) {
         MXUser_ControlRWLock(lock, MXUSER_CONTROL_ENABLE_STATS);
      } else {
         lock->header.statsFunc = NULL;
         Atomic_WritePtr(&lock->statsMem, NULL);
      }

      MXUserAddToList(&lock->header);
   } else {
      if (lock->useNative) {
         MXUserNativeRWDestroy(&lock->nativeLock);
      }

      free(properName);
      free(lock);
      lock = NULL;
   }

   return lock;
}
Exemple #11
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;
}