#include "ulInt.h"
#include "ulIntShared.h"
#include "hashTable.h"
+#include "random.h"
static Bool mxInPanic = FALSE; // track when involved in a panic
}
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * MXUserSydrome --
+ *
+ * Generate the syndrome bits for this MXUser library.
+ *
+ * Each MXUser library has unique syndrome bits enabling the run time
+ * detection of locks created with one copy of the MXUser library and
+ * passed to another copy of the MXUser library.
+ *
+ * The syndrome bits are important as they prevent incompatible versions
+ * of the MXUser library from trashing each other.
+ *
+ * The bits are generated by using a source of bits that is external to
+ * a program and its libraries. This way no code or data based scheme
+ * can be spoofed or aliased.
+ *
+ * Results:
+ * As above
+ *
+ * Side effects:
+ * None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static uint32
+MXUserSyndrome(void)
+{
+ uint32 syndrome;
+ static Atomic_uint32 syndromeMem; // implicitly zero -- mbellon
+
+ syndrome = Atomic_Read(&syndromeMem);
+
+ if (syndrome == 0) {
+ while (Random_Crypto(sizeof syndrome, &syndrome) && (syndrome == 0))
+ ;
+
+ if (syndrome == 0) {
+ syndrome++; // Fudge in case of failure
+ }
+
+ /* blind write; if racing one thread or the other will do */
+ Atomic_ReadIfEqualWrite(&syndromeMem, 0, syndrome);
+
+ syndrome = Atomic_Read(&syndromeMem);
+ ASSERT(syndrome);
+ }
+
+ return syndrome;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * MXUserGetSignature --
+ *
+ * Return a signature appropriate for the specified object type.
+ *
+ * Results:
+ * As above
+ *
+ * Side effects:
+ * None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+uint32
+MXUserGetSignature(uint32 objectType) // IN:
+{
+ uint32 signature;
+
+ ASSERT(objectType < 16); // 4 bits of object type
+
+ signature = (MXUserSyndrome() & 0x0FFFFFFF) | (objectType << 28);
+ ASSERT(signature);
+
+ return signature;
+}
+
#if defined(MXUSER_DEBUG)
#define MXUSER_MAX_LOCKS_PER_THREAD (2 * MXUSER_MAX_REC_DEPTH)
void
MXUserValidateHeader(MXUserHeader *header, // IN:
- uint32 objectID) // IN:
+ uint32 objectType) // IN:
{
- if (header->signature != objectID) {
+ uint32 expected = MXUserGetSignature(objectType);
+
+ if (header->signature != expected) {
MXUserDumpAndPanic(header, "%s: expected %X observed %X\n", __FUNCTION__,
- objectID, header->signature);
+ expected, header->signature);
}
}
#endif
barrier->configCount = count;
barrier->curContext = 0;
- barrier->header.signature = MXUSER_TYPE_BARRIER;
+ barrier->header.signature = MXUserGetSignature(MXUSER_TYPE_BARRIER);
barrier->header.name = properName;
barrier->header.rank = rank;
barrier->header.serialNumber = MXUserAllocSerialNumber();
return NULL;
}
- lock->header.signature = MXUSER_TYPE_EXCL;
+ lock->header.signature = MXUserGetSignature(MXUSER_TYPE_EXCL);
lock->header.name = properName;
lock->header.rank = rank;
lock->header.serialNumber = MXUserAllocSerialNumber();
return (void *) (uintptr_t) VThread_CurID(); // unsigned
}
-#define MXUSER_TYPE_RW 0x57524B4C // 'LKRW' in memory
-#define MXUSER_TYPE_REC 0x43524B4C // 'LKRC' in memory
-#define MXUSER_TYPE_RANK 0x4E4B5241 // 'RANK' in memory
-#define MXUSER_TYPE_EXCL 0x58454B4C // 'LKEX' in memory
-#define MXUSER_TYPE_SEMA 0x414D4553 // 'SEMA' in memory
-#define MXUSER_TYPE_CONDVAR 0x444E4F43 // 'COND' in memory
-#define MXUSER_TYPE_BARRIER 0x52524142 // 'BARR' in memory
+/*
+ * MXUser object type ID value. They must never be zero!
+ */
+
+#define MXUSER_TYPE_RW 0x1
+#define MXUSER_TYPE_REC 0x2
+#define MXUSER_TYPE_RANK 0x3
+#define MXUSER_TYPE_EXCL 0x4
+#define MXUSER_TYPE_SEMA 0x5
+#define MXUSER_TYPE_CONDVAR 0x6
+#define MXUSER_TYPE_BARRIER 0x7
/*
* MXUser header - all MXUser objects start with this
MXRecLock *MXUserInternalSingleton(Atomic_Ptr *storage);
+uint32 MXUserGetSignature(uint32 objectType);
+
#if defined(MXUSER_DEBUG)
void MXUserAcquisitionTracking(MXUserHeader *header,
Bool checkRank);
void MXUserReleaseTracking(MXUserHeader *header);
void MXUserValidateHeader(MXUserHeader *header,
- uint32 objectID);
+ uint32 objectType);
#else
static INLINE void
MXUserAcquisitionTracking(MXUserHeader *header, // IN:
static INLINE void
MXUserValidateHeader(MXUserHeader *header, // IN:
- uint32 objectID) // IN:
+ uint32 objectType) // IN:
{
return;
}
properName = Util_SafeStrdup(userName);
}
- lock->header.signature = MXUSER_TYPE_RW;
+ lock->header.signature = MXUserGetSignature(MXUSER_TYPE_RW);
lock->header.name = properName;
lock->header.rank = rank;
lock->header.serialNumber = MXUserAllocSerialNumber();
lock->vmmLock = NULL;
Atomic_Write(&lock->refCount, 1);
- lock->header.signature = MXUSER_TYPE_REC;
+ lock->header.signature = MXUserGetSignature(MXUSER_TYPE_REC);
lock->header.name = properName;
lock->header.rank = rank;
lock->header.serialNumber = MXUserAllocSerialNumber();
lock = Util_SafeCalloc(1, sizeof(*lock));
- lock->header.signature = MXUSER_TYPE_REC;
+ lock->header.signature = MXUserGetSignature(MXUSER_TYPE_REC);
lock->header.name = Str_SafeAsprintf(NULL, "MX_%p", mutex);
lock->header.rank = rank;
lock->header.serialNumber = MXUserAllocSerialNumber();
if (LIKELY(MXUserInit(&sema->nativeSemaphore) == 0)) {
MXUserStats *stats;
- sema->header.signature = MXUSER_TYPE_SEMA;
+ sema->header.signature = MXUserGetSignature(MXUSER_TYPE_SEMA);
sema->header.name = properName;
sema->header.rank = rank;
sema->header.serialNumber = MXUserAllocSerialNumber();