9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
From: "Russ Cox" <rsc@swtch.com>
To: 9fans@9fans.net
Subject: Re: [9fans] channel_lock
Date: Mon, 14 Jul 2008 16:58:03 -0400	[thread overview]
Message-ID: <20080714205638.BD12F1E8C1F@holo.morphisms.net> (raw)
In-Reply-To: <071420081847.25641.487B9F36000AB7F2000064292200761064040196960E040E9F@comcast.net>

> I have been looking and the implementation of channels/alt in Plan9,
> and I have a question.  Does lock()/unlock() work across procs (not just
> threads)?  For example, in channel.c there is a static Lock *channel_lock.
> Does this provide exclusive to channel data across procs?

Yes: Locks are shared-memory spin locks.  They don't do any scheduling
(in contrast to QLocks).

> I assume yes, just trying to make sure I'm understanding it correctly.
> I was expecting to see code which handles channel access "across procs"
> differently than channel access between threads "in the same proc",
> but I didn't see anything like that.

This is a good question.  Most code doesn't need to keep that distinction
in mind.  There are simply threads, and they are running or ready
or asleep.

Plan 9's synchronization primitive is called rendezvous.  Processes in
a rendezvous group (usually also processes that share memory) can call

	rendezvous(tag, value)

and once two processes in the same group have called rendezvous with
the same tag, the two calls each return the other's value.

Libthread provides a thread-aware version of rendezvous called
_threadrendezvous.  The libc QLock, which normally uses rendezvous, uses
_threadrendezvous inside libthread programs but is otherwise unchanged.

No matter what the interface, at a low level things always look like this:
a running thread decides for whatever reason that it will stop running.
It records a pointer to its Thread* structure t somewhere, and then it
calls a function to enter back into its proc's scheduler.  (In Plan 9
libthread this function is called _sched.)  That proc has a run queue,
and t is not on it.  So either the proc runs some other thread that has
been waiting to run, or, if the run queue is empty, the proc itself goes
to sleep, using the OS-provided rendezvous.

At some point in the future, some thread, perhaps running in a different
proc, comes along and decides it is time for t to wake up.  It calls
_threadready(t), which puts t on t's proc's run queue (with appropriate
locking).  Then, if t's proc is asleep waiting for something to be placed
on the run queue, _threadready needs to wake that proc:

	q = &t->proc->ready;
	lock(&t->proc->readylock);
	... add t to q ...
	if(q->asleep){
		q->asleep = 0;
		/* lock passes to other proc */
		_threaddebug(DBGSCHED, "waking process %d", t->proc->pid);
		while(rendezvous(q, 0) == (void*)~0){
			if(_threadexitsallstatus)
				exits(_threadexitsallstatus);
		}
	}else
		unlock(&t->proc->readylock);

Here, q->asleep can only be true if t->proc is not the current thread's
proc.

Almost every operation in the thread library operates on the current
thread and the current proc.  Readying a thread is the only fundamental
operation that can interact with foreign procs.

Russ



      parent reply	other threads:[~2008-07-14 20:58 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-07-14 18:47 palazzol
2008-07-14 19:07 ` erik quanstrom
2008-07-14 21:04   ` Russ Cox
2008-07-14 20:58 ` 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=20080714205638.BD12F1E8C1F@holo.morphisms.net \
    --to=rsc@swtch.com \
    --cc=9fans@9fans.net \
    /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).