]> git.sur5r.net Git - bacula/bacula/commitdiff
Add new bthread_mutex_t object that check mutex priority order
authorEric Bollengier <eric@eb.homelinux.org>
Tue, 8 Dec 2009 20:03:11 +0000 (21:03 +0100)
committerEric Bollengier <eric@eb.homelinux.org>
Tue, 8 Dec 2009 20:03:11 +0000 (21:03 +0100)
bacula/src/lib/lockmgr.c
bacula/src/lib/lockmgr.h
bacula/src/lib/rwlock.c
bacula/src/lib/rwlock.h

index 3342be2b7de0b3253ca8299153702b5c045f7c4c..d882da271ef7fa1b3dbd54139bd49a93494a741e 100644 (file)
 */
 
 #define _LOCKMGR_COMPLIANT
-#include "lockmgr.h"
+#include "bacula.h"
 
 #undef ASSERT
 #define ASSERT(x) if (!(x)) { \
    char *jcr = NULL; \
-   Pmsg3(000, _("%s:%i Failed ASSERT: %s\n"), __FILE__, __LINE__, #x); \
+   Pmsg3(000, _("Failed ASSERT: %s\n"), __FILE__, __LINE__, #x); \
+   jcr[0] = 0; }
+
+#define ASSERT_p(x,f,l) if (!(x)) {              \
+   char *jcr = NULL; \
+   Pmsg3(000, _("from %s:%i Failed ASSERT: %s\n"), f, l, #x); \
    jcr[0] = 0; }
 
 /*
@@ -139,13 +144,16 @@ public:
    dlink link;
    void *lock;
    lmgr_state_t state;
-   
+   int max_priority;
+   int priority;
+
    const char *file;
    int line;
 
    lmgr_lock_t() {
       lock = NULL;
       state = LMGR_LOCK_EMPTY;
+      priority = max_priority = 0;
    }
 
    lmgr_lock_t(void *l) {
@@ -228,6 +236,7 @@ public:
    lmgr_lock_t     lock_list[LMGR_MAX_LOCK];
    int current;
    int max;
+   int max_priority;
 
    lmgr_thread_t() {
       int status;
@@ -240,6 +249,7 @@ public:
       thread_id = pthread_self();
       current = -1;
       max = 0;
+      max_priority = 0;
    }
 
    void _dump(FILE *fp) {
@@ -264,9 +274,11 @@ public:
    /*
     * Call before a lock operation (mark mutex as WANTED)
     */
-   virtual void pre_P(void *m, const char *f="*unknown*", int l=0) {
-      ASSERT(current < LMGR_MAX_LOCK);
-      ASSERT(current >= -1);
+   virtual void pre_P(void *m, int priority, 
+                      const char *f="*unknown*", int l=0) {
+      ASSERT_p(current < LMGR_MAX_LOCK, f, l);
+      ASSERT_p(current >= -1, f, l);
+      ASSERT_p(!priority || priority >= max_priority, f, l);
       lmgr_p(&mutex);
       {
          current++;
@@ -274,7 +286,10 @@ public:
          lock_list[current].state = LMGR_LOCK_WANTED;
          lock_list[current].file = f;
          lock_list[current].line = l;
+         lock_list[current].priority = priority;
+         lock_list[current].max_priority = MAX(priority, max_priority);
          max = MAX(current, max);
+         max_priority = MAX(priority, max_priority);
       }
       lmgr_v(&mutex);
    }
@@ -288,6 +303,7 @@ public:
       lock_list[current].state = LMGR_LOCK_GRANTED;
    }
    
+   /* Using this function is some sort of bug */
    void shift_list(int i) {
       for(int j=i+1; j<=current; j++) {
          lock_list[i] = lock_list[j];
@@ -296,13 +312,19 @@ public:
          lock_list[current].lock = NULL;
          lock_list[current].state = LMGR_LOCK_EMPTY;
       }
+      /* rebuild the priority list */
+      max_priority = 0;
+      for(int j=0; j< current; j++) {
+         max_priority = MAX(lock_list[j].priority, max_priority);
+         lock_list[j].max_priority = max_priority;
+      }
    }
 
    /*
     * Remove the mutex from the list
     */
    virtual void do_V(void *m, const char *f="*unknown*", int l=0) {
-      ASSERT(current >= 0);
+      ASSERT_p(current >= 0, f, l);
       lmgr_p(&mutex);
       {
          if (lock_list[current].lock == m) {
@@ -326,6 +348,12 @@ public:
                }
             }
          }
+         /* reset max_priority to the last one */
+         if (current >= 0) {
+            max_priority = lock_list[current].max_priority; 
+         } else {
+            max_priority = 0;
+         }
       }
       lmgr_v(&mutex);
    }
