[comp.unix.wizards] Re^2: What kinds of things would you want in the GNU OS?

maart@cs.vu.nl (Maarten Litmaath) (05/27/89)

boomer@athena.mit.edu (Don Alvarez) writes:
\...   and if you back up every day (don't just
\      talk about it!), then the evil wizard can't trash more than
\      one day's work. [...]

Have you ever heard of `poison pots'?
-- 
 "Your password [should be] like your |Maarten Litmaath @ VU Amsterdam:
      toothbrush." (Don Alvarez)      |maart@cs.vu.nl, mcvax!botter!maart

craig@wave4.webo.dg.com (Craig Presson) (06/07/89)

In article <8591@chinet.chi.il.us> les@chinet.chi.il.us (Leslie Mikesell) writes:
>In article <10336@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes:
>
>>The supposed advantage of a thread is that it's cheap to create one,
>>even compared with setting up copy-on-write for a fast fork().  The
>>obvious disadvantage is that the shared data space requires use of
>>concurrency controls among the parallel threads (e.g. monitors).
>
>That's what I thought, but I can't see where it would be useful, except
>perhaps to make up for certain OS functions that might be lacking
>like the ability to cheaply determine that no I/O is pending on any
>of several channels so you can continue doing some work without needing
>a new thread.  Wouldn't there be a problem with static data in
>library routines (or anywhere else)?
>
>Les Mikesell
>
You betcha, Les. You definitely have to do something to protect any
static data which may change. In the DG OSes since 1972 or thereabouts,
(RDOS, the AOS family, and the MP/whatevers), there has been a fairly
well-understood mechanism for multithreading a single user program in
a single address space, with user control of task (==thread) creation,
intertask communication, priority, etc. It has been used for many things
over the years, a lot of them real-time flavored, but some not, like
overlapping disk I/O - processing - tape I/O in backup utilities, timers
and alarms in a variety of programs, etc. During that whole evolution,
the #1 easy trap for programmers to fall into was to unknowingly depend on
the value of some unprotected static data, which then changes or becomes
inconsistent. That's why the MACH project, for example, chose to provide
a "C Threads" library with support for well-managed shared variables.

At DG, we just made a religion of re-entrancy, and were helped along
greatly by the sophistication of many application builders. In the
meantime, the state of the art has progressed to the point where the
problem is not to find a mechanism for solving concurrency problems,
but to choose among a profusion of them.

Those who are saddled with language or OS implementations that neglected
to provide for concurrency have my sympathy. I doubt that a smooth way out
is possible; they'll have to hold their breath and upgrade to a modern
OS ...
-- 
"Why am I a look alike a poss of porterpease?"
      -- James Joyce, _Finnegan's Wake_

uunet!wave4.webo.dg.com!craig UUCP                \
craig@wave4.webo.dg.com       CSNET-to-dg/ux-node ->the 3 faces of DG
craig_presson%DGC.ceo.dg.com@relay.cs.net         /
                              CSNET-to-AOS/VS
Craig Presson, Data General, Westborough Mass. dg/ux development

maart@cs.vu.nl (Maarten Litmaath) (07/08/89)

vsh@etnibsd.UUCP (Steve Harris) writes:
\In article <1549@salgado.Solbourne.COM> dworkin@Solbourne.com (Dieter Muller) writes:
\>I'd *really* like a sane tty driver.
\
\Hear hear!!  At a former job we talked a lot about how we would rewrite
\the tty driver.  One idea was to give the user, via ioctl's, access to
\the uart (or whatever serial-line multiplexer you have).  One ioctl to
\get the uart settings (in a bit vector), another to set them, and
\another to have the driver(??) send you a signal (for which you would
\have to write the appropriate handler) whenever any of the bits changed
\(e.g., DTR was deasserted).  Standard configurations (handlers) would
\be privided in a library.  Of course, one would be limited by the
\capabilities of the uart, but the design would assume total access to
\be possible.

But is this going to take care of the `vi crashed, terminal screwed up'
problem?

\A second idea is "copy-on-write symbolic links" -- I have a symlink:
\	bar -> foo
\When I write to it, a regular file "bar" is created (the symlink is
\destroyed), the contents of foo (up to the current file-pointer-offset)
\are copied to bar, and the write takes place.  I'm not sure what
\happens if foo is not a regular file.

That's easy: a kernel panic! (Ala `date > /dev/printer'.)
Seriously: what would you use them for?
-- 
   "... a lap-top Cray-2 with builtin    |Maarten Litmaath @ VU Amsterdam:
cold fusion power supply"  (Colin Dente) |maart@cs.vu.nl, mcvax!botter!maart

guido@piring.cwi.nl (Guido van Rossum) (08/04/89)

gaf@uucs1.UUCP (gaf) writes:

>Something I'd like in an OS is an all encompassing type of select()
>which would let me take data (events) from a variety of sources in
>the same fashion.  For example, I'd like to wait on a semaphore, a
>message queue, a pipe, and a TCP socket all at once (okay, this is
>a contrived example).

Sounds like you need multiple threads in a single address space, or
light-weight threads as they are referred to in a discussion of the
subject in neighboring newsgroups.  I agree that they are *very* nice to
have in an OS.

--
Guido van Rossum, Centre for Mathematics and Computer Science (CWI), Amsterdam
guido@cwi.nl or mcvax!guido or guido%cwi.nl@uunet.uu.net
"You're so *digital*, girl!" -- Neneh Cherry

