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;
}