Re: O_CLOEXEC (was Re: thread rant)

2000-09-06 Thread Jamie Lokier

dean gaudet wrote:
> suppose you're building a threaded server to scale to 20k connections,
> and you want to support fork()/exec() of CGIs dirctly (rather than
> through a separate daemon process).
> 
> if you don't use close-on-exec, then after fork before exec you have
> to iterate over the 20k descriptors to close them all -- or you have
> to walk your own data structures (a list of open sockets) to find what
> descriptors are open and close them.

> if you use O_CLOEXEC then it's not possible for an fd to be open which
> isn't marked to be closed on the exec, and so you've no extra work to
> do before exec.
> 
> but if you try to use FD_CLOEXEC there's a critical section between
> the open/socket/accept/pipe/... and the fcntl().  you pretty much have
> to put it under a semaphore (although you can get away with a rwlock),
> or iterate over all the descriptors.

Yes, this is the worst part.  Having to synchronise threads.

> i've a hairbrained idea for replacing fd integers with pointers which
> might actually scale better if anyone wants to hear it again.

Completely hairbrained, would make no difference to scalability, and
make accessing your user space data structures slower.  (Think X window
ids and the need to use a hash table instead of a flat table).

O_ANYFD would, in principle, improve scalability.  It was proposed a few
years ago -- it means "kernel can return any fd, not necessarily the
next free one".  I don't think it was considered worth the effort.

-- Jamie
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/



O_CLOEXEC (was Re: thread rant)

2000-09-05 Thread dean gaudet

On Sat, 2 Sep 2000, Alexander Viro wrote:

> On Sat, 2 Sep 2000, Jamie Lokier wrote:
> 
> > dean gaudet wrote:
> > > an example of brokenness in the traditional fd API is close-on-exec --
> > > there's a race between open()/socket()/pipe() and fcntl(FD_CLOEXEC) during
> > > which if another thread does a fork() it's possible the child will inherit
> > > an fd it shouldn't... working around it is painful.  the model which
> 
> Really? Like, say it, close() before exec()?
>
> > > NT/OS2 use for creating a new process scales better in the 99.99% case of
> > > stdin/out/err -- you only specify those fds you want to keep in the new
> > > process.
> > 
> > An obvious solution presents itself.  O_CLOEXEC.

yeah i proposed this and non-blocking inheritance from accept() when i was
doing the initial modelling for threaded apache-2.0 about 3 years ago. you
need O_CLOEXEC to be inherited through accept() as well.  oh, and you also
want it on pipe(), socket(), and socketpair() to be complete. (if you
search linux-kernel archives you can find that this topic has come up
maybe 4 times in 3 years.)

> Even more obvious solution: close what you need to close if you have
> sensitive descriptors around. Close-on-exec is a kludge. If you have
> sensitive pieces of descriptor table you want to do some other things too
> - e.g. make sure that it gets unshared before exec(). Because new
> descriptors of that kind are very likely to follow...

if you'll forgive me for using webservers as an example again i can
maybe give some motivation.

suppose you're building a threaded server to scale to 20k connections,
and you want to support fork()/exec() of CGIs dirctly (rather than
through a separate daemon process).

if you don't use close-on-exec, then after fork before exec you have
to iterate over the 20k descriptors to close them all -- or you have
to walk your own data structures (a list of open sockets) to find what
descriptors are open and close them.

if you want to walk your own data structures then these structures need
to be coherent at the time of the fork -- which means semaphores to
add/delete from the list.  this would mean an extra synchronization after
accept().  i suspect this would suck worse than iterating over 3..2
and calling close -- think of all the cache line activity on an SMP box.

if you use O_CLOEXEC then it's not possible for an fd to be open which
isn't marked to be closed on the exec, and so you've no extra work to
do before exec.

but if you try to use FD_CLOEXEC there's a critical section between
the open/socket/accept/pipe/... and the fcntl().  you pretty much have
to put it under a semaphore (although you can get away with a rwlock),
or iterate over all the descriptors.

opendir() has a similar race, except it's hidden inside libc.

the most portable, and arguably cleaner solution is to use a separate
unthreaded process for forking and fd passing... as long as this meets
your needs.

