summaryrefslogtreecommitdiffstats
path: root/mutrace.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2009-09-14 19:39:11 +0200
committerLennart Poettering <lennart@poettering.net>2009-09-14 19:39:11 +0200
commitf72f5986fd3766a0a31b9feed724dcaa878732ee (patch)
treeda1944f5c3e398642cd2912f4ee5ffde123e2147 /mutrace.c
parent8036e35bb7bb42f40928b195543eb3c93cd4a87f (diff)
handle recursive mutexes properly
Diffstat (limited to 'mutrace.c')
-rw-r--r--mutrace.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/mutrace.c b/mutrace.c
index c576592..e02a011 100644
--- a/mutrace.c
+++ b/mutrace.c
@@ -270,7 +270,7 @@ static void mutex_info_stat(struct mutex_info *mi) {
return;
fprintf(stderr,
- "%8u %8u %8u %8u %12.3f %12.3f %12.3f%s\n",
+ "%8u %8u %8u %8u %12.3f %12.3f %12.3f%s%s\n",
mi->id,
mi->n_locked,
mi->n_owner_changed,
@@ -278,7 +278,8 @@ static void mutex_info_stat(struct mutex_info *mi) {
(double) mi->nsec_locked_total / 1000000.0,
(double) mi->nsec_locked_total / mi->n_locked / 1000000.0,
(double) mi->nsec_locked_max / 1000000.0,
- mi->broken ? " inconsistent!" : "");
+ mi->broken ? " (inconsistent)" : "",
+ mi->is_recursive ? " (recursive)" : "");
}
static void show_summary(void) {
@@ -453,7 +454,7 @@ static char* generate_stacktrace(void) {
return ret;
}
-static struct mutex_info *mutex_info_add(unsigned long u, pthread_mutex_t *mutex) {
+static struct mutex_info *mutex_info_add(unsigned long u, pthread_mutex_t *mutex, bool is_recursive) {
struct mutex_info *mi;
/* Needs external locking */
@@ -465,6 +466,7 @@ static struct mutex_info *mutex_info_add(unsigned long u, pthread_mutex_t *mutex
assert(mi);
mi->mutex = mutex;
+ mi->is_recursive = is_recursive;
mi->stacktrace = generate_stacktrace();
mi->next = alive_mutexes[u];
@@ -505,7 +507,7 @@ static struct mutex_info *mutex_info_acquire(pthread_mutex_t *mutex) {
if (mi->mutex == mutex)
return mi;
- return mutex_info_add(u, mutex);
+ return mutex_info_add(u, mutex, false);
}
static void mutex_info_release(pthread_mutex_t *mutex) {
@@ -524,12 +526,24 @@ int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexa
return r;
if (!recursive) {
+ bool is_recursive = false;
+
recursive = true;
u = mutex_hash(mutex);
lock_hash_mutex(u);
mutex_info_remove(u, mutex);
- mutex_info_add(u, mutex);
+
+ if (mutexattr) {
+ int type = 0, k;
+
+ k = pthread_mutexattr_gettype(mutexattr, &type);
+ assert(k == 0);
+
+ is_recursive = type == PTHREAD_MUTEX_RECURSIVE_NP;
+ }
+
+ mutex_info_add(u, mutex, is_recursive);
unlock_hash_mutex(u);
recursive = false;
@@ -561,7 +575,7 @@ static void mutex_lock(pthread_mutex_t *mutex, bool busy) {
recursive = true;
mi = mutex_info_acquire(mutex);
- if (mi->n_lock_level > 0) {
+ if (mi->n_lock_level > 0 && !mi->is_recursive) {
__sync_fetch_and_add(&n_broken, 1);
mi->broken = true;
}