First stage of mutex profiling.

Switched to trylock and update counters based on state.
This commit is contained in:
Qi Wang 2017-02-23 14:18:07 -08:00 committed by Qi Wang
parent 32e7cf51cd
commit 6309df628f
5 changed files with 149 additions and 32 deletions

View file

@ -1,9 +1,50 @@
#ifndef JEMALLOC_INTERNAL_MUTEX_STRUCTS_H
#define JEMALLOC_INTERNAL_MUTEX_STRUCTS_H
struct lock_prof_data_s {
/*
* Counters touched on the slow path, i.e. when there is lock
* contention. We update them once we have the lock.
*/
/* Total time spent waiting on this lock. */
nstime_t tot_wait_time;
/* Max time spent on a single lock operation. */
nstime_t max_wait_time;
/* # of times have to wait for this lock (after spinning). */
uint64_t n_wait_times;
/* # of times acquired the lock through local spinning. */
uint64_t n_spin_acquired;
/* Max # of threads waiting for the lock at the same time. */
uint32_t max_n_thds;
/* Current # of threads waiting on the lock. Atomic synced. */
uint32_t n_waiting_thds;
/*
* Data touched on the fast path. These are modified right after we
* grab the lock, so it's placed closest to the end (i.e. right before
* the lock) so that we have a higher chance of them being on the same
* cacheline.
*/
/* # of times the new lock holder is different from the previous one. */
uint64_t n_owner_switches;
/* Previous lock holder, to facilitate n_owner_switches. */
tsdn_t *prev_owner;
/* # of lock() operations in total. */
uint64_t n_lock_ops;
};
struct malloc_mutex_s {
union {
struct {
/*
* prof_data is defined first to reduce cacheline
* bouncing: the data is not touched by the lock holder
* during unlocking, while might be modified by
* contenders. Having it before the lock itself could
* avoid prefetching a modified cacheline (for the
* unlocking thread).
*/
lock_prof_data_t prof_data;
#ifdef _WIN32
# if _WIN32_WINNT >= 0x0600
SRWLOCK lock;
@ -22,7 +63,7 @@ struct malloc_mutex_s {
#endif
};
/*
* We only touch witness when configured w/ debug. However we
* We only touch witness when configured w/ debug. However we
* keep the field in a union when !debug so that we don't have
* to pollute the code base with #ifdefs, while avoid paying the
* memory cost.