fork/exec and threads just don't mix so well with lots of fds.
(a spawnve() API with an additional argument to indicate which fds to
dup would be better...  similar to NT's CreateProcess)

i've a hairbrained idea for replacing fd integers with pointers which
might actually scale better if anyone wants to hear it again.

-dean

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/



RE: thread rant

2000-09-04 Thread David Schwartz


> I've heard comments from Alan, and others in the past bashing
> threads, and I can understand the "threads are for people who
> can't write state machines" comments I've heard, but what other
> ways are there of accomplishing the goals that threads solve in
> an acceptable manner that gives good performance without coding
> complexity?

That's a nonsensical complaint anyway, since you need to use state machines
with threads. When there's work to be done, you hand it to a thread. That
thread needs to know what state the object it's working on was in. When that
thread is finished working, that object is in some other state.

The reason you need threads is because you may have 12,000 state machines
and 3 of them may need to be worked on at the same time. You may not know
ahead of time whether the needed work is CPU intensive, I/O intensive, or
neither.

> This is all just curiosity.  I've considered trying some thread
> programming, but if it is as stupid as it sounds, I'd rather
> learn the "right" way of writing code that would ordinarily be
> done with threads, etc..  Right now, I'm using fork() all over
> the place and don't much care how much waste it is...  I'd like
> to though.

Fork is good if you really need a whole process. It's also good if you're
doing something potentially risky and can't afford to the process that is
forking fail. It makes life miserable, however, if you need tight
communication with the forked process.

There are plenty of things I don't like about pthreads. But pthreads is not
threads. A lot of the ugliness in pthreads was to allow operating systems
that couldn't do threads right to claim to 'fully support' threading.

One major problem with a big 'poll loop' is that you're vulnerable to
ambush. A sudden page fault from a slow disk (or worse, NFS mount *shudder*)
and your entire process screeches to a halt. Obviously, one process per
connection/task is out of the question. Threads give you a very satisfying
in-between point.

DS

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/



Re: thread rant

2000-09-04 Thread Stephen C. Tweedie

Hi,

On Sat, Sep 02, 2000 at 09:41:03PM +0200, Ingo Molnar wrote:
> 
> On Sat, 2 Sep 2000, Alexander Viro wrote:
> 
> > unlink() and the last munmap()/exit() will get rid of it...
> 
> yep - and this isnt possible with traditional SysV shared memory, and isnt
> possible with traditional SysV semaphores. (forget my filesystem comment,
> it's a thinko.)

Using the SysV APIs, you can do this for shared memory: do an
IPC_RMID and the segment will disappear on the last detach/exit.  But
yes, you can't do the same for SysV semaphores.

--Stephen
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/



Re: thread rant

2000-09-03 Thread Christoph Rohland

Richard Gooch <[EMAIL PROTECTED]> writes:

> Ingo Molnar writes:
> > yep - and this isnt possible with traditional SysV shared memory,
> > and isnt possible with traditional SysV semaphores. (forget my
> > filesystem comment, it's a thinko.)
> 
> Huh? After attaching, if you "delete" a SHMID, it will be removed
> when all processes referring to it unattach or die. Fairly similar
> semantics.

Would be nice if it really would be _that_ similar. We had to
reintroduce some linuxism that you can still attach to an deleted
SHMID. This is quite uncommon for filesystems (and for SYSV shm on
other *NIX)

Christoph

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/



RE: thread rant [semi-OT]

2000-09-02 Thread Marty Fouts


just an aside on asynchronous i/o: concurrency by asychronous I/O actually
predates concurrency via thread-like models, and goes back to the earliest
OS-precursors.  Early work on thread-like concurrency models were, in part,
a response to the difficulties inherent in getting asynchronous I/O right,
and so now the pendulum is swinging back.

A pedantic nit: the basic Un*x I/O model, with syncrhronous interfaces
predates Un*x networking by some time.  I woudl make the case that the
people who grafted Un*x networking (most notably sockets) onto Un*x didn't
really understand the I/O model, and crafted cruft, that just happened to
have a few usable features, one being a sort-of way of sometimes getting
asynchrony.

Prior to posix, by the way, there were any number of Un*x variants that
asynchronous I/o models, supporting any number of i/o completion
notification models, buffering schemes and (lack of) cancellation semantics.
My personal favorite was the variant in the Cray-2 Unicos; my personal least
favorite was Intergraph's Clix.

Marty

-Original Message-
From: Dan Maas [mailto:[EMAIL PROTECTED]]
Sent: Friday, September 01, 2000 11:50 PM
To: [EMAIL PROTECTED]
Subject: Re: thread rant [semi-OT]

[...]

Can we do better? Yes, thanks to various programming techniques that allow
us to keep more of the system busy. The most important bottleneck is
probably the network - it makes no sense for our server to wait while a slow
client takes its time acknowledging our packets. By using standard UNIX
multiplexed I/O (select()/poll()), we can send buffers of data to the kernel
just when space becomes available in the outgoing queue; we can also accept
client requests piecemeal, as the individual packets flow in. And while
we're waiting for packets from one client, we can be processing another
client's request.

The improved program performs better since it keeps the CPU and network busy
at the same time. However, it will be more difficult to write, since we have
to maintain the connection state manually, rather than implicitly on the
call stack.


So now the server handles many clients at once, and it gracefully handles
slow clients. Can we do even better? Yes, let's look at the next
bottleneck - disk I/O. If a client asks for a file that's not in memory, the
whole server will come to a halt while it read()s the data in. But the
SCSI/IDE controller is smart enough to handle this alone; why not let the
CPU and network take care of other clients while the disk does its work?

How do we go about doing this? Well, it's UNIX, right? We talk to disk files
the same way we talk to network sockets, so let's just select()/poll() on
the disk files too, and everything will be dandy... (Unfortunately we can't
do that - the designers of UNIX made a huge mistake and decided against
implementing non-blocking disk I/O as they had with network I/O. Big booboo.
For that reason, it was impossible to do concurrent disk I/O until the POSIX
Asynchronous I/O standard came along. So we go learn this whole bloated API,
in the process finding out that we can no longer use select()/poll(), and
must switch to POSIX RT signals - sigwaitinfo() - to control our server***).
After the dust has settled, we can now keep the CPU, network card, and the
disk busy all the time -- so our server is even faster.

[...]
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/



RE: thread rant

2000-09-02 Thread Marty Fouts

I'm confused.  Threads are harder than *what* to get right?

If you need concurrency, you need concurrency, and any existing model is
hard.  Besides, at some level, all of the concurrency models come down to a
variant on threads, anyway.

-Original Message-
From: Alexander Viro [mailto:[EMAIL PROTECTED]]
Sent: Saturday, September 02, 2000 1:07 AM
To: dean gaudet
Cc: Mike A. Harris; Michael Bacarella; Linux Kernel mailing list
Subject: Re: thread rant




On Sat, 2 Sep 2000, dean gaudet wrote:

> the thread bashing is mostly bashing programs which do things such as a
> thread per-connection.  this is the most obvious, and easy way to use
> threads, but it's not necessarily the best performance, and certainly
> doesn't scale.  (on the scalability side just ask yourself how much RAM is
> consumed by stacks -- how many cache lines will that consume, and how many
> TLB entries.  it sucks pretty fast.)
 
> state machines are hard.  while people on linux-kernel may be hot shot
> programmers who can do state machines in their sleep, this is definitely
> not the case for the average programmer.
> 
> fortunately fully threaded and fully state driven are two opposite ends of
> a spectrum, and there are lots of useful compromises in between where
> threads are used in a way that allows the average programmer to
> maintain/extend a codebase; while also getting the scalability of state
> machines.

Lovely. You've completely sidestepped the main part:

*threads* *are* *hard* *to* *write* *correctly*

Average programmer will fuck up and miss tons of race conditions. Better
than average programmers do. If you've got shared resource - you are in
for problems. Threads are useful. But they take more efforts and are much
harder to debug _and_ to prove correctness. In other words, that's one of
the last resort tools, not the first one. If you can do it without shared
state - don't bother with threads. Same as with rewrite in assmebler - do
it with small critical parts and don't unless you absolutely have to. The
first rule of optimisation: don't. Keep the critical sections small and if
you can avoid them - it's worth the efforts. You'll win a lot when it will
come to changing the thing. And you will have to change it, sooner or
later. Same goes for debugging. Non-threaded code is easier to understand.
Yes, you may be very clever. But you'll have to debug it on Friday evening
after a hard week when you want only one thing - go home and sleep. Or
somebody else will and he will curse you. KISS. And threads are _not_
simple.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/



Re: thread rant

2000-09-02 Thread Igmar Palsenberg

On Fri, 1 Sep 2000, Michael Bacarella wrote:

> 
> Q: Why do we need threads?
> A: Because on some operating systems, task switches are expensive.

No. threads share variable and code memory, processes do not. And
sometimes it can make your life a lot easier. Even if you can use things
such as SHM or so.

> Q: So, threads are a hack to get around operating systems that suck?
> A: Basically.

I don't agree.
 
> Q: So, why must Linux support threads?
> A1:  : |
> A2: So other programs can be easily ported to Linux!
> 
> That can already happen. It's not the *best* implementation. It's
> not as fast as it can be. But it works. And that's all it should do. If
> you're not happy, cope.
> 
>   "But threads on this system are faster than on Linux!"
> 
> The fact that the system implements threads speaks enough about
> it's capabilities. ie, it's trying hard to suck less. So, from my POV,
> we're looking to make Linux suck more by effectively emulating systems
> that are trying to suck less.
> 
> But, I've never done anything worthwhile for Linux, so take this for what
> it's worth, from an asshole.
> -MB


Igmar

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/



Re: thread rant

2000-09-02 Thread Richard Gooch

Ingo Molnar writes:
> 
> On Sat, 2 Sep 2000, Alexander Viro wrote:
> 
> > > what i mean is that i dont like the cleanup issues associated with SysV
> > > shared memory - eg. it can hang around even if all users have exited, so
> > > auto-cleanup of resources is not possible.
> > 
> > unlink() and the last munmap()/exit() will get rid of it...
> 
> yep - and this isnt possible with traditional SysV shared memory,
> and isnt possible with traditional SysV semaphores. (forget my
> filesystem comment, it's a thinko.)

Huh? After attaching, if you "delete" a SHMID, it will be removed when
all processes referring to it unattach or die. Fairly similar
semantics.

Regards,

Richard
Permanent: [EMAIL PROTECTED]
Current:   [EMAIL PROTECTED]
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/



Re: thread rant

2000-09-02 Thread Ingo Molnar


On Sat, 2 Sep 2000, Alexander Viro wrote:

> > what i mean is that i dont like the cleanup issues associated with SysV
> > shared memory - eg. it can hang around even if all users have exited, so
> > auto-cleanup of resources is not possible.
> 
> unlink() and the last munmap()/exit() will get rid of it...

yep - and this isnt possible with traditional SysV shared memory, and isnt
possible with traditional SysV semaphores. (forget my filesystem comment,
it's a thinko.)

Ingo

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/



Re: thread rant

2000-09-02 Thread Alexander Viro



On Sat, 2 Sep 2000, Ingo Molnar wrote:

> 
> On Sat, 2 Sep 2000, Alexander Viro wrote:
> 
> > Why? I would say that bad thing about SysV shared memory is that it's
> > _not_ sufficiently filesystem-thing - a special API where 'create a
> > file on ramfs and bloody mmap() it' would be sufficient. Why bother
> > with special sets of syscalls?
> 
> what i mean is that i dont like the cleanup issues associated with SysV
> shared memory - eg. it can hang around even if all users have exited, so
> auto-cleanup of resources is not possible.

unlink() and the last munmap()/exit() will get rid of it...

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/



Re: thread rant

2000-09-02 Thread Ingo Molnar


On Sat, 2 Sep 2000, Alexander Viro wrote:

> Why? I would say that bad thing about SysV shared memory is that it's
> _not_ sufficiently filesystem-thing - a special API where 'create a
> file on ramfs and bloody mmap() it' would be sufficient. Why bother
> with special sets of syscalls?

what i mean is that i dont like the cleanup issues associated with SysV
shared memory - eg. it can hang around even if all users have exited, so
auto-cleanup of resources is not possible.

Ingo

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/



Re: thread rant

2000-09-02 Thread Kai Henningsen

[EMAIL PROTECTED] (dean gaudet)  wrote on 02.09.00 in 
<[EMAIL PROTECTED]>:

> although you know the most amusing thing to watch a thread programmer try
> to do is to pass data bidirectionally between two sockets.

I'm tempted to say "don't do that, then". I.e., sounds like the wrong  
abstraction.

Of course, you may have no choice.

Easy threads rule-of-thumb: if you need to juggle two concurrent jobs in  
one thread, you have the wrong abstraction; maybe you need to split your  
thread.

> can we be friends and say "everything in moderation including moderation
> itself"?  :)

That's always wise.

MfG Kai
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/



Re: thread rant [semi-OT]

2000-09-02 Thread Kai Henningsen

[EMAIL PROTECTED] (Dan Maas)  wrote on 02.09.00 in 
<020d01c014a9$f48d3fa0$0701a8c0@morph>:

> When people think of "multithreading," often they are just looking for a way
> to extract more concurrency from their machine. You want all these
> independent parts to be working on your task simultaneously. There are many
> different mechanisms for achieveing this. Here we go...

[...]

> In summary, when "multithreading" floats into your mind, think
> "concurrency." Think very carefully about how you might simultaneously

Let me see if I get this right.

Some people say "threading" when they mean "performance", so we all should  
think "performance" when we hear "threading"?

Why am I not impressed by that logic?

MfG Kai
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/



Re: thread rant

2000-09-02 Thread Kai Henningsen

[EMAIL PROTECTED] (Alexander Viro)  wrote on 02.09.00 in 
<[EMAIL PROTECTED]>:

>   *threads* *are* *hard* *to* *write* *correctly*

Not really.

The real problem is that threads - just like pointers, incidentally -  
react *far* worse to getting it wrong than most abstractions do, that is,  
threads (and pointers) are often hard to debug.

And like all abstractions, they don't do you much good unless you have a  
sane way of describing your problem in the terms of this abstraction.

Once you *do* have that, however, threads can be a really nice fit for  
your problem. Just don't try to force-fit them on something different.

All of this, of course, is looking from the programming-abstraction point  
of view. It's much harder to get right from the performance-sucks point of  
view.

(Fortunately, getting it right the first way can lead to getting it right  
the second way.)

Essentially, it usually comes down to the same thing: get a good high- 
level description of your problem. Without it, you're fucked.

*That* is where the most energy should be spent.

Then, code it, and debug it.

> Average programmer will fuck up and miss tons of race conditions. Better

s/Average/Inexperienced/ or you have a serious documentation problem.  
Which happens. of course.

> than average programmers do. If you've got shared resource - you are in
> for problems. Threads are useful. But they take more efforts and are much
> harder to debug _and_ to prove correctness. In other words, that's one of

Often easier than pointers, IME.

Of course, in both cases using some conventions can help bigtime.

> the last resort tools, not the first one. If you can do it without shared

In my current job project, structure went state machines -> coroutines ->  
threads. Both conversions eliminated buttloads of bugs. I wish I had  
started out with threads in the first place (it wasn't possible in the  
circumstances). That would have solved *so* much headache.

And there was the equivalent of race conditions even back in the state  
machine version. Except they were *much* harder to solve there.

Oh, and the code still has state machines - *where they make sense*.  
Something with several tens of KB of internal state and complex logic  
isn't where they make sense.

(Oh, and as to "one thread per connection doesn't scale" argument: thread  
overhead say 8KB, connection local data 50-200KB - if the *thread*  
overhead kills you, you were dead anyway.)

> state - don't bother with threads. Same as with rewrite in assmebler - do

I've never seen a problem solved with threads that *didn't* have shared  
state. Ok, some only had shared state in the file system, so I know what  
you mean :-)

In any case, the canonical example of a program that absolutely *MUST*  
have threads is an OS kernel. You can crunch it down to a micro kernel,  
but that sucks in other ways, and your servers will probably need their  
own threading anyway.

> it with small critical parts and don't unless you absolutely have to. The

Right; the assembler problem is vastly different, though: here, you're  
*giving up* abstractions. Don't do that unless you have no choice.

> first rule of optimisation: don't. Keep the critical sections small and if
> you can avoid them - it's worth the efforts. You'll win a lot when it will

That's why the threaded version of this project often uses producer- 
consumer message queues for internal communication. Much easier to get one  
queue right than three dozen shared variables, all subtly different.

Another case of "chose the right abstraction".

> come to changing the thing. And you will have to change it, sooner or
> later. Same goes for debugging. Non-threaded code is easier to understand.

Not for inherently parallel stuff it's not. Definitely not. Complex state  
machines are *hard* to understand.

> Yes, you may be very clever. But you'll have to debug it on Friday evening
> after a hard week when you want only one thing - go home and sleep. Or

And that was often when I said "I wish I had threads instead of these  
bloody state machines". Now I have, and boy has it helped a lot.

> somebody else will and he will curse you. KISS. And threads are _not_
> simple.

In this you're wrong.

MfG Kai
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/



Re: thread rant

2000-09-02 Thread Christoph Rohland

Alexander Viro <[EMAIL PROTECTED]> writes:

> On Sat, 2 Sep 2000, Ingo Molnar wrote:
> 
> > well, Linux SysV shared memory indeed has a 'software version' of
> > pagetables, this way if one process faults in a new page (because
> > all pages are unmapped originally), then the new physical page
> > address can be discovered by all other subsequent faults in other
> > process contexts. It works just fine - the thing i dislike about
> > SysV shared memory is not the VM part but its 'filesystem
> > characteristics' - i think anonymous shared memory is the way to
> > go.
> 
> Why? I would say that bad thing about SysV shared memory is that
> it's _not_ sufficiently filesystem-thing - a special API where
> 'create a file on ramfs and bloody mmap() it' would be
> sufficient. Why bother with special sets of syscalls?

Yes, and that's what I plan for 2.5: Redoing the shm filesystem part
like (or in?) ramfs and better separation of both the VM part and the
SYSV API part.

I always objected against doing anonymous shared mmap over SYSV shared
mem because I wanted to have this handling in the VM layer and _not_
in some horrible^wspecial API layer.

So my goal would be:

1) anonymous shared mappings should be handled by the vm layer (with
   better integration into the pagecache)
2) the filesystem frontend should be redone to make more use of the
   VFS.
3) SYSV shm should only be a special API using this functionality

