*/
+#include "drd_clientobj.h"
#include "drd_error.h"
#include "drd_mutex.h"
-#include "drd_suppression.h"
#include "priv_drd_clientreq.h"
#include "pub_tool_errormgr.h" // VG_(maybe_record_error)()
#include "pub_tool_libcassert.h" // tl_assert()
-#include "pub_tool_libcprint.h" // VG_(printf)()
+#include "pub_tool_libcprint.h" // VG_(message)()
#include "pub_tool_machine.h" // VG_(get_IP)()
#include "pub_tool_threadstate.h" // VG_(get_running_tid)()
-// Type definitions.
-
-struct mutex_info
-{
- Addr mutex; // Pointer to client mutex.
- SizeT size; // Size in bytes of client-side object.
- MutexT mutex_type; // pthread_mutex_t or pthread_spinlock_t.
- int recursion_count; // 0 if free, >= 1 if locked.
- DrdThreadId owner; // owner if locked, last owner if free.
- VectorClock vc; // vector clock associated with last unlock.
-};
-
-
// Local functions.
static Bool mutex_is_locked(struct mutex_info* const p);
static Bool s_trace_mutex;
static ULong s_mutex_lock_count;
-struct mutex_info s_mutex[256];
// Function definitions.
{
tl_assert(mutex != 0);
tl_assert(size > 0);
-#if 0
- tl_assert(mutex_type == mutex_type_mutex
- || mutex_type == mutex_type_spinlock);
-#endif
- p->mutex = mutex;
- p->size = size;
+ tl_assert(p->a1 == mutex);
+ tl_assert(p->a2 == mutex + size);
+ p->cleanup = (void(*)(DrdClientobj*))&mutex_destroy;
p->mutex_type = mutex_type;
p->recursion_count = 0;
p->owner = DRD_INVALID_THREADID;
const SizeT size,
const MutexT mutex_type)
{
- int i;
-
-#if 0
- tl_assert(mutex_type == mutex_type_mutex
- || mutex_type == mutex_type_spinlock);
-#endif
+ struct mutex_info* p;
- for (i = 0; i < sizeof(s_mutex)/sizeof(s_mutex[0]); i++)
+ tl_assert(offsetof(DrdClientobj, mutex) == 0);
+ p = &drd_clientobj_get(mutex, ClientMutex)->mutex;
+ if (p)
{
- if (s_mutex[i].mutex == mutex)
- {
- if (s_mutex[i].mutex_type != mutex_type)
- {
- VG_(message)(Vg_DebugMsg, "??? mutex %p: type changed from %d into %d",
- s_mutex[i].mutex, s_mutex[i].mutex_type, mutex_type);
- }
- tl_assert(s_mutex[i].mutex_type == mutex_type);
- tl_assert(s_mutex[i].size == size);
- return &s_mutex[i];
- }
+ tl_assert(p->mutex_type == mutex_type);
+ tl_assert(p->a2 - p->a1 == size);
+ return p;
}
- for (i = 0; i < sizeof(s_mutex)/sizeof(s_mutex[0]); i++)
+
+ if (drd_clientobj_present(mutex, mutex + size))
{
- if (s_mutex[i].mutex == 0)
- {
- if (drd_is_any_suppressed(mutex, mutex + size))
- {
- GenericErrInfo GEI;
- VG_(maybe_record_error)(VG_(get_running_tid)(),
- GenericErr,
- VG_(get_IP)(VG_(get_running_tid)()),
- "Not a mutex",
- &GEI);
- return 0;
- }
- mutex_initialize(&s_mutex[i], mutex, size, mutex_type);
- drd_start_suppression(mutex, mutex + size,
- mutex_get_typename(&s_mutex[i]));
- return &s_mutex[i];
- }
+ GenericErrInfo GEI;
+ VG_(maybe_record_error)(VG_(get_running_tid)(),
+ GenericErr,
+ VG_(get_IP)(VG_(get_running_tid)()),
+ "Not a mutex",
+ &GEI);
+ return 0;
}
- tl_assert(0);
- return 0;
+
+ p = &drd_clientobj_add(mutex, mutex + size, ClientMutex)->mutex;
+ mutex_initialize(p, mutex, size, mutex_type);
+ return p;
}
struct mutex_info*
mutex);
}
-#if 0
- tl_assert(mutex_type == mutex_type_mutex
- || mutex_type == mutex_type_spinlock);
-#endif
-
mutex_p = mutex_get(mutex);
if (mutex_p)
{
const ThreadId vg_tid = VG_(get_running_tid)();
MutexErrInfo MEI
- = { mutex_p->mutex, mutex_p->recursion_count, mutex_p->owner };
+ = { mutex_p->a1, mutex_p->recursion_count, mutex_p->owner };
VG_(maybe_record_error)(vg_tid,
MutexErr,
VG_(get_IP)(vg_tid),
"drd_pre_mutex_destroy tid = %d/%d, %s 0x%lx",
vg_tid, drd_tid,
mutex_get_typename(p),
- p->mutex);
+ p->a1);
}
if (mutex_is_locked(p))
{
- MutexErrInfo MEI = { p->mutex, p->recursion_count, p->owner };
+ MutexErrInfo MEI = { p->a1, p->recursion_count, p->owner };
VG_(maybe_record_error)(VG_(get_running_tid)(),
MutexErr,
VG_(get_IP)(VG_(get_running_tid)()),
&MEI);
}
- drd_finish_suppression(p->mutex, p->mutex + p->size);
-
- vc_cleanup(&p->vc);
- p->mutex = 0;
+ drd_clientobj_remove(p->a1);
}
void mutex_pre_destroy(struct mutex_info* const p)
if (mutex_get_recursion_count(mutex) > 0)
{
const ThreadId vg_tid = VG_(get_running_tid)();
- MutexErrInfo MEI = { p->mutex, p->recursion_count, p->owner };
+ MutexErrInfo MEI = { p->a1, p->recursion_count, p->owner };
VG_(maybe_record_error)(vg_tid,
MutexErr,
VG_(get_IP)(vg_tid),
struct mutex_info* mutex_get(const Addr mutex)
{
- int i;
- for (i = 0; i < sizeof(s_mutex)/sizeof(s_mutex[0]); i++)
- if (s_mutex[i].mutex == mutex)
- return &s_mutex[i];
- return 0;
+ tl_assert(offsetof(DrdClientobj, mutex) == 0);
+ return &drd_clientobj_get(mutex, ClientMutex)->mutex;
}
/** Called before pthread_mutex_lock() is invoked. If a data structure for
&& p->recursion_count >= 1
&& mutex_type != mutex_type_recursive_mutex)
{
- MutexErrInfo MEI = { p->mutex, p->recursion_count, p->owner };
+ MutexErrInfo MEI = { p->a1, p->recursion_count, p->owner };
VG_(maybe_record_error)(VG_(get_running_tid)(),
MutexErr,
VG_(get_IP)(VG_(get_running_tid)()),
#endif
tl_assert(p->mutex_type == mutex_type);
- tl_assert(p->size == size);
+ tl_assert(p->a2 - p->a1 == size);
if (p->recursion_count == 0)
{
"The impossible happened: mutex 0x%lx is locked"
" simultaneously by two threads (recursion count %d,"
" owners %d and %d) !",
- p->mutex, p->recursion_count, p->owner, drd_tid);
+ p->a1, p->recursion_count, p->owner, drd_tid);
p->owner = drd_tid;
}
p->recursion_count++;
if (p->owner == DRD_INVALID_THREADID)
{
- MutexErrInfo MEI = { p->mutex, p->recursion_count, p->owner };
+ MutexErrInfo MEI = { p->a1, p->recursion_count, p->owner };
VG_(maybe_record_error)(vg_tid,
MutexErr,
VG_(get_IP)(vg_tid),
if (p->mutex_type != mutex_type)
{
VG_(message)(Vg_DebugMsg, "??? mutex %p: type changed from %d into %d",
- p->mutex, p->mutex_type, mutex_type);
+ p->a1, p->mutex_type, mutex_type);
}
tl_assert(p->mutex_type == mutex_type);
tl_assert(p->owner != DRD_INVALID_THREADID);
if (p->owner != drd_tid)
{
- MutexErrInfo MEI = { p->mutex, p->recursion_count, p->owner };
+ MutexErrInfo MEI = { p->a1, p->recursion_count, p->owner };
VG_(maybe_record_error)(vg_tid,
MutexErr,
VG_(get_IP)(vg_tid),
if (p->recursion_count < 0)
{
MutexErrInfo MEI
- = { p->mutex, p->recursion_count, p->owner };
+ = { p->a1, p->recursion_count, p->owner };
VG_(maybe_record_error)(vg_tid,
MutexErr,
VG_(get_IP)(vg_tid),
*/
void mutex_thread_delete(const DrdThreadId tid)
{
- int i;
- for (i = 0; i < sizeof(s_mutex)/sizeof(s_mutex[0]); i++)
+ struct mutex_info* p;
+
+ drd_clientobj_resetiter();
+ for ( ; (p = &drd_clientobj_next(ClientMutex)->mutex) != 0; )
{
- struct mutex_info* const p = &s_mutex[i];
- if (p->mutex && p->owner == tid && p->recursion_count > 0)
+ if (p->owner == tid && p->recursion_count > 0)
{
MutexErrInfo MEI
- = { p->mutex, p->recursion_count, p->owner };
+ = { p->a1, p->recursion_count, p->owner };
VG_(maybe_record_error)(VG_(get_running_tid)(),
MutexErr,
VG_(get_IP)(VG_(get_running_tid)()),
}
}
-void mutex_stop_using_mem(const Addr a1, const Addr a2)
-{
- unsigned i;
- for (i = 0; i < sizeof(s_mutex)/sizeof(s_mutex[0]); i++)
- {
- if (a1 <= s_mutex[i].mutex && s_mutex[i].mutex < a2)
- {
- tl_assert(s_mutex[i].mutex + s_mutex[i].size <= a2);
- mutex_destroy(&s_mutex[i]);
- }
- }
-}
-
ULong get_mutex_lock_count(void)
{
return s_mutex_lock_count;