@@ -341,7 +369,7 @@ class lmgr_dummy_thread_t: public lmgr_thread_t
 {
    void do_V(void *m, const char *file, int l)  {}
    void post_P()                                {}
-   void pre_P(void *m, const char *file, int l) {}
+   void pre_P(void *m, int priority, const char *file, int l) {}
 };
 
 /*
@@ -357,6 +385,7 @@ static pthread_key_t lmgr_key;  /* used to get lgmr_thread_t object */
 static dlist *global_mgr = NULL;  /* used to store all lgmr_thread_t objects */
 static pthread_mutex_t lmgr_global_mutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_t undertaker;
+static bool use_undertaker=true;
 
 #define lmgr_is_active() (global_mgr != NULL)
 
@@ -554,12 +583,14 @@ void create_lmgr_key()
    lmgr_thread_t *n=NULL;
    global_mgr = New(dlist(n, &n->link));
 
-   status = pthread_create(&undertaker, NULL, check_deadlock, NULL);
-   if (status != 0) {
-      berrno be;
-      Pmsg1(000, _("pthread_create failed: ERR=%s\n"),
-            be.bstrerror(status));
-      ASSERT(0);
+   if (use_undertaker) {
+      status = pthread_create(&undertaker, NULL, check_deadlock, NULL);
+      if (status != 0) {
+         berrno be;
+         Pmsg1(000, _("pthread_create failed: ERR=%s\n"),
+               be.bstrerror(status));
+         ASSERT(0);
+      }
    }
 }
 
@@ -606,7 +637,9 @@ void lmgr_cleanup_main()
    if (!global_mgr) {
       return;
    }
-   pthread_cancel(undertaker);
+   if (use_undertaker) {
+      pthread_cancel(undertaker);
+   }
    lmgr_cleanup_thread();
    lmgr_p(&lmgr_global_mutex);
    {
@@ -617,15 +650,40 @@ void lmgr_cleanup_main()
    lmgr_v(&lmgr_global_mutex);
 }
 
+/* 
+ * Set the priority of the lmgr mutex object
+ */
+void bthread_mutex_set_priority(bthread_mutex_t *m, int prio)
+{
+   m->priority = prio;
+}
+
+/*
+ * Replacement for pthread_mutex_init()
+ */
+int bthread_mutex_init(bthread_mutex_t *m, const pthread_mutexattr_t *attr)
+{
+   m->priority = 0;
+   return pthread_mutex_init(&m->mutex, attr);
+}
+
+/*
+ * Replacement for pthread_mutex_destroy()
+ */
+int bthread_mutex_destroy(bthread_mutex_t *m)
+{
+   return pthread_mutex_destroy(&m->mutex);
+}
+
 /*
  * Replacement for pthread_mutex_lock()
  * Returns always ok 
  */
-int lmgr_mutex_lock(pthread_mutex_t *m, const char *file, int line)
+int bthread_mutex_lock_p(bthread_mutex_t *m, const char *file, int line)
 {
    lmgr_thread_t *self = lmgr_get_thread_info();
-   self->pre_P(m, file, line);
-   lmgr_p(m);
+   self->pre_P(m, m->priority, file, line);
+   lmgr_p(&m->mutex);
    self->post_P();   
    return 0;
 }