Comments?
Christoph

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/



Re: thread rant

2000-09-02 Thread David S. Miller

   Date:Sat, 2 Sep 2000 13:08:41 +0200 (CEST)
   From: Ingo Molnar <[EMAIL PROTECTED]>

   i think anonymous shared memory is the way to go.

We have it now in 2.4.x, MAP_SHARED | MAP_ANONYMOUS
actually works these days. :-)

Or were you talking about creating some other kind of
"new semaphores"?

Later,
David S. Miller
[EMAIL PROTECTED]
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/



Re: thread rant

2000-09-02 Thread Alexander Viro



On Sat, 2 Sep 2000, Jamie Lokier wrote:

> dean gaudet wrote:
> > an example of brokenness in the traditional fd API is close-on-exec --
> > there's a race between open()/socket()/pipe() and fcntl(FD_CLOEXEC) during
> > which if another thread does a fork() it's possible the child will inherit
> > an fd it shouldn't... working around it is painful.  the model which

Really? Like, say it, close() before exec()?

> > NT/OS2 use for creating a new process scales better in the 99.99% case of
> > stdin/out/err -- you only specify those fds you want to keep in the new
> > process.
> 
> An obvious solution presents itself.  O_CLOEXEC.

Even more obvious solution: close what you need to close if you have
sensitive descriptors around. Close-on-exec is a kludge. If you have
sensitive pieces of descriptor table you want to do some other things too
- e.g. make sure that it gets unshared before exec(). Because new
descriptors of that kind are very likely to follow...

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/



