Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 15 Jul 2003 03:35:24 -0700
From:      Terry Lambert <tlambert2@mindspring.com>
To:        Petri Helenius <pete@he.iki.fi>
Cc:        freebsd-threads@freebsd.org
Subject:   Re: LinuxThreads replacement
Message-ID:  <3F13D8EC.8899DA42@mindspring.com>
References:  <007601c3467b$5f20e960$020aa8c0@aims.private> <004d01c348ae$583084f0$812a40c1@PETEX31>	<3F12EF5A.71249E4D@mindspring.com> <16146.65087.69689.594109@emerger.yogotech.com> <3F13B1B4.8765B8F3@mindspring.com> <049201c34aab$9361d070$812a40c1@PETEX31>

next in thread | previous in thread | raw e-mail | index | archive | help
Petri Helenius wrote:
> > One evil purpose threads can be used for is to intentionally exploit
> > a decriptor close race with a blocking fd operation not protected by
> > giant, such that the close invalidates the descriptor before the
> > blocking operation completes, after which the code following the
> > blocking operation dereferences the (now invalid) descriptor contents=
=2E
> >
> Are you saying that this is a fundamental flaw in the design or a bug
> that hasn=B4t been fixed as of yet?

It depends on how you intend to handle close(2) in the case that
there is a positive reference count greater than 1 for the fd
being closed out from under the kernel, and it depends on how
you intend to handle references on the f_data (and, now, f_vnode)
members of struct file to protect them.

The really evil way to do this would be to either fail or block the
close.  I think there is actually a lot of Java code that expects
the close call to abort the pending blocked operation in progess on
thread #2 when thread #1 closes the descriptor out from under it
(that's what Solaris does), which probably means that's the only
really viable option.


> > I can also guarantee you from a performance perspective that an FSA
> > will beat almost anything else you could write, in terms of raw
> > ability to move data, or support high client loads, and will handily
> > beat threads, unless you are on an SMP system, and aren't willing to
> > run multiple copies of the program to do your scaling.
> =

> The usual thing I run across is to how effectively manage large
> fd_set=B4s without using threaded architechture. Spinning through a few=

> thousand descriptors for almost each read gets expensive quickly.
> (or write, if you=B4re going that way)
> As usual, suggestions are welcome and might lead to more better
> code in the world...

The general answer is "kqueue is your friend".  8-).

One thing that is very helpful to do is to seperate out the flags
and hint arguments to KNOTE(), and then pass the user void argument
through to the knote() code.  Doing this is very handy, besides
enabling you to raise maxproc higher than the point where it
collides with the hints bits, I mean.

One of the things Linux-ites always complain about when talking
about kqueue() is "it's level triggered, not edge triggered".  By
this, they mean that you don't get a separate event per source
event (e.g. if you get three packets of data, and you haven't
reaped the note in the time it takes to do this, then you will
only reap a single note with the aggregate byte count in it, rather
than three notes with the bytecount per packet).

By passing in the user's void * address, you can guarantee that
the user and a given new kevent can make a contract to deal with
event disposition, e.g. into a buffer to contain a list of events.
This lets you address the Linux argument.

For example, if you were writing an AnitVirus package (speaking
hypothetically), then you could trap all opens and/or writes to
files, and find the guilty party who's doing the infecting, at
the time of the infection.  Then you terminate the program.


> > Yes, this is somewhat mitigated by the fact that it's easier to write=

> > threads code than an FSA, such that a lesser coder is still able to
> > be productive.  As a class, it's a tool I would lump in with things
> > like "perl".
> =

> perl is good "Leatherman(TM)" tool.

"Perl is a tool for other people."  8-).  It's good for a
quick-and-dirty implementation of something, and, as far as
scripting languages go, it's possible to write readable perl;
in practice, however, almost no one does.  Everyone has their
favorite method of solving a problem, and perl offers lots of
ways to skin a cat.  In practice, that tends to make the code
only easily readable by the original author.

Alfred told me he was helping someone out with some threads
code the other day, and they ended up managing the server
connections in a threads separate from the worker thread that
had to deal with the descriptor.  As a result, the tended to
do things like close fd's out from under their worker threads
(which is what put me in mind of the close race problem).  I
put this in the same class of naieve coding errors that one
commonly makes when trying to maintain someone else's perl
code.  It's not so much that either one is inherently bad,
but that they both tend to magnetize your feet any time you
pick up a gun.  8-).


> > All that said, FreeBSD's libkse is much less offensive, in terms of
> > overhead and cost, than a raw 1:1 implementation, like the one in
> > the current Solaris, or Linux.  Solaris' argument is that it's hard
> > to get something like that correct, and they were worried about the
> > implementation bugs; that just adds fodder to the argument that you
> > should avoid threaded code, where possible.
> =

> There are people who solve their database performance problems by
> adding memory until everything is cached. Putting more hardware in
> seems to be default operating pattern for Solaris environments. And
> everybody seems to be happy with it. At least there the OS does not
> bloat constantly like it does in the WinTel land.

I guess to a large degree the ability to do this for Solaris
comes from the fact that they are a 64bit OS, so they can just
stuff RAM into the box until the power supply can no longer
cope with it.  8-).  It helps to have the necessary head room
to be *able* to throw hardware at the problem.

-- Terry



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3F13D8EC.8899DA42>