@@ -634,7 +692,32 @@ int lmgr_mutex_lock(pthread_mutex_t *m, const char *file, int line)
  * Replacement for pthread_mutex_unlock()
  * Returns always ok
  */
-int lmgr_mutex_unlock(pthread_mutex_t *m, const char *file, int line)
+int bthread_mutex_unlock_p(bthread_mutex_t *m, const char *file, int line)
+{
+   lmgr_thread_t *self = lmgr_get_thread_info();
+   self->do_V(m, file, line);
+   lmgr_v(&m->mutex);
+   return 0;
+}
+
+/*
+ * Replacement for pthread_mutex_lock() but with real pthread_mutex_t
+ * Returns always ok 
+ */
+int bthread_mutex_lock_p(pthread_mutex_t *m, const char *file, int line)
+{
+   lmgr_thread_t *self = lmgr_get_thread_info();
+   self->pre_P(m, 0, file, line);
+   lmgr_p(m);
+   self->post_P();   
+   return 0;
+}
+
+/*
+ * Replacement for pthread_mutex_unlock() but with real pthread_mutex_t
+ * Returns always ok
+ */
+int bthread_mutex_unlock_p(pthread_mutex_t *m, const char *file, int line)
 {
    lmgr_thread_t *self = lmgr_get_thread_info();
    self->do_V(m, file, line);
@@ -642,17 +725,65 @@ int lmgr_mutex_unlock(pthread_mutex_t *m, const char *file, int line)
    return 0;
 }
 
+
+/* TODO: check this
+ */
+int bthread_cond_wait_p(pthread_cond_t *cond,
+                        pthread_mutex_t *m,
+                        const char *file, int line)
+{
+   int ret;
+   lmgr_thread_t *self = lmgr_get_thread_info();
+   self->do_V(m, file, line);   
+   ret = pthread_cond_wait(cond, m);
+   self->pre_P(m, 0, file, line);
+   self->post_P();
+   return ret;
+}
+
+/* TODO: check this
+ */
+int bthread_cond_timedwait_p(pthread_cond_t *cond,
+                             pthread_mutex_t *m,
+                             const struct timespec * abstime,
+                             const char *file, int line)
+{
+   int ret;
+   lmgr_thread_t *self = lmgr_get_thread_info();
+   self->do_V(m, file, line);   
+   ret = pthread_cond_timedwait(cond, m, abstime);
+   self->pre_P(m, 0, file, line);
+   self->post_P();
+   return ret;
+}
+
 /* TODO: check this
  */
-int lmgr_cond_wait(pthread_cond_t *cond,
-                   pthread_mutex_t *mutex,
-                   const char *file, int line)
+int bthread_cond_wait_p(pthread_cond_t *cond,
+                        bthread_mutex_t *m,
+                        const char *file, int line)
 {
    int ret;
    lmgr_thread_t *self = lmgr_get_thread_info();
-   self->do_V(mutex, file, line);   
-   ret = pthread_cond_wait(cond, mutex);
-   self->pre_P(mutex, file, line);
+   self->do_V(m, file, line);   
+   ret = pthread_cond_wait(cond, &m->mutex);
+   self->pre_P(m, m->priority, file, line);
+   self->post_P();
+   return ret;
+}
+
+/* TODO: check this
+ */
+int bthread_cond_timedwait_p(pthread_cond_t *cond,
+                             bthread_mutex_t *m,
+                             const struct timespec * abstime,
+                             const char *file, int line)
+{
+   int ret;
+   lmgr_thread_t *self = lmgr_get_thread_info();
+   self->do_V(m, file, line);   
+   ret = pthread_cond_timedwait(cond, &m->mutex, abstime);
+   self->pre_P(m, m->priority, file, line);
    self->post_P();
    return ret;
 }