peter@ficc.uu.net (Peter da Silva) (08/07/89)

[ gaf@uucs1.UUCP (gaf) wants an n-way wait() ]

In article <8311@boring.cwi.nl>, guido@piring.cwi.nl (Guido van Rossum) writes:
> Sounds like you need multiple threads in a single address space, or
> light-weight threads as they are referred to in a discussion of the
> subject in neighboring newsgroups.  I agree that they are *very* nice to
> have in an OS.

An n-way wait can be implemented by using N threads, having each of them
waiting on a seperate event, and having a thread signal the mainline
when its event occurs. It can also be implemented using software interrupts...
(or in UNIX terms, signals). It's usually desirable, though, to implement
an n-way wait anyway, because it may be more efficient. When one is doing
this sort of thing, one is often involved in process monitoring or control,
where efficiency is an important factor.

Conversely, if you have an N-way wait, it's relatively easy to implement
threads. It's like the various process co-ordination tools: semaphores,
monitors, messages, etc... you can use any of them to implement the others.
It's generally desirable to have at least a couple of them be primitives
in any real system... and define all of them in a portable one.
-- 
Peter da Silva, Xenix Support, Ferranti International Controls Corporation.
Business: peter@ficc.uu.net, +1 713 274 5180. | "The sentence I am now
Personal: peter@sugar.hackercorp.com.   `-_-' |  writing is the sentence
Quote: Have you hugged your wolf today?  'U`  |  you are now reading"

andrew@alice.UUCP (Andrew Hume) (08/07/89)

gaf said s/he wanted an all encompassing select. sounds good to me.
to reply that this is teh same as having multiple threads in
a single address space is but one (to my taste peculiar) solution
with known technology. if anyone is keeping a list, keep the
former, not the latter.

jack@piring.cwi.nl (Jack Jansen) (08/08/89)

In article <5568@ficc.uu.net> peter@ficc.uu.net (Peter da Silva) writes:
>[ gaf@uucs1.UUCP (gaf) wants an n-way wait() ]
>
>In article <8311@boring.cwi.nl>, guido@piring.cwi.nl (Guido van Rossum) writes:
>> Sounds like you need multiple threads in a single address space, or
>> light-weight threads as they are referred to in a discussion of the
>> subject in neighboring newsgroups.  I agree that they are *very* nice to
>> have in an OS.
>
>An n-way wait can be implemented by using N threads, having each of them
>waiting on a seperate event, and having a thread signal the mainline
>when its event occurs. It can also be implemented using software interrupts...
>(or in UNIX terms, signals). It's usually desirable, though, to implement
>an n-way wait anyway, because it may be more efficient.


Well, I've noticed that it is actually the other way around: everytime
I use select() I really wanted multiple threads in the first place
and only used select because they weren't there.

Usually, my select code looks like

    while(1) {
	select()
	if( event-1 ) {
	    handle-event-1;
	}
	if( event-2 ) {
	    handle-event-2;
	}
	etc;
    }
With multiple threads, you would have multiple threads each doing
a simple
	while(1) {
	    wait();
	    do-event;
	}
Not only do I find this much easier to understand, but there are also
other advantages, like having local state on the stack in stead of
having a global array that you have to index by event number each time
(think of things like handling two or more keyboards at the same
time).
-- 
--
Een volk dat voor tirannen zwicht	| Oral:     Jack Jansen
zal meer dan lijf en goed verliezen	| Internet: jack@cwi.nl
dan dooft het licht			| Uucp:     mcvax!jack

peter@ficc.uu.net (Peter da Silva) (08/09/89)

In article <8318@boring.cwi.nl>, jack@piring.cwi.nl (Jack Jansen) writes:
> Well, I've noticed that it is actually the other way around: everytime
> I use select() I really wanted multiple threads in the first place
> and only used select because they weren't there.

If you have select you can implement n-way threads trivially, subject to
language considerations. In Forth it was a matter of some 40 lines of
code to get the co-routines working. In C, well, I would expect the
context-switch and stack-allocation stuff would be non-portable. What
I'd really like to see in a future C library standard would be a portable
implementation of:

	typedef struct {
		int initial_stack_size;
		void (*initial_pc)();
		...
	} context_template;

	context = create_context(context_template);
	status = destroy_context(context);
	switch_context(context);

Plus some sort of co-ordination (semaphores, monitors, messages, or
whatever). Multitasking, coroutines, whatever... could be built on
top of this. Because the context switch is implicit you don't get to
deal with race conditions (such as switching context inside of malloc).
You still have to worry about globals, though.

> With multiple threads, you would have multiple threads each doing
> a simple
> 	while(1) {
> 	    wait();
> 	    do-event;
> 	}

Co-ordination then becomes a problem. I've worked with both programming
models on the Amiga, where they're supported, and each has its place. It's
a LOT easier to debug the simple-event-loop, but if it gets too complex
you can always go the other way.
-- 
Peter da Silva, Xenix Support, Ferranti International Controls Corporation.
Business: peter@ficc.uu.net, +1 713 274 5180. | "The sentence I am now
Personal: peter@sugar.hackercorp.com.   `-_-' |  writing is the sentence
Quote: Have you hugged your wolf today?  'U`  |  you are now reading"