Commits

Paweł Wieczorek committed 8179ba6

* poprawiono mutexy

Comments (0)

Files changed (3)

         "DEFERED",\
         "ASYNCHRONOUS")
 
+
+/**
+ * @brief wewnętrzna procedura inicjalizująca bibliotekę
+ * @warning zostanie wywołana sama w odpowiednim miejscu
+ */
 int
 pwuthread_init(void)
 {
     return r;
 }
 
-/*
- *
- */
 void
 pwuthread_log(const char *fmt, ...)
 {
     va_end(ap);
 }
 
-/*
- *
- */
 void
 pwuthread_perror(int e, const char *fmt, ...)
 {
     pwuthread_log("%s: %s (errno %i)", buf, ebuf, e);
 } 
 
-/*
- *
- */
 int
 pwuthread_equal(pwuthread_t a, pwuthread_t b)
 {
     return a == b;
 }
 
-/*
- *
- */
 pwuthread_t
 pwuthread_self(void)
 {
 #define ALLOC_SPECIFIC()\
     (pwuthread_value_s*)calloc(sizeof(pwuthread_value_s), PWUTHREAD_KEYS_MAX)
 
-/*
- *
+/**
+ * @brief inicjalizuje podsystem wartości prywatnych
  */
 void
 pwuthread_specific_init(void)
     memset(keys, 0, sizeof(keys));
 }
 
-/*
- *
+/**
+ * @brief tworzy prywatny segment pamięci dla danego wątku
  */
 void
 pwuthread_specific_create(pwuthread_t t)
     }
 }
 
-/*
- *
+/**
+ * @brief niszczy prywatny segment pamięci dla danego wątku
  */
 void
 pwuthread_specific_destroy(pwuthread_t t)
     free(t->specific);
 }
 
-/*
- *
+/**
+ * @brief tworzy nowy klucz
+ * @param k deskryptor klucza do uzupełnienia
+ * @param dtor destruktor (obecnie nie obsługiwany)
  */
 int
 pwuthread_key_create(pwuthread_key_t *k, pwuthread_keydtor_f *dtor)
     return r;
 }
 
-/*
- *
+/**
+ * @brief niszczy klucz
+ * @param k klucz
  */
 int
 pwuthread_key_destroy(pwuthread_key_t k)
     return 0;
 }
 
-/*
- *
+/**
+ * @brief wpisuje prywatną wartość pod dany klucz
+ * @param k klucz
+ * @param v wartość
  */
 int
 pwuthread_setspecific(pwuthread_key_t k, const void *v)
     return r;
 }
 
-/*
- *
+/**
+ * @brief wyciąga prywatną wartość z danego klucza
+ * @param k klucz
+ * @return wartość klucza (jeżeli nie była ustalona lub klucz nie jest
+ *         prawidłowy to NULL).
  */
 void *
 pwuthread_getspecific(pwuthread_key_t k)
 #include <assert.h>
 #include <unistd.h>
 
-static void mutex_lock(pwuthread_mutex_t m);
+static int mutex_lock(pwuthread_mutex_t m, pwuthread_t t);
 static void mutex_unlock(pwuthread_mutex_t m);
 
+/**
+ * @brief inicjalizuje zamek typu mutex
+ * @param _mtx referencja do deskryptora zamku
+ * @param n nie używane
+ */
 int
 pwuthread_mutex_init(pwuthread_mutex_t *_mtx, const void *n)
 {
     return 0;
 }
 
-
+/**
+ * @brief zamyka zamek (wchodzi do sekcji krytycznej)
+ * @param _mtx deskryptor zamka
+ * @return 0 jeżeli udało się zablokować zamek, EDEADLK gdy próba zamknięcia
+ *      zamka, którego jesteśmy już włascicielami
+ */
 int
 pwuthread_mutex_lock(pwuthread_mutex_t *_mtx)
 {
     pwuthread_sched_lock();
     cur = pwuthread_current;
     mtx = *_mtx;
+    if (mtx->owner == cur) {
+        r = EDEADLK;
+    } else {
+        if (!mutex_lock(mtx, pwuthread_current)) {
+            pwuthread_log("thread %p blocked by mutex %p", cur, mtx);
+            pwuthread_sched_wait();
+            pwuthread_log("thread %p got mutex %p", cur, mtx);            
+        }
+    }
+    /* stara implementacja, gorsza
     if (mtx->owner != NULL) {
         if (mtx->owner == cur) {
             pwuthread_log("thread %p do rec-lock on mutex %p", cur, mtx);
         pwuthread_log("thread %p locked mutex %p", cur, mtx);
         mtx->owner = cur;
     }
-
+    */
     pwuthread_sched_unlock();
     return r;
 }
 
+/**
+ * @brief próbuje zamknąć zamek (próbuje wejśc dosekcji krytycznej)
+ * @param _mtx deskryptor zamka
+ * @return 0 jeżeli udało się zablokować zamek, EDEADLK gdy próba zamknięcia
+ *      zamka, którego jesteśmy już włascicielami, -1 gdy zamek już ma
+ *      własciciela
+ */
+int
+pwuthread_mutex_trylock(pwuthread_mutex_t *_mtx)
+{
+    pwuthread_t cur;
+    pwuthread_mutex_s *mtx;
+    int r = 0;
+
+    pwuthread_sched_lock();
+    cur = pwuthread_current;
+    mtx = *_mtx;
+    if (mtx->owner == cur) {
+        r = EDEADLK;
+    } else
+    if (mtx->owner == NULL) {
+        mutex_lock(mtx, pwuthread_current);
+    } else {
+        r = -1;
+    }
+    pwuthread_sched_unlock();
+    return r;
+}
+
+/**
+ * @brief odblokowuje zamek (wychodzi z sekcji krytycznej)
+ * @param _mtx zamek którego obecny wątek jest właścicielem
+ * @return 0 gdy udało się odblokować zamek, EINVAL gdy nie jesteśmy
+ *         jego właścicielami.
+ */
 int
 pwuthread_mutex_unlock(pwuthread_mutex_t *_mtx)
 {
     return r;
 }
 
+/**
+ * @brief 
+ */
 int
 pwuthread_cond_init(pwuthread_cond_t *_cnd, const void *_)
 {
         mutex_unlock(mtx);
         list_insert_tail(&cnd->wait_list, pwuthread_current);
         pwuthread_sched_wait();
-        mutex_lock(mtx);
     } else {
         r = EPERM;
     }
     pwuthread_t t;
     pwuthread_sched_lock();
     t = list_extract_first(&cnd->wait_list);
-    if (t) list_insert_tail(&t->cond_mutex->wait_list, t);
+    if (t && mutex_lock(t->cond_mutex, t)) {
+        pwuthread_sched_wakeup(t);
+    }
     pwuthread_sched_unlock();
     return 0;
 }
     pwuthread_sched_lock();
     t = list_extract_first(&cnd->wait_list);
     for (; t; t = list_extract_first(&cnd->wait_list)) {
-        list_insert_tail(&t->cond_mutex->wait_list, t);
+        if (mutex_lock(t->cond_mutex, t)) {
+            pwuthread_sched_wakeup(t);
+        }
     }
     pwuthread_sched_unlock();
 
 }
 
 
-void
-mutex_lock(pwuthread_mutex_t mtx)
+int
+mutex_lock(pwuthread_mutex_t mtx, pwuthread_t t)
 {
-    mtx->owner = pwuthread_current;
+    int r = 0;
+    if (mtx->owner) {
+        list_insert_tail(&mtx->wait_list, t);
+    } else {
+        r = 1;
+        mtx->owner = t;
+    }
+    return r;
 }
 
 void