Re: thread rant

2000-09-02 Thread Alexander Viro



On Sat, 2 Sep 2000, Ingo Molnar wrote:

> well, Linux SysV shared memory indeed has a 'software version' of
> pagetables, this way if one process faults in a new page (because all
> pages are unmapped originally), then the new physical page address can be
> discovered by all other subsequent faults in other process contexts. It
> works just fine - the thing i dislike about SysV shared memory is not the
> VM part but its 'filesystem characteristics' - i think anonymous shared
> memory is the way to go.

Why? I would say that bad thing about SysV shared memory is that it's
_not_ sufficiently filesystem-thing - a special API where 'create a file
on ramfs and bloody mmap() it' would be sufficient. Why bother with
special sets of syscalls?

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/



Re: thread rant

2000-09-02 Thread Jamie Lokier

dean gaudet wrote:
> an example of brokenness in the traditional fd API is close-on-exec --
> there's a race between open()/socket()/pipe() and fcntl(FD_CLOEXEC) during
> which if another thread does a fork() it's possible the child will inherit
> an fd it shouldn't... working around it is painful.  the model which
> NT/OS2 use for creating a new process scales better in the 99.99% case of
> stdin/out/err -- you only specify those fds you want to keep in the new
> process.

An obvious solution presents itself.  O_CLOEXEC.

Glibc could easily be made to call fcntl(FD_CLOEXEC) for kernels that
don't implement O_CLOEXEC, so that applications can simply use the flag
and rely on it.

-- Jamie
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/



Re: thread rant

2000-09-02 Thread dean gaudet

On Sat, 2 Sep 2000, Ingo Molnar wrote:

> i dont understand why this is such an important category. If the sharing
> is very high between the threads then it makes sense to use 'shared-all
> threads'. But frequently the example given are webservers, which often do
> not have alot of cross-request shared state.

web *applications* are loaded with cross-request state. there's only so
much you can stuff in a cookie, and what application servers typically do
is stuff only a session id into the cookie and keep the rest of the
application state in memory or on disk.  a good example would be a
web-based email gateway to an IMAP mail-store.  (i.e. think about how to
write yahoo mail or hotmail)

web content is easy compared to web applications...

> > file descriptors -- yeesh these are hard, you want some sharing and
> > some not sharing. [...]
> 
> well (in Linux) you can specify it on a per-filedescriptor level wether to
> share or not to share, and you can pass a filedescriptor to another
> process and you can establish it there. Is there any API missing in this
> area?

so even if CLONE_FILES is set i can specify i don't want files to be
shared?  how does that work?

