El dom, 17-11-2002 a las 16:30, Neal H. Walfield escribió:
> > Is there a replacement for CPROC_SWITCHING and CPROC_RUNNING in
> > cproc_t->state, to know if a thread has been waken up?
> 
> No.  We do not need it.
> 
I should have sent more info last message.

> > Can a thread be waken up if it hasnt been blocked?
> 
> pthread_state has nothing to do with that.  Threads are put to sleep
> via __pthread_block and awoken with __pthread_wakeup.
> 

I attach here a diff of another hurd_condition_wait example. 
Is there a race condition before __pthread_block? We can receive
pthread_broadcast before we have blocked.
If so, how do we solve that? 
Would then be necessary a replacement for CPROC_SWITCHING/RUNNING?

--

Thanks,
Vicente.

--- hurd_condition_wait.old.c   2002-11-17 17:41:49.000000000 +0100
+++ hurd_condition_wait.c       2002-11-17 13:01:02.000000000 +0100
@@ -1,21 +1,20 @@
 /* Just like condition_wait, but cancellable.  Returns true if cancelled.  */
 int
-hurd_condition_wait (condition_t c, mutex_t m)
+hurd_condition_wait (pthread_cond_t c, pthread_mutex_t m)
 {
   /* This function will be called by hurd_thread_cancel while we are blocked
      in the condition_wait.  We wake up all threads blocked on C,
      so our thread will wake up and notice the cancellation flag.  */
   void cancel_me (void)
     {
-      condition_broadcast (c);
+      pthread_cond_broadcast (&c);
     }
   struct hurd_sigstate *ss = _hurd_self_sigstate ();
-  cproc_t p = cproc_self ();
+  struct __pthread *self = _pthread_self ();
   int cancel;
 
   assert (ss->intr_port == MACH_PORT_NULL); /* Sanity check for signal bugs. */
 
-  p->state = CPROC_CONDWAIT | CPROC_SWITCHING;
 
   /* Atomically enqueue our cproc on the condition variable's queue of
      waiters, and mark our sigstate to indicate that `cancel_me' must be
@@ -24,8 +23,8 @@
      hurd_thread_cancel can never suspend us and then deadlock in
      condition_broadcast waiting for the condition variable's lock.  */
 
-  spin_lock (&ss->lock);
-  spin_lock (&c->lock);
+  __pthread_spin_lock (&ss->lock);
+  __pthread_spin_lock (&c->__lock);
   cancel = ss->cancel;
   if (cancel)
     /* We were cancelled before doing anything.  Don't block at all.  */
@@ -34,46 +33,26 @@
     {
       /* Put us on the queue so that condition_broadcast will know to wake
          us up.  */
-      cthread_queue_enq (&c->queue, p);
+      __pthread_enqueue (&c->__queue, self);
       /* Tell hurd_thread_cancel how to unblock us.  */
       ss->cancel_hook = &cancel_me;
     }
-  spin_unlock (&c->lock);
-  spin_unlock (&ss->lock);
+  __pthread_spin_unlock (&c->__lock);
+  __pthread_spin_unlock (&ss->lock);
 
   if (cancel)
     {
       /* Cancelled on entry.  Just leave the mutex locked.  */
       m = NULL;
-      p->state = CPROC_RUNNING;
     }
   else
     {
       /* Now unlock the mutex and block until woken.  */
-
-#ifdef WAIT_DEBUG
-      p->waiting_for = (char *)c;
-#endif  /* WAIT_DEBUG */
-
-      mutex_unlock (m);
-
-      spin_lock (&p->lock);
-      if (p->state & CPROC_SWITCHING)
-       cproc_block ();
-      else
-       {
-         /* We were woken up someplace before reacquiring P->lock.
-            We can just continue on.  */
-         p->state = CPROC_RUNNING;
-         spin_unlock(&p->lock);
-       }
-
-#ifdef WAIT_DEBUG
-      p->waiting_for = (char *)0;
-#endif  /* WAIT_DEBUG */
+      pthread_mutex_unlock (&m);
+      __pthread_block (self);
     }
 
-  spin_lock (&ss->lock);
+  __pthread_spin_lock (&ss->lock);
   /* Clear the hook, now that we are done blocking.  */
   ss->cancel_hook = NULL;
   /* Check the cancellation flag; we might have unblocked due to
@@ -82,11 +61,11 @@
      right after waking up).  */
   cancel |= ss->cancel;
   ss->cancel = 0;
-  spin_unlock (&ss->lock);
+  __pthread_spin_unlock (&ss->lock);
 
   if (m)
     /* Reacquire the mutex and return.  */
-    mutex_lock (m);
+    __pthread_mutex_lock (&m);
 
   return cancel;
 }

Reply via email to