9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
From: Russ Cox <russcox@gmail.com>
To: Sergey Reva <rs_rlab@mail.ru>,
	Fans of the OS Plan 9 from Bell Labs <9fans@cse.psu.edu>
Subject: Re: [9fans] How it work?
Date: Fri, 25 Mar 2005 12:08:14 -0500	[thread overview]
Message-ID: <ee9e417a05032509081c7815cd@mail.gmail.com> (raw)
In-Reply-To: <676328296.20050325123343@mail.ru>

lock(2):

          Rendezes are rendezvous points.  Each Rendez r is protected
          by a QLock r->l, which must be held by the callers of
          rsleep, rwakeup, and rwakeupall. Rsleep atomically releases
          r->l and suspends execution of the calling task.  After
          resuming execution, rsleep will reacquire r->l before
          returning.  If any processes are sleeping on r, rwakeup
          wakes one of them.  it returns 1 if a process was awakened,
          0 if not.  Rwakeupall wakes all processes sleeping on r,
          returning the number of processes awakened.  Rwakeup and
          rwakeupall do not release r->l and do not suspend execution
          of the current task.

          Before use, Rendezes should be initialized to all zeros
          except for r->l pointer, which should point at the QLock
          that will guard r.

You're not locking the qlock first.

> I can use lock, qlock and rendezvous without any problem but Rendez
> don't work... if rsleep executed earlier than rwakeup, abort() cause
> exception, stk() show:
> rsleep ... /sys/src/libc/9sys/qlock.c:286
> This line contain me = getqlp() in getqlp i find abort()...

You're being misled.  The line that stk() shows is the
code that the call to abort will return to, which is
sometimes the next line of code.  The actual
call is earlier, on line 283 or so:

	/* we should hold the qlock */
	if(!r->l->locked)
>		abort();

	/* add ourselves to the wait list */
	me = getqlp();

Since getqlp wasn't on your stack frame, you can be
pretty sure that's not what called abort.  (The Plan 9
compilers thankfully don't do any tail call elimination.)

> in other way when rwakeup executed first, abort() ... stk() show:
> rwakeup ... /sys/src/libc/9sys/qlock.c:329
> which point me to another abort()

This time the line ref is correct.

> Maybe it wrong initialization? But I also try other way... or I wrong
> use rendez?

Well, yes.  In addition to not locking the qlock before
calling rsleep or rwakeup, you're not actually checking
a condition.

>         for(;;)
>         {
>                 print("Sleep\n");
>                 rsleep(&r);
>                 print("Wake up!\n");
>         }

>         for (x=0;x<10;)
>         {
>                 if (rwakeup(&r))
>                         x++;
>         }

I guess this technically will work, but the standard usage
is that you're expecting some condition to happen, like
there's a shared queue and one thread is waiting for more
input and the other thread, which has just added to the queue,
wants to wake him.  Commonly you see:

    qlock(&l);
    while(bad condition)
        rsleep(&r);
    code depending on good condition
    qunlock(&l)

and

    qlock(&l)
    make condition good
    rwakeup(&r)
    qunlock(&l)

It's like the sleep and wakeup in the kernel except that
the locking is a little different.

See http://swtch.com/usr/local/plan9/src/libmux/queue.c
for a full example.  It's an arbitrarily buffered queue.
The Rendez q->r is slept on by receivers waiting for
something to be put into the queue.

Russ


      reply	other threads:[~2005-03-25 17:08 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-03-22 19:00 Sergey Reva
2005-03-23  0:40 ` Tim Newsham
2005-03-23  6:57   ` Sergey Reva
2005-03-23 17:34     ` Russ Cox
2005-03-24  8:46       ` Sergey Reva
2005-03-24  8:55         ` noselasd
     [not found]         ` <4439b95e268ad4987f174271ac554f28@smtp.songnetworks.no>
2005-03-25 10:33           ` Sergey Reva
2005-03-25 17:08             ` Russ Cox [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ee9e417a05032509081c7815cd@mail.gmail.com \
    --to=russcox@gmail.com \
    --cc=9fans@cse.psu.edu \
    --cc=rs_rlab@mail.ru \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).