an example of brokenness in the traditional fd API is close-on-exec --
there's a race between open()/socket()/pipe() and fcntl(FD_CLOEXEC) during
which if another thread does a fork() it's possible the child will inherit
an fd it shouldn't... working around it is painful.  the model which
NT/OS2 use for creating a new process scales better in the 99.99% case of
stdin/out/err -- you only specify those fds you want to keep in the new
process.

i know you've done a kick-ass job of making fd allocation not collide a
hell of a lot, but it's another synchronization that's unnecessary really.

> > other than TLB/page-table changes is there anything else i'm missing
> > which makes SMP and threading "slow"?
> 
> it's not slow, it's 'slower' in the 'common memory allocation' case.

yeah malloc generally sucks because it puts synchronization in when and
the avg programmer doesn't realise it.  http://www.hoard.org/ is pretty
interesting research in this area though.

-dean

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/



Re: thread rant

2000-09-02 Thread Alan Cox

> This is all just curiosity.  I've considered trying some thread
> programming, but if it is as stupid as it sounds, I'd rather
> learn the "right" way of writing code that would ordinarily be
> done with threads, etc..  Right now, I'm using fork() all over
> the place and don't much care how much waste it is...  I'd like
> to though.

The single thing people forget most is that threads are expensive. Sure use
one for rendering one for computation, but dont use one per socket on a 
web server.

If you think of threading as fork() that shares more then you'll probably be
making sensible use of threading.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/



Re: thread rant

2000-09-02 Thread Ingo Molnar


On Sat, 2 Sep 2000, dean gaudet wrote:

> i don't understand why another semaphore type is needed -- about the
> only semaphore missing is the pshared portion of posix.  (recently i
> ported a large commercial MTA to linux and the only thing missing was
> the pthread_mutexattr_{s,g}etpshare stuff.)

i'd like to have waitqueue based (kernel-space) semaphores such as the
SysV semaphores are, not signal or sched_yield() based ones.

> regarding using shared memory/multiprocess -- how do you handle the
> case where the shared region needs to grow?

i dont understand why this is such an important category. If the sharing
is very high between the threads then it makes sense to use 'shared-all
threads'. But frequently the example given are webservers, which often do
not have alot of cross-request shared state.

> i actually think there's far more grossness to trying to figure out
> when to grow a shared mem region -- you almost need to check every
> time you follow a pointer.  and hopefully you can arrange to have the
> same mapping in all processes or else you need some sort of extra page
> table... almost forced to implement paging in software.

well, Linux SysV shared memory indeed has a 'software version' of
pagetables, this way if one process faults in a new page (because all
pages are unmapped originally), then the new physical page address can be
discovered by all other subsequent faults in other process contexts. It
works just fine - the thing i dislike about SysV shared memory is not the
VM part but its 'filesystem characteristics' - i think anonymous shared
memory is the way to go.

> file descriptors -- yeesh these are hard, you want some sharing and
> some not sharing. [...]

well (in Linux) you can specify it on a per-filedescriptor level wether to
share or not to share, and you can pass a filedescriptor to another
process and you can establish it there. Is there any API missing in this
area?

> other than TLB/page-table changes is there anything else i'm missing
> which makes SMP and threading "slow"?

it's not slow, it's 'slower' in the 'common memory allocation' case.

Ingo

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/



Re: thread rant

2000-09-02 Thread dean gaudet

On Sat, 2 Sep 2000, Alexander Viro wrote:

>   *threads* *are* *hard* *to* *write* *correctly*

in C, yes that can be essentially true.

although you can do a webserver with no mutexes pretty easily... the first
threaded apache had exactly one mutex -- inside the memory allocator when
it had to go to a list of free pages (which is the slow path -- apache's
fast allocation path needs no mutexes).  otherwise the threads
successfully ran without any need to co-ordinate with each other.  the
kernel provided all the co-ordination necessary through accept().

i should have chosen my phrasing a bit better too -- when i was talking
about the spectrum between fully threaded and fully state driven, and i
said that "threads are easier to program" i was actually thinking more
along the lines of "call-return stacks make programming a lot easier"...
although that too is totally related to the languages we generally choose
to code in these days.  my biggest beef with state-machine coding is that
there's essentially no call-return stack.

although you know the most amusing thing to watch a thread programmer try
to do is to pass data bidirectionally between two sockets.

can we be friends and say "everything in moderation including moderation
itself"?  :)

-dean

p.s. you lectured me on optimising only that which needs optimising...
that is exactly what i was suggesting.  the only time apache, for example,
needs a state machine is to handle the low bandwidth clients/long
downloads.  writing the whole server as a state machine is an essentially
impossible task... if you don't believe me then i suggest trying it.  
don't forget to make your server extensible, and plan for perl, php, and
java application services.  that's the way people program the web, no
amount of ranting on linux-kernel is going to change it.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/



Re: thread rant

2000-09-02 Thread dean gaudet

On Sat, 2 Sep 2000, Ingo Molnar wrote:

> 
> On Fri, 1 Sep 2000, dean gaudet wrote:
> 
> > yup you can do this without threads.  apache-1.3+mod_ssl for example.
> > 
> > but it's not fun, and it's a lot more work on the portability side.  
> > inter-process shared memory and inter-process semaphores are
> > notoriously different across platforms... [...]
> 
> but it's slower (on SMP) and more error-prone to use threads. We have the
> following task: 'use multiple contexts and share some state'. The 'share
> everything' model overdoes this goal a bit. Why not share the *specific*
> state that should be shared, and nothing more? The fact that this is
> inconsistent across platforms is IMHO not a good excuse - it just shows
> the mistaken concept that threads should be used for such tasks. You are
> right about the semaphore part - i have plans to add a new type of
> semaphore to Linux, which are not as complex as SysV semaphores and are
> not persistent.

i don't understand why another semaphore type is needed -- about the only
semaphore missing is the pshared portion of posix.  (recently i ported a
large commercial MTA to linux and the only thing missing was the
pthread_mutexattr_{s,g}etpshare stuff.)

regarding using shared memory/multiprocess -- how do you handle the case
where the shared region needs to grow?

you're the expert here, tell me what i'm missing:

a threaded program growing its memory requires one cross-cpu TLB update in
case other threads are currently running; this requires n-1 messages where
n is the number of CPUs.

a shared memory/multiprocess program needs some sort of note in the shared
mem to indicate another page should be mapped; and as each process
discovers this need for a new mapping it issues a syscall. this requires m
syscalls where m is the number of processes.

if i understand what you're advocating, m will be much greater than n...
does shared mem still work out faster?

i actually think there's far more grossness to trying to figure out when
to grow a shared mem region -- you almost need to check every time you
follow a pointer.  and hopefully you can arrange to have the same mapping
in all processes or else you need some sort of extra page table... almost
forced to implement paging in software.

is this really what you mean?