@@ -660,14 +791,14 @@ int lmgr_cond_wait(pthread_cond_t *cond,
 /*
  * Use this function when the caller handle the mutex directly
  *
- * lmgr_pre_lock(m);
+ * lmgr_pre_lock(m, 10);
  * pthread_mutex_lock(m);
  * lmgr_post_lock(m);
  */
-void lmgr_pre_lock(void *m, const char *file, int line)
+void lmgr_pre_lock(void *m, int prio, const char *file, int line)
 {
    lmgr_thread_t *self = lmgr_get_thread_info();
-   self->pre_P(m, file, line);
+   self->pre_P(m, prio, file, line);
 }
 
 /*
@@ -682,10 +813,10 @@ void lmgr_post_lock()
 /*
  * Do directly pre_P and post_P (used by trylock)
  */
-void lmgr_do_lock(void *m, const char *file, int line)
+void lmgr_do_lock(void *m, int prio, const char *file, int line)
 {
    lmgr_thread_t *self = lmgr_get_thread_info();
-   self->pre_P(m, file, line);
+   self->pre_P(m, prio, file, line);
    self->post_P();
 }
 
@@ -751,21 +882,27 @@ void dbg_print_lock(FILE *fp)
 #ifdef _TEST_IT
 
 #include "lockmgr.h"
-#define pthread_mutex_lock(x)   lmgr_mutex_lock(x)
-#define pthread_mutex_unlock(x) lmgr_mutex_unlock(x)
-#define pthread_cond_wait(x,y)  lmgr_cond_wait(x,y)
-#define pthread_create(a, b, c, d)  lmgr_thread_create(a,b,c,d)
+#define BTHREAD_MUTEX_NO_PRIORITY      {PTHREAD_MUTEX_INITIALIZER, 0}
+#define BTHREAD_MUTEX_PRIORITY_1       {PTHREAD_MUTEX_INITIALIZER, 1}
+#define BTHREAD_MUTEX_PRIORITY_2       {PTHREAD_MUTEX_INITIALIZER, 2}
+#define BTHREAD_MUTEX_PRIORITY_3       {PTHREAD_MUTEX_INITIALIZER, 3}
+#define BTHREAD_MUTEX_PRIORITY_4       {PTHREAD_MUTEX_INITIALIZER, 4}
 #undef P
 #undef V
-#define P(x) lmgr_mutex_lock(&(x), __FILE__, __LINE__)
-#define V(x) lmgr_mutex_unlock(&(x), __FILE__, __LINE__)
-
-pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
-pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
-pthread_mutex_t mutex3 = PTHREAD_MUTEX_INITIALIZER;
-pthread_mutex_t mutex4 = PTHREAD_MUTEX_INITIALIZER;
-pthread_mutex_t mutex5 = PTHREAD_MUTEX_INITIALIZER;
-pthread_mutex_t mutex6 = PTHREAD_MUTEX_INITIALIZER;
+#define P(x) bthread_mutex_lock_p(&(x), __FILE__, __LINE__)
+#define V(x) bthread_mutex_unlock_p(&(x), __FILE__, __LINE__)
+#define pthread_create(a, b, c, d)    lmgr_thread_create(a,b,c,d)
+
+bthread_mutex_t mutex1 = BTHREAD_MUTEX_NO_PRIORITY;
+bthread_mutex_t mutex2 = BTHREAD_MUTEX_NO_PRIORITY;
+bthread_mutex_t mutex3 = BTHREAD_MUTEX_NO_PRIORITY;
+bthread_mutex_t mutex4 = BTHREAD_MUTEX_NO_PRIORITY;
+bthread_mutex_t mutex5 = BTHREAD_MUTEX_NO_PRIORITY;
+bthread_mutex_t mutex6 = BTHREAD_MUTEX_NO_PRIORITY;
+bthread_mutex_t mutex_p1 = BTHREAD_MUTEX_PRIORITY_1;
+bthread_mutex_t mutex_p2 = BTHREAD_MUTEX_PRIORITY_2;
+bthread_mutex_t mutex_p3 = BTHREAD_MUTEX_PRIORITY_3;
+static const char *my_prog;
 
 void *self_lock(void *temp)
 {
@@ -786,9 +923,9 @@ void *nolock(void *temp)
 
 void *locker(void *temp)
 {
-   pthread_mutex_t *m = (pthread_mutex_t*) temp;
-   lmgr_p(m);
-   lmgr_v(m);
+   bthread_mutex_t *m = (bthread_mutex_t*) temp;
+   P(*m);
+   V(*m);
    return NULL;
 }
 
@@ -872,6 +1009,14 @@ void *th3(void *a) {
    return NULL;
 }
 
+void *th_prio(void *a) {
+   char buf[512];
+   bstrncpy(buf, my_prog, sizeof(buf));
+   bstrncat(buf, " priority", sizeof(buf));
+   int ret = system(buf);
+   return (void*) ret;
+}
+
 int err=0;
 int nb=0;
 void _ok(const char *file, int l, const char *op, int value, const char *label)
@@ -912,15 +1057,28 @@ int report()
  *  - lock/unlock in wrong order
  *  - deadlock with 2 or 3 threads
  */
-int main()
+int main(int argc, char **argv)
 {
+   void *ret=NULL;
+   lmgr_thread_t *self;
    pthread_t id1, id2, id3, tab[200];
+   my_prog = argv[0];
+
+   use_undertaker = false;
    lmgr_init_thread();
 
+   if (argc == 2) {             /* do priority check */
+      P(mutex_p2);                /* not permited */
+      P(mutex_p1);
+      V(mutex_p1);                /* never goes here */
+      V(mutex_p2);
+      return 0;
+   }
+
    pthread_create(&id1, NULL, self_lock, NULL);
    sleep(2);
    ok(lmgr_detect_deadlock(), "Check self deadlock");
-   lmgr_v(&mutex1);             /* a bit dirty */
+   lmgr_v(&mutex1.mutex);                /* a bit dirty */
    pthread_join(id1, NULL);
 
 
@@ -997,6 +1155,48 @@ int main()
    sleep(1);
    ok(lmgr_detect_deadlock(), "Check for deadlock");
 
+   pthread_create(&id3, NULL, th_prio, NULL);
+   pthread_join(id3, &ret);
+   ok(ret != 0, "Check for priority segfault");
+
+   self = lmgr_get_thread_info();
+   P(mutex_p1);
+   ok(self->max_priority == 1, "Check max_priority 1/4");
+   P(mutex_p2);
+   ok(self->max_priority == 2, "Check max_priority 2/4");
+   P(mutex_p3);
+   ok(self->max_priority == 3, "Check max_priority 3/4");
+   P(mutex6);
+   ok(self->max_priority == 3, "Check max_priority 4/4");
+   V(mutex6);
+   ok(self->max_priority == 3, "Check max_priority 1/5");
+   V(mutex_p3);
+   ok(self->max_priority == 2, "Check max_priority 4/5");
+   V(mutex_p2);
+   ok(self->max_priority == 1, "Check max_priority 4/5");
+   V(mutex_p1);
+   ok(self->max_priority == 0, "Check max_priority 5/5");
+
+
+   P(mutex_p1);
+   P(mutex_p2);
+   P(mutex_p3);
+   P(mutex6);
+   ok(self->max_priority == 3, "Check max_priority mixed");
+   V(mutex_p2);
+   ok(self->max_priority == 3, "Check max_priority mixed");
+   V(mutex_p1);
+   ok(self->max_priority == 3, "Check max_priority mixed");
+   V(mutex_p3);
+   ok(self->max_priority == 0, "Check max_priority mixed");
+   V(mutex6);
+   ok(self->max_priority == 0, "Check max_priority mixed");
+
+   P(mutex_p1);
+   P(mutex_p2);
+   V(mutex_p1);
+   V(mutex_p2);
+
 //   lmgr_dump();
 //
 //   pthread_create(&id3, NULL, th3, NULL);
index 697b84483826ce8da3caa237dbff40982a62f7e4..fdde9c7a2add07a9ec71de8843f39b7a86321d17 100644 (file)
@@ -29,8 +29,6 @@
 #ifndef _LOCKMGR_H
 #define _LOCKMGR_H 1
 
-#include "bacula.h"
-
 /*
  * P and V op that don't use the lock manager (for memory allocation or on
  * win32)
@@ -40,40 +38,74 @@ void lmgr_v(pthread_mutex_t *m);
 
 #ifdef _USE_LOCKMGR
 
+typedef struct bthread_mutex_t
+{
+   pthread_mutex_t mutex;
+   int priority;
+} bthread_mutex_t;
+
 /* 
  * We decide that a thread won't lock more than LMGR_MAX_LOCK at the same time
  */
 #define LMGR_MAX_LOCK 32
 
-/* Not yet working */
-int lmgr_cond_wait(pthread_cond_t *cond,
-                   pthread_mutex_t *mutex,
-                   const char *file="*unknown*", int line=0);
+int bthread_cond_wait_p(pthread_cond_t *cond,
+                        bthread_mutex_t *mutex,
+                        const char *file="*unknown*", int line=0);
+
+int bthread_cond_timedwait_p(pthread_cond_t *cond,
+                             bthread_mutex_t *mutex,
+                             const struct timespec * abstime,
+                             const char *file="*unknown*", int line=0);
+
+/* Same with real pthread_mutex_t */
+int bthread_cond_wait_p(pthread_cond_t *cond,
+                        pthread_mutex_t *mutex,
+                        const char *file="*unknown*", int line=0);
+
+int bthread_cond_timedwait_p(pthread_cond_t *cond,
+                             pthread_mutex_t *mutex,
+                             const struct timespec * abstime,
+                             const char *file="*unknown*", int line=0);
+
+/* Replacement of pthread_mutex_lock()  but with real pthread_mutex_t */
+int bthread_mutex_lock_p(pthread_mutex_t *m, 
+                         const char *file="*unknown*", int line=0);
+
+/* Replacement for pthread_mutex_unlock() but with real pthread_mutex_t */
+int bthread_mutex_unlock_p(pthread_mutex_t *m,
+                           const char *file="*unknown*", int line=0);
 
 /* Replacement of pthread_mutex_lock() */
-int lmgr_mutex_lock(pthread_mutex_t *m, 
-                    const char *file="*unknown*", int line=0);
+int bthread_mutex_lock_p(bthread_mutex_t *m, 
+                         const char *file="*unknown*", int line=0);
 
 /* Replacement of pthread_mutex_unlock() */
-int lmgr_mutex_unlock(pthread_mutex_t *m, 
-                      const char *file="*unknown*", int line=0);
+int bthread_mutex_unlock_p(bthread_mutex_t *m, 
+                           const char *file="*unknown*", int line=0);
 
 /* 
  * Use them when you want use your lock yourself (ie rwlock)
  */
 
 /* Call before requesting the lock */
-void lmgr_pre_lock(void *m, const char *file="*unknown*", int line=0);
+void lmgr_pre_lock(void *m, int prio=0,
+                   const char *file="*unknown*", int line=0);
 
 /* Call after getting it */ 
 void lmgr_post_lock();
 
 /* Same as pre+post lock */
-void lmgr_do_lock(void *m, const char *file="*unknown*", int line=0);
+void lmgr_do_lock(void *m, int prio=0, 
+                  const char *file="*unknown*", int line=0);
 
 /* Call just before releasing the lock */
 void lmgr_do_unlock(void *m); 
 
+int bthread_mutex_init(bthread_mutex_t *m, const pthread_mutexattr_t *attr);
+int bthread_mutex_destroy(bthread_mutex_t *m);
+void bthread_mutex_set_priority(bthread_mutex_t *m, int prio);
+
 /*
  * Each thread have to call this function to put a lmgr_thread_t object
  * in the stack and be able to call mutex_lock/unlock
@@ -120,16 +152,28 @@ int lmgr_thread_create(pthread_t *thread,
  * Define _LOCKMGR_COMPLIANT to use real pthread functions
  */
 
+#define BTHREAD_MUTEX_NO_PRIORITY     {PTHREAD_MUTEX_INITIALIZER, 0}
+#define BTHREAD_MUTEX_PRIORITY_1      {PTHREAD_MUTEX_INITIALIZER, 1}
+#define BTHREAD_MUTEX_PRIORITY_2      {PTHREAD_MUTEX_INITIALIZER, 2}
+#define BTHREAD_MUTEX_PRIORITY_3      {PTHREAD_MUTEX_INITIALIZER, 3}
+#define BTHREAD_MUTEX_PRIORITY_4      {PTHREAD_MUTEX_INITIALIZER, 4}
+#define BTHREAD_MUTEX_INITIALIZER     BTHREAD_MUTEX_NO_PRIORITY
+#define bthread_mutex_lock(x)      bthread_mutex_lock_p(x, __FILE__, __LINE__)
+#define bthread_mutex_unlock(x)    bthread_mutex_unlock_p
+#define bthread_cond_wait(x,y)     bthread_cond_wait_p(x,y, __FILE__, __LINE__)
+#define bthread_cond_timedwait(x,y,z) bthread_cond_timedwait_p(x,y,z, __FILE__, __LINE__)
+
 #ifdef _LOCKMGR_COMPLIANT
 # define P(x) lmgr_p(&(x))
 # define V(x) lmgr_v(&(x))
 #else
-# define P(x) lmgr_mutex_lock(&(x), __FILE__, __LINE__)
-# define V(x) lmgr_mutex_unlock(&(x), __FILE__, __LINE__)
-# define pthread_mutex_lock(x)       lmgr_mutex_lock(x, __FILE__, __LINE__)
-# define pthread_mutex_unlock(x)     lmgr_mutex_unlock(x, __FILE__, __LINE__)
-# define pthread_cond_wait(x,y)      lmgr_cond_wait(x,y, __FILE__, __LINE__)
-# define pthread_create(a, b, c, d)  lmgr_thread_create(a,b,c,d)
+# define P(x)                   bthread_mutex_lock_p(&(x), __FILE__, __LINE__)
+# define V(x)                   bthread_mutex_unlock_p(&(x), __FILE__, __LINE__)
+# define pthread_create(a, b, c, d)      lmgr_thread_create(a,b,c,d)
+# define pthread_mutex_lock(x)           bthread_mutex_lock(x)
+# define pthread_mutex_unlock(x)         bthread_mutex_unlock(x)
+# define pthread_cond_wait(x,y)          bthread_cond_wait(x,y)
+# define pthread_cond_timedwait(x,y,z)   bthread_cond_timedwait(x,y,z)
 #endif
 
 #else   /* _USE_LOCKMGR */
@@ -143,9 +187,22 @@ int lmgr_thread_create(pthread_t *thread,
 # define lmgr_do_lock(m, f, l)
 # define lmgr_do_unlock(m)
 # define lmgr_cleanup_main()
+# define bthread_mutex_set_priority(a)
+# define bthread_mutex_init(a,b)     pthread_mutex_init(a,b)
+# define bthread_mutex_destroy(a)    pthread_mutex_destroy(a)
+# define bthread_mutex_lock(a)       pthread_mutex_lock(a)
+# define bthread_mutex_unlock(a)     pthread_mutex_unlock(a)
+# define lmgr_cond_wait(a,b)         pthread_cond_wait(a,b)
+# define lmgr_cond_timedwait(a,b,c)  pthread_cond_timedwait(a,b,c)
+# define bthread_mutex_t             pthread_mutex_t
 # define P(x) lmgr_p(&(x))
 # define V(x) lmgr_v(&(x))
-
+# define BTHREAD_MUTEX_NO_PRIORITY  PTHREAD_MUTEX_INITIALIZER
+# define BTHREAD_MUTEX_PRIORITY_1   PTHREAD_MUTEX_INITIALIZER
+# define BTHREAD_MUTEX_PRIORITY_2   PTHREAD_MUTEX_INITIALIZER
+# define BTHREAD_MUTEX_PRIORITY_3   PTHREAD_MUTEX_INITIALIZER
+# define BTHREAD_MUTEX_PRIORITY_4   PTHREAD_MUTEX_INITIALIZER
+# define BTHREAD_MUTEX_INITIALIZER  PTHREAD_MUTEX_INITIALIZER
 #endif  /* _USE_LOCKMGR */
 
 #endif  /* _LOCKMGR_H */
index e91b9eab373d02f67bfef8faa74d4a18a819e2bc..0647343aa58ec3f452453e407904d7a96ed57a84 100644 (file)
  *  Returns: 0 on success
  *           errno on failure
  */
-int rwl_init(brwlock_t *rwl)
+int rwl_init(brwlock_t *rwl, int prio)
 {
    int stat;
 
    rwl->r_active = rwl->w_active = 0;
    rwl->r_wait = rwl->w_wait = 0;
+   rwl->priority = prio;
    if ((stat = pthread_mutex_init(&rwl->mutex, NULL)) != 0) {
       return stat;
    }
@@ -233,7 +234,7 @@ int rwl_writelock(brwlock_t *rwl)
       pthread_mutex_unlock(&rwl->mutex);
       return 0;
    }
-   lmgr_pre_lock(rwl, __FILE__, __LINE__);
+   lmgr_pre_lock(rwl, rwl->priority, __FILE__, __LINE__);
    if (rwl->w_active || rwl->r_active > 0) {
       rwl->w_wait++;                  /* indicate that we are waiting */
       pthread_cleanup_push(rwl_write_release, (void *)rwl);
@@ -278,7 +279,7 @@ int rwl_writetrylock(brwlock_t *rwl)
    } else {
       rwl->w_active = 1;              /* we are running */
       rwl->writer_id = pthread_self(); /* save writer thread's id */
-      lmgr_do_lock(rwl, __FILE__, __LINE__);
+      lmgr_do_lock(rwl, rwl->priority, __FILE__, __LINE__);
    }
    stat2 = pthread_mutex_unlock(&rwl->mutex);
    return (stat == 0 ? stat2 : stat);
index f03af8eb9f949b748382b59d4b4bce0a9f0dd0a9..7c5847636d9f09c83b652c5ee998f72acc4e7d8b 100644 (file)
@@ -46,6 +46,7 @@ typedef struct s_rwlock_tag {
    pthread_cond_t    read;            /* wait for read */
    pthread_cond_t    write;           /* wait for write */
    pthread_t         writer_id;       /* writer's thread id */
+   int               priority;        /* used in deadlock detection */
    int               valid;           /* set when valid */
    int               r_active;        /* readers active */
    int               w_active;        /* writers active */
@@ -68,7 +69,7 @@ typedef struct s_rwsteal_tag {
 /*
  * read/write lock prototypes
  */
-extern int rwl_init(brwlock_t *wrlock);
+extern int rwl_init(brwlock_t *wrlock, int priority=0);
 extern int rwl_destroy(brwlock_t *rwlock);
 extern int rwl_readlock(brwlock_t *rwlock);
 extern int rwl_readtrylock(brwlock_t *rwlock);