i have no qualms about "sharing as little as possible".  i totally agree
with it.  i just think "sharing all of memory" is as close to as little as
you can get for some applications.  signals, cwd/chroot,
uid/gid/capabilities, this is all crap i don't care about sharing. file
descriptors -- yeesh these are hard, you want some sharing and some not
sharing.  (unix fds are one of the really gross places where you can see
that threading was not present in the original unix design.)

other than TLB/page-table changes is there anything else i'm missing which
makes SMP and threading "slow"?

-dean

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/



Re: thread rant [semi-OT]

2000-09-02 Thread Ingo Molnar


On Sat, 2 Sep 2000, J. Dow wrote:

> Dan, another thing to consider with multithreading is that it is a way
> to avoid "convoy" effects if there is a nice priority mechanism for
> first in first out messaging. [...]

yep, this is a frequent problem at the level of the kernel. We fixed such
a (longtime) performance bug just a couple of weeks ago in the TCP-accept
logic. We are using FIFO in most places where multiple contexts are
waiting. But is 'shared everything multithreading' the natural solution
for this? Nope, that statement is misleading. 'Multi-contexting' is the
solution. Those contexts can be 'shared-everything threads' or 'isolated
processes' as well.

Ingo

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/



Re: thread rant

2000-09-02 Thread Ingo Molnar


On Fri, 1 Sep 2000, dean gaudet wrote:

> yup you can do this without threads.  apache-1.3+mod_ssl for example.
> 
> but it's not fun, and it's a lot more work on the portability side.  
> inter-process shared memory and inter-process semaphores are
> notoriously different across platforms... [...]

but it's slower (on SMP) and more error-prone to use threads. We have the
following task: 'use multiple contexts and share some state'. The 'share
everything' model overdoes this goal a bit. Why not share the *specific*
state that should be shared, and nothing more? The fact that this is
inconsistent across platforms is IMHO not a good excuse - it just shows
the mistaken concept that threads should be used for such tasks. You are
right about the semaphore part - i have plans to add a new type of
semaphore to Linux, which are not as complex as SysV semaphores and are
not persistent.

Ingo

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/



Re: thread rant

2000-09-02 Thread Alexander Viro



On Sat, 2 Sep 2000, dean gaudet wrote:

> the thread bashing is mostly bashing programs which do things such as a
> thread per-connection.  this is the most obvious, and easy way to use
> threads, but it's not necessarily the best performance, and certainly
> doesn't scale.  (on the scalability side just ask yourself how much RAM is
> consumed by stacks -- how many cache lines will that consume, and how many
> TLB entries.  it sucks pretty fast.)
 
> state machines are hard.  while people on linux-kernel may be hot shot
> programmers who can do state machines in their sleep, this is definitely
> not the case for the average programmer.
> 
> fortunately fully threaded and fully state driven are two opposite ends of
> a spectrum, and there are lots of useful compromises in between where
> threads are used in a way that allows the average programmer to
> maintain/extend a codebase; while also getting the scalability of state
> machines.

Lovely. You've completely sidestepped the main part:

*threads* *are* *hard* *to* *write* *correctly*

Average programmer will fuck up and miss tons of race conditions. Better
than average programmers do. If you've got shared resource - you are in
for problems. Threads are useful. But they take more efforts and are much
harder to debug _and_ to prove correctness. In other words, that's one of
the last resort tools, not the first one. If you can do it without shared
state - don't bother with threads. Same as with rewrite in assmebler - do
it with small critical parts and don't unless you absolutely have to. The
first rule of optimisation: don't. Keep the critical sections small and if
you can avoid them - it's worth the efforts. You'll win a lot when it will
come to changing the thing. And you will have to change it, sooner or
later. Same goes for debugging. Non-threaded code is easier to understand.
Yes, you may be very clever. But you'll have to debug it on Friday evening
after a hard week when you want only one thing - go home and sleep. Or
somebody else will and he will curse you. KISS. And threads are _not_
simple.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/



Re: thread rant

2000-09-02 Thread dean gaudet

On Fri, 1 Sep 2000, Mike A. Harris wrote:

> I've heard comments from Alan, and others in the past bashing
> threads, and I can understand the "threads are for people who
> can't write state machines" comments I've heard, but what other
> ways are there of accomplishing the goals that threads solve in
> an acceptable manner that gives good performance without coding
> complexity?

the thread bashing is mostly bashing programs which do things such as a
thread per-connection.  this is the most obvious, and easy way to use
threads, but it's not necessarily the best performance, and certainly
doesn't scale.  (on the scalability side just ask yourself how much RAM is
consumed by stacks -- how many cache lines will that consume, and how many
TLB entries.  it sucks pretty fast.)

state machines are hard.  while people on linux-kernel may be hot shot
programmers who can do state machines in their sleep, this is definitely
not the case for the average programmer.

fortunately fully threaded and fully state driven are two opposite ends of
a spectrum, and there are lots of useful compromises in between where
threads are used in a way that allows the average programmer to
maintain/extend a codebase; while also getting the scalability of state
machines.

this is where "worker thread pools" and message queues come in.

for example, consider an IMAP server.  the fully threaded implementation
would have a thread per connection.  but most connections sit idle most of
the time.  instead restructure it so that there is a thread per
in-progress command; plus one thread doing a state machine for all the
idle connections.  this scales much better because you only have as many
threads as active commands.  the actual IMAP code itself can be written in
the comfortable threading model rather than a state model.

it's still not perfect -- large mail messages sent to slow clients chew a
thread for an inordinate amount of time.  an obvious next modification
would be to let the state thread also handle the sending of messages. this
can be done relatively cleanly.

part of the apache-2.0 design was to allow for such a setup -- using a
thread for the "thinking" part of each HTTP request, and once a response
object is decided on, it is passed back to the state machine.  (responses
generally fit into the categories of disk file, pipe, or memory region.)
but nobody has yet implemented beyond thread-per-connection.

-dean

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/



Re: thread rant [semi-OT]

2000-09-02 Thread J. Dow

> In summary, when "multithreading" floats into your mind, think
> "concurrency." Think very carefully about how you might simultaneously
> exploit all of the independent resources in your computer. Due to the long
> and complex history of OS development, a different API is usually required
> to communicate with each device. (e.g. old-school UNIX has always handled
> non-blocking network I/O with select(), but non-blocking disk I/O is
rather
> new and must be done with AIO or threads; and don't even ask about
> asynchronous access to the graphics card =).

Dan, another thing to consider with multithreading is that it is a way to
avoid "convoy" effects if there is a nice priority mechanism for first in
first out messaging. Until NT crufted in its IO Completion model it was
highly prone to either starvation or convoy problems with certain problems.
If you fired off reads on several interfaces which all experienced about the
same problem the first on in the array searched by the multiple object
wait function was more likely to get serviced than the others. The initial
solution reordered the list each pass through the wait. IO Completion
actually added in first in first out messaging for all the messages
reaching that particular wait for io completion call. This made a VERY
measureable improvement in performance overall. You can run into
the same problems with psuedo-threading in state machines with
polling loops only it's a whole lot uglier. (Been there, done that, kicked
myself, bought the teeshirt in disgrace, and retreated to a proper
solution.)

(Heh, incidentally I was rather surprised by the time I hit NT tasking
to discover its array based message handling. I was used to the
FIFO message queueing on AmigaDOS that it enjoyed from day
zero. So I wrote as if I had that on NT I learned the hard way.)

{^_^}


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/



Re: thread rant [semi-OT]

2000-09-01 Thread Dan Maas

> All portability issues aside, if one is writing an application in
> Linux that one would be tempted to make multithreaded for
> whatever reason, what would be the better Linux way of doing
> things?

Let's go back to basics. Look inside your computer. See what's there:

1) one (or more) CPUs
2) some RAM
3) a PCI bus, containing:
4)   -- a SCSI/IDE controller
5)   -- a network card
6)   -- a graphics card

These are all the parts of your computer that are smart enough to accomplish
some amount of work on their own. The SCSI or IDE controller can read data
from disk without bothering any other components. The network card can send
and receive packets fairly autonomously. Each CPU in an SMP system operates
nearly independently. An ideal application could have all of these devices
doing useful work at the same time.

When people think of "multithreading," often they are just looking for a way
to extract more concurrency from their machine. You want all these
independent parts to be working on your task simultaneously. There are many
different mechanisms for achieveing this. Here we go...

A naively-written "server" program (eg a web server) might be coded like so:

* Read configuration file - all other work stops while data is fetched from
disk
* Parse configuration file - all other work stops while CPU/RAM work on
parsing the file
* Wait for a network connection - all other work stops while waiting for
incoming packets
* Read request from client - all other work stops while waiting for incoming
packets
* Process request - all other work stops while CPU/RAM figure out what to do
  - all other work stops while disk fetches requested file
* Write reply to client - all other work stops until final buffer
transmitted

I've phrased the descriptions to emphasize that only one resource is being
used at once - the rest of the system sits twiddling its thumbs until the
one device in question finishes its task.


Can we do better? Yes, thanks to various programming techniques that allow
us to keep more of the system busy. The most important bottleneck is
probably the network - it makes no sense for our server to wait while a slow
client takes its time acknowledging our packets. By using standard UNIX
multiplexed I/O (select()/poll()), we can send buffers of data to the kernel
just when space becomes available in the outgoing queue; we can also accept
client requests piecemeal, as the individual packets flow in. And while
we're waiting for packets from one client, we can be processing another
client's request.

The improved program performs better since it keeps the CPU and network busy
at the same time. However, it will be more difficult to write, since we have
to maintain the connection state manually, rather than implicitly on the
call stack.


So now the server handles many clients at once, and it gracefully handles
slow clients. Can we do even better? Yes, let's look at the next
bottleneck - disk I/O. If a client asks for a file that's not in memory, the
whole server will come to a halt while it read()s the data in. But the
SCSI/IDE controller is smart enough to handle this alone; why not let the
CPU and network take care of other clients while the disk does its work?

How do we go about doing this? Well, it's UNIX, right? We talk to disk files
the same way we talk to network sockets, so let's just select()/poll() on
the disk files too, and everything will be dandy... (Unfortunately we can't
do that - the designers of UNIX made a huge mistake and decided against
implementing non-blocking disk I/O as they had with network I/O. Big booboo.
For that reason, it was impossible to do concurrent disk I/O until the POSIX
Asynchronous I/O standard came along. So we go learn this whole bloated API,
in the process finding out that we can no longer use select()/poll(), and
must switch to POSIX RT signals - sigwaitinfo() - to control our server***).
After the dust has settled, we can now keep the CPU, network card, and the
disk busy all the time -- so our server is even faster.


Notice that our program has been made heavily concurrent, and I haven't even
used the word "thread" yet!


Let's take it one step further. Packets and buffers are now coming in and
out so quickly that the CPU is sweating just handling all the I/O. But say
we have one or three more CPU's sitting there idle - how can we get them
going, too? We need to run multiple request handlers at once.

Conventional multithreading is *one* possible way to accomplish this; it's
rather brute-force, since the threads share all their memory, sockets, etc.
(and full VM sharing doesn't scale optimally, since interrupts must be sent
to all the CPUs when the memory layout changes).

Lots of UNIX servers run multiple *processes*- the "sub-servers" might not
share anything, or they might file cache or request queue. If we were brave,
we'd think carefully about what resources really should be shared between
the sub-servers, and then implement it manually using

Re: thread rant

2000-09-01 Thread J. Dow

(Hm, I meant for a copy of this to go to the list, too. So here it is.)

Mike Harris comments:
> > I've heard comments from Alan, and others in the past bashing
> > threads, and I can understand the "threads are for people who
> > can't write state machines" comments I've heard, but what other
> > ways are there of accomplishing the goals that threads solve in
> > an acceptable manner that gives good performance without coding
> > complexity?
>
> Threads are a handy way to allow a prioritized state machine
> operations. State machines are nice and I use them and have
> used them to good effect. (The MX3000 SatCom modem data
> mode and fax mode are both state machines - as far as the
> Inmarsat spec vs the Facsimile spec allowed.) I also use
> multithreaded code. I use it when I want to switch from thread
> to thread based on input events and priority. I don't want to
> continue to run through a low priority "state" before I can service
> a high priority "state". Threads are the mechanism. People who
> make declarations such as you cite remind me of people who
> yank the gas pliers out of their back pockets to pound in 10
> penny nails. If you need a hammer and do not have one then
> any tool begins to look like a hammer.
>
> > This is all just curiosity.  I've considered trying some thread
> > programming, but if it is as stupid as it sounds, I'd rather
> > learn the "right" way of writing code that would ordinarily be
> > done with threads, etc..  Right now, I'm using fork() all over
> > the place and don't much care how much waste it is...  I'd like
> > to though.
>
> Think on what it is you want to do. State machines are REAL
> good when every state should run to completion before you
> run the next state. State machines are not good when your
> program has functions that must be run at a higher priority
> than the other's while the others must not block when the
> higher priority thread blocks. Use the two tools with some
> discrimination and you can get wonderful results.
>
> > >The fact that the system implements threads speaks enough about
> > >it's capabilities. ie, it's trying hard to suck less. So, from my POV,
> > >we're looking to make Linux suck more by effectively emulating systems
> > >that are trying to suck less.
> >
> > Makes sense... if you understand the details of why threads
> > suck.  I understand there are some cache coherency issues, and
> > I've heard of other things as well, but is there an FAQ out there
> > saying "Why to not use threads?" that goes into good detail and
> > provides alternatives?
>
> Doesn't make sense to me, Mike. But then I use threads where
> threads are appropriate and state machines where state machines
> are appropriate and linear code where linear code is appropriate.
> Consider threads a tool. Learn how the tool works. Then select it
> and use it when the situation warrants it.
>
> > >But, I've never done anything worthwhile for Linux, so take this for
what
> > >it's worth, from an asshole.
> >
> > Works for me.  ;o)
>
> Sometimes I remember I am a lady and that ladies don't reply to that
> level of comment. 'Sides, if I did reply it'd not be by fainting. He might
> discover a new apperature somewhere on his body that resembles
> the orifice referenced that he didn't plan on or have OEM.
>
> {^_-}
>
>

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/



Re: thread rant

2000-09-01 Thread Lincoln Dale

At 22:48 01/09/00, Michael Bacarella wrote:

>Q: Why do we need threads?
>A: Because on some operating systems, task switches are expensive.
>
>Q: So, threads are a hack to get around operating systems that suck?
>A: Basically.

urgh, i think you've missed the point.

while threads /may/ be abused by many applications where fork() or 
decent-event-queue/state-machine would probably produce much better 
performance (i believe some of the java libraries are a perfect example of 
this), there are _MANY_ applications where threads work, work well, and are 
superior to the alternatives available (fork with shm segments).

one such example is cpu compultationally-expensive work where some degree 
of working-set is required to be shared between processes.  one could use 
fork(), run multiple instances, have them register to a shm segment and 
then implement some form of IPC between them.
alternatively, you could create 'n' work threads where "n == NR_CPUs" with 
the working-set automatically available to all worker threads.  for 
whatever synchronization is required, you don't have to write your IPC 
mechanism - mutexes come standard with things like pthreads.  (of course, 
there is no excuse for bad programming or bad algorithms; mutex use should 
be kept to a minimum).  perhaps you then need this application to then do 
bulk disk-i/o?  one-thread-per-disk-spindle works nicely in this scenario too.

threads are useful and powerful.  perhaps the real problem with threads are 
that it is too easy to write bad code using them.
caveat emptor.


cheers,

lincoln.


--
   Lincoln Dale   Content Services Business Unit
   [EMAIL PROTECTED]  cisco Systems, Inc.   | |
||||
   +1 (408) 525-1274  bldg G, 170 West Tasman    
   +61 (3) 9659-4294 <<   San Jose CA 95134..:||:..:||:.. 

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/



Re: thread rant

2000-09-01 Thread Mike A. Harris

On Fri, 1 Sep 2000, Michael Bacarella wrote:

>Q: Why do we need threads?
>A: Because on some operating systems, task switches are expensive.
>
>Q: So, threads are a hack to get around operating systems that suck?
>A: Basically.

Am I understanding correctly then that using fork() is
faster/better?  Or should one use a state machine?  I'm just
asking out of curiosity because thread programming is new to me.

All portability issues aside, if one is writing an application in
Linux that one would be tempted to make multithreaded for
whatever reason, what would be the better Linux way of doing
things?

I've heard comments from Alan, and others in the past bashing
threads, and I can understand the "threads are for people who
can't write state machines" comments I've heard, but what other
ways are there of accomplishing the goals that threads solve in
an acceptable manner that gives good performance without coding
complexity?

This is all just curiosity.  I've considered trying some thread
programming, but if it is as stupid as it sounds, I'd rather
learn the "right" way of writing code that would ordinarily be
done with threads, etc..  Right now, I'm using fork() all over
the place and don't much care how much waste it is...  I'd like
to though.

>Q: So, why must Linux support threads?
>A1:  : |
>A2: So other programs can be easily ported to Linux!
>
>That can already happen. It's not the *best* implementation. It's
>not as fast as it can be. But it works. And that's all it should do. If
>you're not happy, cope.
>
>   "But threads on this system are faster than on Linux!"
>
>The fact that the system implements threads speaks enough about
>it's capabilities. ie, it's trying hard to suck less. So, from my POV,
>we're looking to make Linux suck more by effectively emulating systems
>that are trying to suck less.

Makes sense... if you understand the details of why threads
suck.  I understand there are some cache coherency issues, and
I've heard of other things as well, but is there an FAQ out there
saying "Why to not use threads?" that goes into good detail and
provides alternatives?


>But, I've never done anything worthwhile for Linux, so take this for what
>it's worth, from an asshole.

Works for me.  ;o)


--
Mike A. Harris Linux advocate 
Computer Consultant  GNU advocate  
Capslock Consulting  Open Source advocate

Be up to date on nerd news and stuff that matters:  http://slashdot.org

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/



Re: thread rant

2000-09-01 Thread dean gaudet

On Fri, 1 Sep 2000, Michael Bacarella wrote:

> Q: Why do we need threads?
> A: Because on some operating systems, task switches are expensive.

maybe this problem will help you understand threads better:

design a webserver which supports SSL session keys.  consider the
performance of your webserver on single CPU and multiple CPU boxes.
consider also the performance of your webserver on datasets which do
not fit within RAM, hence requiring disk i/o.  and finally, consider
the effect of having one disk spindle versus multiple disk spindles.

in this problem, the "SSL session key" requirement is there so that state
information for previous connections has to be available to efficiently
process future connections.  (the ssl session key reduces the number of
times the RSA key signature needs to be performed.)

the SMP requirement is to indicate why single process select loop won't
always cut it.  (especially if you're doing SSL you'd like to grind crypto
on all CPUs).

the disk i/o, multiple spindle requirement is there so you consider what
it takes to get a disk array with 50 disks in it going full-tilt.  
(nevermind stuffing the elevator on a single disk -- i'm just trying to
make it really obvious how much parallelism may be available in a system.)

yup you can do this without threads.  apache-1.3+mod_ssl for example.

but it's not fun, and it's a lot more work on the portability side.  
inter-process shared memory and inter-process semaphores are notoriously
different across platforms... just look at the "mm" library from mod_ssl
(which is a less puke-filled version of what's in
apache-1.3/src/main/http_main.c).

-dean

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/



thread rant

2000-09-01 Thread Michael Bacarella


Q: Why do we need threads?
A: Because on some operating systems, task switches are expensive.

Q: So, threads are a hack to get around operating systems that suck?
A: Basically.

Q: So, why must Linux support threads?
A1:  : |
A2: So other programs can be easily ported to Linux!

That can already happen. It's not the *best* implementation. It's
not as fast as it can be. But it works. And that's all it should do. If
you're not happy, cope.

"But threads on this system are faster than on Linux!"

The fact that the system implements threads speaks enough about
it's capabilities. ie, it's trying hard to suck less. So, from my POV,
we're looking to make Linux suck more by effectively emulating systems
that are trying to suck less.

But, I've never done anything worthwhile for Linux, so take this for what
it's worth, from an asshole.

-MB

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/