|
Home > Archive > Unix Programming > February 2006 > Are Device Drivers Reentrant -- or Daemons?
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Are Device Drivers Reentrant -- or Daemons?
|
|
| Olumide 2006-02-09, 6:02 pm |
| Hi -
I wonder if device drivers are reentrant, my guess is perhaps not. Here
is my possibly-flawed reasoning:
A process calls a kernel IO function, saves state, context switch,
enters kernel mode (at this point the process is running kernel code),
after which the request is passed to the appropriate device driver -
and here's the source of confusion. If the request is for disk access,
reads and/or writes cannot have to be scheduled, and this suggests that
there be some sort of adjudicator (okay, scheduler) which is aware of
all requests and services them as it sees fit. And although the process
now that its in kernel mode, and now executing device driver code (I
know I'm on shaky ground here) can access kernel information relating
to requests, it seems unwise to me to allow every process in kernel
mode to play the scheduler.
So, I guess my question is: does the process pass its request to a
kernel level process running the device driver and then block, or does
it act the scheduler in the manner I (probably wrongly) suggested
above.
Thanks for resisting the urge to flame me ;-)
- Olumide
| |
| Maxim S. Shatskih 2006-02-09, 6:02 pm |
| > A process calls a kernel IO function, saves state, context switch,
No context switch. Mode switch - yes. Saving state - yes. But still the same
process identity and the same thread identity (with the same related stuff -
security context, parent IDs etc).
> and here's the source of confusion. If the request is for disk access,
> reads and/or writes cannot have to be scheduled, and this suggests that
> there be some sort of adjudicator (okay, scheduler)
This is a part of each driver itself, possibly using some general-purpose queue
implementation in the kernel (like IoStartPacket/IoStartNextPacket in Windows).
--
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
maxim@storagecraft.com
http://www.storagecraft.com
| |
| Francesco Frigo 2006-02-09, 6:02 pm |
| Hi,
> it seems unwise to me to allow every process in kernel
> mode to play the scheduler.
Processes running in "kernel mode" are can be seen as "kernel processes"
because they are in fact executing kernel code, which is trustworthy by
definition.
Hence what you should do is:
1) acquire a spinlock for the driver request queue;
2) enqueue your I/O request;
3) go back to user mode (if you have asynchronous I/O) or block
(sleep/suspend the process) until the driver signals you;
Then your driver would dequeue I/O requests according to some priority
criteria. The simplest one is FIFO, but there are more efficient
ones.
> So, I guess my question is: does the process pass its request to a
> kernel level process running the device driver and then block, or does
> it act the scheduler in the manner I (probably wrongly) suggested
> above.
See above.
Probably what you were missing was the lock/signal part.
HTH,
Francesco Frigo
--
To e-mail me, remove "NOSPAM" from my e-mail address.
| |
| Olumide 2006-02-09, 6:02 pm |
|
Francesco Frigo wrote:
> Processes running in "kernel mode" are can be seen as "kernel processes"
> because they are in fact executing kernel code, which is trustworthy by
> definition.
Thanks.
> Hence what you should do is:
> 1) acquire a spinlock for the driver request queue;
> 2) enqueue your I/O request;
> 3) go back to user mode (if you have asynchronous I/O) or block
> (sleep/suspend the process) until the driver signals you;
>
> Then your driver would dequeue I/O requests according to some priority
> criteria. The simplest one is FIFO, but there are more efficient
> ones.
So, you're saying is that the device driver is a kernel level process?
....
(BTW, I'm not trying to write a device driver. I just want to know
more.)
| |
| David Schwartz 2006-02-09, 6:02 pm |
|
"Olumide" <50295@web.de> wrote in message
news:1139516768.361867.113010@o13g2000cwo.googlegroups.com...
> So, you're saying is that the device driver is a kernel level process?
No, a device driver is not a process. It is a chunk of code that is
executed by the kernel as its functions are invoked. It can start a kernel
level process if it wants to, but that would only be part of the driver.
DS
| |
| Paul Barker 2006-02-09, 6:02 pm |
| The device driver could be a piece of kernel code, or it could be a
user process, or it could even be running on a different machine (in a
distributed OS). Basically, it depends on the system. For linux most
drivers run in kernel mode, in windows I think its a mix of kernel mode
and user mode depending on the device.
Some more info about what system you're thinking of would help.
Cheers,
Paul
| |
| Olumide 2006-02-09, 6:02 pm |
| David Schwartz wrote:
>
> No, a device driver is not a process. It is a chunk of code that is
> executed by the kernel as its functions are invoked. It can start a kernel
> level process if it wants to, but that would only be part of the driver.
Okay, I know. The driver is code. But what I meant to say was, who
(typically) runs it?
| |
| Olumide 2006-02-09, 6:02 pm |
| Paul Barker wrote:
> The device driver could be a piece of kernel code, or it could be a
> user process, or it could even be running on a different machine (in a
> distributed OS). Basically, it depends on the system. For linux most
> drivers run in kernel mode, in windows I think its a mix of kernel mode
> and user mode depending on the device.
>
> Some more info about what system you're thinking of would help.
Thanks Paul, but please refer to my original question. I am interested
in the operation(?) of device drivers, and I have no perticular
architecture in mind, but I suppose mordern OSs have similar principles.
| |
| David Schwartz 2006-02-09, 6:02 pm |
|
"Olumide" <50295@web.de> wrote in message
news:1139520049.821751.182140@g44g2000cwa.googlegroups.com...
> David Schwartz wrote:
[vbcol=seagreen]
[vbcol=seagreen]
> Okay, I know. The driver is code. But what I meant to say was, who
> (typically) runs it?
There are three common cases:
1) The kernel discovers the hardware and loads/activates the appropriate
driver by calling its initialization function. The initialization function
adds information about the hardware to kernel tables that result in the
kernel making more calls into the driver later. The calls occur from the
kernel's own contexts, usually meaning the kernel's startup context,
interrupt context, or the context of a user-space process that indirectly
invokes the driver. This is typical for network drivers.
2) A user-space process opens a device file that refers to a particular
driver. The kernel calls the device driver's 'open' function from a kernel
context associated with that process. The device driver is free to create a
kernel thread or do other things during the invocation of this function. If
it allows the 'open' to succeed, the kernel will typically refer all other
things related to that file to that device driver, calling it in the kernel
context corresponding to the invoking process. This is typical for drivers
like the null driver.
3) A user-space process commands the kernel to load/activate a device
driver. The kernel loads and links the device driver code and calls its
startup function, often from the kernel context corresponding to some kind
of 'module loader' process. The device driver generally makes calls into the
kernel that arrange for the kernel to call it back when things happen, often
using specific calls for the type of driver it is. This is typical for
drivers that are dynamically loaded, such as USB device drivers.
DS
| |
| Paul Barker 2006-02-09, 6:02 pm |
| Modern OS's have very different principles depending on whether they
are monolithic or micro-kernel, as well as other design issues. A
common idea, which I think is used in linux, is to have a central
scheduler for block devices. This scheduler handles all block device
requests by simply queueing them and the drivers process / kernel
thread / whatever reads items off the queue. This avoids the problems
of re-entrancy everywhere except the main scheduler, which can be
protected, for example, by a spinlock. This is effectively like the
drivers running as daemons. The other advantage of central handling for
block devices is the ability to keep a central cache.
On the other hand, consider that with some devices it makes no sense
for more than 1 process to have them open at one time (maybe a simple
console or soundcard), and some devices have no issues at all with
re-entracy (eg. /dev/null). You might want to take a look at the
Windows DDK (device driver kit - for writing device drivers) which will
give you some idea of the interface between drivers and the kernel in
Windows (I have very little idea of this so I can only provide a
pointer). In linux (at least in my kernel) the folder "block" at the
root of the source tree contains all the generic block device stuff.
There may also be some good docs included with the kernel source.
At the end of the day, most operating systems have no compatibility
with drivers from other operating systems. Also, devices themselves
need handling in a huge variety of ways and a single OS may have
several ways of comunicating with different types of devices. It's a
zoo.
HTH,
Paul Barker
| |
| Alexei A. Frounze 2006-02-10, 3:02 am |
| "Olumide" <50295@web.de> wrote in message
news:1139520049.821751.182140@g44g2000cwa.googlegroups.com...
> David Schwartz wrote:
>
> Okay, I know. The driver is code. But what I meant to say was, who
> (typically) runs it?
The dumbest way would be basically to process the I/O request right away,
which may have a look like basically calling a subroutine. When that
subroutine finishes, it returns to the caller. This is the way BIOS and DOS
worked (unless disk caches were loaded such as smartdrv.exe). A call to r/w
a file on the disk (DOS int 21h) ended up calling int 13h (BIOS routines for
disk I/O). The actual I/O routine could in fact require interrupt servicing
if it is important to get some information from the device and this
information isn't available immedieately (e.g. DMA signals about I/O
completion by issuing an IRQ). This is the point where you can't truly think
of the things in terms of single-processing or plain subroutines, some form
of preemtion and multiprocessing is already present here. Now, if we
consider the same thing but with one of the popular disk caches for DOS
(e.g. smartdrv), then the I/O request is passed to the caching software and
it is free to do some job in the background, or kind off in parallel, to
your application that issues the I/O requests. The cache activity may be
triggered by several events: incoming I/O requests, timer interrupts (e.g.
buffered data gets saved from memory to disk every n seconds; reading
ahead), completion of the I/O on the disk level (e.g. DMA interrupt or
simply completion of int 13h). This ultimately makes the caching software
appear more complex than just a subroutine to call, it really becomes
something of the process/daemon/whatever. And now, if we introduce a
multitasking OS (which DOS wasn't), then this scales up manyfold. And it may
be possible that not just one process services the I/O requests, but
actually a few may be available to do some job for the users. And them,
consider the case when you have multiple I/O devices, a few hard drives. If
you want the I/O to be efficient, you definetely want to access them
independently, from different processes, so that you may do some meaningful
work with one drive fron one process/thread while the other one is serviced
by another. If you had just one, you'd process one at a time. Recently I
installed 2nd harddrive on my machine at work and it greatly improved the
usability of the machine while building the project on it. If the compiler
constantly does disk I/O and even doesn't utilize the CPU fully, you still
can't do much having just one disk because other applications need file
access too and therefore they get real unresponsive not because there's no
CPU time for them but because their requests get queued along with the
compiler requests and they don't get serviced quickly. That could probably
changed by altering priorities of the requests or applications (the latter
if the disk requests inherit the application priorities). But simply putting
another drive and removing the competition for the disk I/O fixes the
problem because the disks are accessed independently from different
procesess and don't interfere too much with one another. That's what I think
it is.
Alex
| |
| Matthias Bethke 2006-02-10, 7:49 am |
| begin followup to Paul Barker in comp.unix.programmer:
> In linux (at least in my kernel) the folder "block" at the
> root of the source tree contains all the generic block device stuff.
> There may also be some good docs included with the kernel source.
There's a pretty good book by O'Reilly on Linux device drivers from
kernel 2.0 to 2.4, available on dead trees as well as free hypertext:
http://www.xml.com/ldd/chapter/book/
cheers!
Matthias
--
end
| |
| Nils O. Selåsdal 2006-02-10, 7:49 am |
| Olumide wrote:
> Hi -
>
> I wonder if device drivers are reentrant, my guess is perhaps not. Here
> is my possibly-flawed reasoning:
>
> A process calls a kernel IO function, saves state, context switch,
> enters kernel mode (at this point the process is running kernel code),
> after which the request is passed to the appropriate device driver -
> and here's the source of confusion. If the request is for disk access,
> reads and/or writes cannot have to be scheduled, and this suggests that
> there be some sort of adjudicator (okay, scheduler) which is aware of
> all requests and services them as it sees fit. And although the process
> now that its in kernel mode, and now executing device driver code (I
> know I'm on shaky ground here) can access kernel information relating
> to requests, it seems unwise to me to allow every process in kernel
> mode to play the scheduler.
>
> So, I guess my question is: does the process pass its request to a
> kernel level process running the device driver and then block, or does
> it act the scheduler in the manner I (probably wrongly) suggested
> above.
All this depends entierly on the device driver (and OS).
Some devices are exclusive open - only one process can open them at a time.
Some performs synchronous operations on the device, and act pretty
much as a function call.
Some performs the operation in an async matter, they place the process
in a sleeping state, informs another subsystem to do some work, goes
on servicing other tasks and wakes up the process when , returning the
result. State might be stored in context of the calling process so other
processes doesn't interfer with other. Or (parts of it) could be shared
among other processes or kernel subsystems.
Some drivers doesn't work in the context of a process, but runs as part
of interrupt handlers and/or gets serviced at appropriate times - e.g.
right before doing context/mode switching. Some runs a seperate kernel
thread.
In short - it depends. On alot.
| |
| Norm Dresner 2006-02-10, 5:53 pm |
| "Olumide" <50295@web.de> wrote in message
news:1139520049.821751.182140@g44g2000cwa.googlegroups.com...
> David Schwartz wrote:
>
> Okay, I know. The driver is code. But what I meant to say was, who
> (typically) runs it?
It's functions are called by other kernel code. Therefore it's kernel
(level) code when it executes.
Norm
| |
| Gordon Burditt 2006-02-10, 5:53 pm |
| >> I wonder if device drivers are reentrant, my guess is perhaps not. Here
There are various definitions of reentrant, and some of them specify
that if it has to block waiting for exclusive access to a resource,
it's not reentrant. Almost all devices will handle a maximum of
less than an infinite number of requests at once (an exception
perhaps being a read-only clock). If the device is busy, you have
to queue the request until it can handle the new request. Some
controllers may have the ability to do multiple requests, but
not an infinite number of them (e.g. SCSI tagged requests).
[vbcol=seagreen]
Probable brain far here: requests DO have to be scheduled in the
case of hardware that can only handle, for example, one sector
read/write in progress simultaneously on any given hard drive.
[vbcol=seagreen]
Common code will likely handle this task. Some very old UNIX V6
disk drivers I worked on long ago had a common set of code that
sorted disk I/O requests by cylinder number, giving priority to
those near where the head currently was, reducing average seek time.
Really old device drivers (before the advent of "kernel processes")
had two parts: the top level, where they were called as subroutines
by processes making requests, and interrupt level, where the device
says it's done with something and the next part of the request or
the next request is started.
The top level generally worked as: if the device is busy, queue it,
otherwise start the request. The interrupt level worked as: this
request (or part of one) is done, mark it finished, grab the next
request from the queue and start it. Of course, locking is required
for manipulating the queue so it doesn't get messed up.
[vbcol=seagreen]
It's at the kernel level, but it may not be a kernel *process*.
When making an I/O request, it's acting on behalf of the calling
process, and the driver needs to know that context.
Gordon L. Burditt
| |
| James Harris 2006-02-10, 5:53 pm |
|
"Olumide" <50295@web.de> wrote in message
news:1139505082.346373.216660@z14g2000cwz.googlegroups.com...
> Hi -
>
> I wonder if device drivers are reentrant, my guess is perhaps not.
> Here
> is my possibly-flawed reasoning:
>
> A process calls a kernel IO function, saves state, context switch,
> enters kernel mode (at this point the process is running kernel code),
> after which the request is passed to the appropriate device driver -
> and here's the source of confusion. If the request is for disk access,
> reads and/or writes cannot have to be scheduled, and this suggests
> that
> there be some sort of adjudicator (okay, scheduler) which is aware of
> all requests and services them as it sees fit. And although the
> process
> now that its in kernel mode, and now executing device driver code (I
> know I'm on shaky ground here) can access kernel information relating
> to requests, it seems unwise to me to allow every process in kernel
> mode to play the scheduler.
>
> So, I guess my question is: does the process pass its request to a
> kernel level process running the device driver and then block, or does
> it act the scheduler in the manner I (probably wrongly) suggested
> above.
>
> Thanks for resisting the urge to flame me ;-)
>
> - Olumide
>
| |
| James Harris 2006-02-10, 5:53 pm |
|
"Olumide" <50295@web.de> wrote in message
news:1139505082.346373.216660@z14g2000cwz.googlegroups.com...
> Hi -
>
> I wonder if device drivers are reentrant, my guess is perhaps not.
> Here
> is my possibly-flawed reasoning:
>
snip
>
> So, I guess my question is: does the process pass its request to a
> kernel level process running the device driver and then block, or does
> it act the scheduler in the manner I (probably wrongly) suggested
> above.
I'm not sure what 'reentrant' means here. AFAIK a program code segment
is usually reentrant in that it cannot normally be written to - so
multiple processes can use the same copy of the code. A process is
normally not reentrant because it has state - variables, if you like. If
you can safely have multiple copies of that type of process - each with
its own state - does that make the process reentrant?
As for device drivers since you asked about the theory rather than a
specific OS I'd suggest not seeing them as a single process. There can
be multiple levels or, in theory, even multiple processes in a driver.
At the lowest level, since it is interacting with a device it seems to
me that it would have to have some state. In other words you couldn't
have multiple copies of it controlling one device unless the parts they
controlled were independent. (You may well have one copy of the driver
for each device of a given type.) The lowest level, then, cannot be
duplicated. However, each program may refer to the same code if that
code is non-modifiable, i.e. reentrant.
In short, it seems appropriate to classify /modules/ by whether they are
stateful or stateless rather than reentrant or not.
As for whether they block, that depends on the design. If the call to
the device driver requires no response the caller doesn't need to block.
If it requires a response it needs to block (until it gets a response).
Practically, if the response is something that is stored in the driver's
state it would not be normal to call that 'blocking' as the response
would always be ready immediately. If, on the other hand, the response
may require interaction with an external source - I/O device, server
process etc. - it would be normal to call that a blocking call (even if
the result can sometimes be available immediately due to, say,
read-ahead).
I guess you still may have intended a question different from what I've
tried to answer....!
HTH,
James
| |
| Gordon Burditt 2006-02-10, 8:48 pm |
| >> So, I guess my question is: does the process pass its request to a
>
>I'm not sure what 'reentrant' means here. AFAIK a program code segment
>is usually reentrant in that it cannot normally be written to - so
>multiple processes can use the same copy of the code. A process is
>normally not reentrant because it has state - variables, if you like. If
Reentrant code may have state in the form of *LOCAL* variables. If
it modifies GLOBAL variables, it's not reentrant. For example, the
C function strtok() is not reentrant because it is required to have
hidden state. You can't fix it without changing the interface.
(sometimes done by adding a parameter that points at someplace to
put the state, supplied by the caller).
I'm not sure what the term "reentrant process" means.
>you can safely have multiple copies of that type of process - each with
>its own state - does that make the process reentrant?
If you can safely have multiple activations of a function - each
with its own state - and they do not interfere with each other,
that makes the function reentrant.
>As for device drivers since you asked about the theory rather than a
>specific OS I'd suggest not seeing them as a single process. There can
I suggest not seeing them as a process at all (they don't have to
be, although some implementations do it that way). They are often
subroutines of the caller (granted, kernel code, not user-supplied
code) and interrupt handlers.
Gordon L. Burditt
| |
| Maxim S. Shatskih 2006-02-11, 6:06 pm |
| > using specific calls for the type of driver it is. This is typical for
> drivers that are dynamically loaded, such as USB device drivers.
At least in Windows, the USB drivers are loaded when the hardware is attached,
and not on software demand.
--
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
maxim@storagecraft.com
http://www.storagecraft.com
| |
| Maxim S. Shatskih 2006-02-11, 6:06 pm |
| > common idea, which I think is used in linux, is to have a central
> scheduler for block devices.
I don't remember this in Linux. Disk scheduler/queue code should surely know
about the concepts of SCSI tagged queue and such (hardware-side scheduling),
so, it must be as low level as possible.
In Windows, the disk driver just deals with partition stuff and translates
read/write to SCSI commands sent down to the so-called "storage port". No
queues in the disk driver.
The storage port is conceptually the driver for "controller with storage
devices attached", be it hardware or virtual, and talks SCSI on its upper edge.
For real SCSI controllers, it is SCSIPORT.SYS which a small plugin which is
exactly the controller's hardware driver (called "the miniport"). Essentially,
the main 2 routines called by SCSIPORT in the miniport are - StartIo and the
interrupt handler. The main reverse calls are - RequestComplete and NextRequest
(ready for next request). There are a couple of other calls too, and yes,
initialization and termination, but the general concept is such.
So, the driver for a real SCSI card is a miniport plugged to SCSIPORT, and must
be very simple - in fact, only the hardware-access stuff.
All queing is done in SCSIPORT.SYS, so is the SCSI queue tag assignment.
For IDE/SATA the things are similar, but ATAPI.SYS is instead SCSIPORT.SYS. It
contains the major duplicate of SCSIPORT code (I've heard MS just copy-pasted
it) for queue management and such, and also the standard PIO 0x1f0-based
controller driver code. ATAPI.SYS also supports plugins (like VIAIDE.SYS) for
to do DMA - to start DMA and so o.
ATAPI.SYS can only work with the hardware which is port-level compatible with
0x1f0 AT disk controller. All other IDE/SATA controllers are treated as SCSI in
Windows and the driver is a SCSIPORT's miniport.
For USB, the USBSTOR is a storage port, it converts the SCSI requests to USB
requests and sends them down to USB stack. I have doubts about USBSTOR having
any queues.
So is 1394, the storage port is SBP2PORT.SYS.
Needless to say that all these storage ports all support CD/DVD-ROMs and - for
XP and later - CD writing. w2k's USBSTOR driver did not support the command set
for CD writing.
So, the idea of central disk scheduling is bad a bit. For instance, the best
place of request scheduling of the USB disk is the USB stack itself, and not
some central "disk schedulers".
> requests by simply queueing them and the drivers process / kernel
I don't remember any "driver processes" in Linux disk stack. kflushd? Yes, but
it is above the disk stack, and not a "driver process".
> drivers running as daemons. The other advantage of central handling for
> block devices is the ability to keep a central cache.
This is not an advantage at all, since nobody ever needs it cache is a part
of the VFS/filesystems code in modern OSes, and is tied to mmap()
implementation - both need the "pile of physical pages which contain this
file's data" facility.
--
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
maxim@storagecraft.com
http://www.storagecraft.com
| |
| Maxim S. Shatskih 2006-02-11, 6:06 pm |
| > I'm not sure what 'reentrant' means here. AFAIK a program code segment
> is usually reentrant in that it cannot normally be written to - so
I'm against the whole word of ''reentrant". It is, in fact, something from the
old time of MS-DOS add-ons which tried to do multitasking from this pathetic
OS.
"Thread-safe" or "SMP-safe" are better words.
--
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
maxim@storagecraft.com
http://www.storagecraft.com
| |
| Paul Barker 2006-02-11, 6:06 pm |
| I'm talking rubbish, I should think before I start posting...
> I don't remember this in Linux
I said I thought it was used in linux. The rest is about the concept
not linux.
> So, the idea of central disk scheduling is bad a bit. For instance, the best
> place of request scheduling of the USB disk is the USB stack itself, and not
> some central "disk schedulers".
True. Scheduling centrally is simple and is possibly a good place to
start, but isn't really going to give good performance.
> I don't remember any "driver processes" in Linux disk stack.
Again I was talking about the concept, not linux.
> This is not an advantage at all, since nobody ever needs it cache is a part
> of the VFS/filesystems code in modern OSes, and is tied to mmap()
> implementation - both need the "pile of physical pages which contain this
> file's data" facility.
I think a central cache mapping (memory inode number, offset) onto a
page is a good idea, which can be used for block devices and normal
files, as long as every open file is given a memory inode. Since this
is the system I plan to use, If you've got any suggestions I'd be glad
to hear them. I'd rather re-design any problems now than after I've
coded them.
On the more general point, I was trying to illustrate that operating
systems are quite varied in how they interface drivers, and that even
in one OS there may be several ways of interfacing drivers (eg. Block
devices treated differently to character devices). That first paragraph
of my post maybe needed a bit more research.
Thanks,
Paul Barker
| |
| David Schwartz 2006-02-11, 6:06 pm |
|
"Maxim S. Shatskih" <maxim@storagecraft.com> wrote in message
news:dsl53j$1hja$1@gavrilo.mtu.ru...
[vbcol=seagreen]
> At least in Windows, the USB drivers are loaded when the hardware is
> attached,
> and not on software demand.
I'm pretty sure this is not the case. When hardware is attached, the
driver for whatever that hardware was attached to invokes a software process
to locate, load, and attach the appropriate driver. That software process
instructs the kernel to load the driver, which then attaches to the hardware
by attaching to the driver for whatever device the new hardware attached to.
DS
| |
| Maxim S. Shatskih 2006-02-11, 6:06 pm |
| > > At least in Windows, the USB drivers are loaded when the hardware is
>
> I'm pretty sure this is not the case. When hardware is attached, the
> driver for whatever that hardware was attached to invokes a software process
> to locate, load, and attach the appropriate driver. That software process
> instructs the kernel to load the driver, which then attaches to the hardware
> by attaching to the driver for whatever device the new hardware attached to.
Yes, but not on file open. Not on the app's demand "I want to work with this
device, please load the driver for it".
When PnP service demands driver loading - it is not when user app demands this.
--
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
maxim@storagecraft.com
http://www.storagecraft.com
| |
| Ben Bacarisse 2006-02-11, 6:06 pm |
| On Sun, 12 Feb 2006 00:37:09 +0300, Maxim S. Shatskih wrote:
>
> Yes, but not on file open. Not on the app's demand "I want to work with
> this device, please load the driver for it".
Are you referring to fixed device nodes? If so, you are are rather
out of date. That meachanism still exists if, for some reason, an app
were to want it, but I do no know on any that work that way. DS'd
description is pretty much what happens, particularly with USB devices
(with the usual Linux caveat that you can change it and do it another way
if you want).
--
Ben.
| |
| Nick Roberts 2006-02-11, 8:47 pm |
| Maxim S. Shatskih wrote:
>
> I'm against the whole word of ''reentrant". It is, in fact, something from the
> old time of MS-DOS add-ons which tried to do multitasking from this pathetic
> OS.
>
> "Thread-safe" or "SMP-safe" are better words.
I think the term 're-entrant' is fine; it is used in a lot of technical
documentation that I have seen. But, like most of these technical terms,
it is always best to define what you mean whenever you use it.
My own experience of the term is when it is applied to subroutines
within a program, where it has the meaning: two or more different
threads can safely call the same subroutine in parallel.
Of course, this definition can be hedged around with subtleties; for
example, an otherwise re-entrant subroutine may only be re-entrant for a
certain portion of the execution of the program (e.g. between completion
of an initialisation phase and initiation of a finalisation phase of the
program).
I don't think the term 're-entrant' is generally used when speaking
about operating system calls (even though, in practice, such a call will
typically just call some OS subroutine, perhaps in a privileged hardware
state). I have seen the term used in conjunction with calls to the
MS-DOS and PC BIOS APIs (in that they are not re-entrant), but never any
other OS.
I've never come across a full OS that supports multi-threading (or
equivalent) which doesn't provide a fully thread-safe API, except for
Win16 and Win32 (which I attribute to Microsoft's exceptional
incompetence in the technology). As for skeleton OSes (e.g. RTOSes and
microkernels), the timing and synchronisation details of using their
facilities can be extremely complex and tricky.
I use the term 'thread-safe' here to mean that two threads can call the
same API routine in parallel safely, except for interactions that are
(or should be!) explicitly detailed in the API documentation.
Thus, there can be a subtle but significant difference between the
meanings of 're-entrant' and 'thread-safe'. Again, the only safe thing
to do is to define exactly what you mean when you use one of these terms.
One interesting phenomenon that I have observed is that many programs
which are multi-threaded and work correctly on both single processor and
SMP (symmetric multi-processor) machines seem to work very inefficiently
on the SMP machines (e.g. barely any faster than on a single-processor
machine running at the same clock speed). This, I am convinced, is due
to the program using the memory caches on the SMP machine in a way that
causes a huge level of contention (each instance of which requires a
large number of bus transactions to be resolved). Thus, a program can be
'SMP-safe' but nevertheless almost 'SMP-useless'.
--
Nick Roberts
[Cross posted: alt.os.development; comp.unix.internals;
comp.unix.programmer]
| |
| Brian Raiter 2006-02-12, 2:47 am |
| > My own experience of the term is when it is applied to subroutines
> within a program, where it has the meaning: two or more different
> threads can safely call the same subroutine in parallel.
Perhaps this distinction is now mainly archaic, but I believe that the
original meaning had little to do with threads or processes. It
specifically meant a function that could be invoked while already in
the middle of an invocation. In other words, if the function called
another function during its execution, could that sub-function
potentionally wind up calling the first function again -- and if so,
would it work correctly or not? If it did, then the function was
re-entrant -- it could literally be re-entered.
b
| |
| Logan Shaw 2006-02-12, 2:47 am |
| Maxim S. Shatskih wrote:
>
> Yes, but not on file open. Not on the app's demand "I want to work with this
> device, please load the driver for it".
I guess that means that when you said "not on software demand", you
actually meant "not on apps' demand"? (There is such a thing as
user-mode software that isn't an application. At least on most
operating systems I've encountered.)
- Logan
| |
| Gordon Burditt 2006-02-12, 2:47 am |
| >> My own experience of the term is when it is applied to subroutines
>
>Perhaps this distinction is now mainly archaic, but I believe that the
>original meaning had little to do with threads or processes. It
>specifically meant a function that could be invoked while already in
>the middle of an invocation. In other words, if the function called
>another function during its execution, could that sub-function
>potentionally wind up calling the first function again -- and if so,
>would it work correctly or not? If it did, then the function was
>re-entrant -- it could literally be re-entered.
I don't think the distinction (applied to functions or subroutines)
is archaic. For example, can you safely call it from a C signal
handler (or an OS interrupt handler)? If it's reentrant, yes. If
it's not, you may have to go through a lot of trouble ensuring that
the main process is not going to be doing something that will get
messed up, and that perhaps means sections where signals are masked.
Note: a signal handler can't "wait" for the main process to do
something (like release a mutex); until it returns, the main process
won't do anything.
Can it safely be used recursively? If it's reentrant, yes (assuming
a couple of other things like it's not INFINITE recursion and you
won't run out of stack).
Gordon L. Burditt
| |
| Maxim S. Shatskih 2006-02-12, 5:56 pm |
| > I guess that means that when you said "not on software demand", you
> actually meant "not on apps' demand"?
Correct. Windows loads drivers on _PnP's_ demand, which is a part of the kernel
(software) and sometimes even user-mode helper service (when the driver is not
yet installed for this devnode, so an INF scan or maybe even bothering the user
is needed).
My intent was to say - "on _application_ software demand".
I know that there were some filesystems in Linux which could do this, IIRC
experimental ones. Windows also has this feature called SWENUM, but it is
hardly tied to audio/video subsystems, so that MS's people do not recommend to
use it in any other software.
Older Windows - 9x/Me - had the feature of loading the driver on file open. It
has its own major issues too - for instance, you cannot enumerate all devices
on the machine which expose some function (like audio), etc. Maybe that's why
modern Windows do not use it (except for SWENUM).
And, surely, non-PnP drivers (i.e. non-hardware related kernel modules) - can
be loaded on app's demand, if the app is running under sufficient privileges.
--
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
maxim@storagecraft.com
http://www.storagecraft.com
| |
| Maxim S. Shatskih 2006-02-12, 5:56 pm |
| > equivalent) which doesn't provide a fully thread-safe API, except for
> Win16 and Win32 (which I attribute to Microsoft's exceptional
> incompetence in the technology).
Please note where and when the Win32 APIs are not thread-safe. Please do not
mix them with the obsolete and ancient C runtime calls like asctime().
> I use the term 'thread-safe' here to mean that two threads can call the
> same API routine in parallel safely, except for interactions that are
> (or should be!) explicitly detailed in the API documentation.
Correct. All Win32 is such.
> which are multi-threaded and work correctly on both single processor and
> SMP (symmetric multi-processor) machines seem to work very inefficiently
> on the SMP machines (e.g. barely any faster than on a single-processor
> machine running at the same clock speed). This, I am convinced, is due
> to the program using the memory caches on the SMP machine in a way that
Yes. Starvation can also be an issue - if the CPU-heavy activity is waiting for
IO heavy activity, or such.
> 'SMP-safe' but nevertheless almost 'SMP-useless'.
Using SMP _just to raise the speed of the interactive UI app_ requires some
smartness. With server software, it is simpler - the OS dispatcher will take
care on thread distribution across CPUs, so, the CPU will no more be a
bottleneck for your server (if you had 100% before installing second CPU, you
will have 60% or so).
--
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
maxim@storagecraft.com
http://www.storagecraft.com
| |
| Brian Inglis 2006-02-12, 8:47 pm |
| On 9 Feb 2006 09:11:22 -0800 in comp.unix.internals, "Olumide"
<50295@web.de> wrote:
>I wonder if device drivers are reentrant, my guess is perhaps not. Here
>is my possibly-flawed reasoning:
>
>A process calls a kernel IO function, saves state, context switch,
>enters kernel mode (at this point the process is running kernel code),
>after which the request is passed to the appropriate device driver -
>and here's the source of confusion. If the request is for disk access,
>reads and/or writes cannot have to be scheduled, and this suggests that
>there be some sort of adjudicator (okay, scheduler) which is aware of
>all requests and services them as it sees fit. And although the process
>now that its in kernel mode, and now executing device driver code (I
>know I'm on shaky ground here) can access kernel information relating
>to requests, it seems unwise to me to allow every process in kernel
>mode to play the scheduler.
>
>So, I guess my question is: does the process pass its request to a
>kernel level process running the device driver and then block, or does
>it act the scheduler in the manner I (probably wrongly) suggested
>above.
[generalized conceptual overview of some points]
Device drivers may have to be reentrant to handle multiple devices, or
allow a device interrupt to be serviced while an I/O request is setup;
really depends on the OS and driver contexts.
If no operations are currently pending on a device, a requested
operation will be started immediately.
Any rejection or queuing of requests has to be handled by the device
driver as each device (sometimes controller) will have its own limit
on the number of concurrent users and/or requests it can handle (often
just one).
When a device interrupts to signal an operation is complete, and there
is a queued request, the next operation will be started before the
driver returns.
In the case of normal disk device drivers where more than one request
is queued, the driver could maintain the queue in order to minimize
the seek or rotational distance between subsequent operations.
HTH
--
Thanks. Take care, Brian Inglis Calgary, Alberta, Canada
Brian.Inglis@CSi.com (Brian[dot]Inglis{at}SystematicSW[dot]ab[dot]ca)
fake address use address above to reply
| |
| Nick Roberts 2006-02-13, 2:52 am |
| Maxim S. Shatskih wrote:
> Please note where and when the Win32 APIs are not thread-safe.
Maxim, I get the impression that you know a lot about the Win32 API, so
I'm surprised by your question. Note that I have been familiar with the
Win32 API from the earliest days of Windows, and I have studied their
design in detail. (In truth, I've forgotten most of what I used to know,
it was such a long time ago.)
The problem is essentially with the Microsoft documentation, which has
always been ludicrously inadequate, not least in the area of
multi-threaded programming. It would take me a very long time to give a
comprehensive list of these inadequacies, but let me give just one,
entirely typical example.
When a thread of a Windows program calls the Win32 API function
CreateWindow (or CreateWindowEx), a handle is returned to the created
window. This handle is used for all subsequent interaction with the
window via the Windows API.
For a long time (several years, I recall), people were trying to do
window operations using a multi-threaded program and wondering why it
didn't work. Eventually, Microsoft came clean, and admitted that only
the thread that created the window could subsequently manipulate that
window (in particular, only that thread can receive messages from the
window). For this reason (together with the fact that Unix doesn't
support threading at all), most Windows programs remain single-threaded;
programmers acquired the impression that multi-threading under Windows
was such a black art it wasn't worth the effort.
--
Nick Roberts
| |
| Maxim S. Shatskih 2006-02-13, 2:52 am |
| > > Please note where and when the Win32 APIs are not thread-safe.
>
> Maxim, I get the impression that you know a lot about the Win32 API, so
> I'm surprised by your question.
I'm surprised by your answer. Can you _name the exact Win32 API routines by
Microsoft_ which do not support multithreading?
> When a thread of a Windows program calls the Win32 API function
> CreateWindow (or CreateWindowEx), a handle is returned to the created
> window. This handle is used for all subsequent interaction with the
> window via the Windows API.
HWND belongs to a thread. IIRC it is well-described in lots of places, and is a
well known fact in Windows world.
> didn't work. Eventually, Microsoft came clean, and admitted that only
> the thread that created the window could subsequently manipulate that
> window (in particular, only that thread can receive messages from the
> window).
There is no such things like "messages from the window" in Windows. Messages TO
the window" - yes, a reality.
Several years? What several years? The adequate professionals knew this in
around 1996, which is 1 year after the desktop Windows version (Win95)
supported multi-threading. More so, the COM threading models were never any
secret, and there as an MS's document on them (around 1996 IIRC, just after
DCOM appeared in NT4).
>For this reason (together with the fact that Unix doesn't
> support threading at all),
Stupid ancient UNIXen - do not. Good UNIXen - do, and have pthreads
implementation mapped to real kernel threads (like modern Linux does).
>most Windows programs remain single-threaded;
> programmers acquired the impression that multi-threading under Windows
> was such a black art it wasn't worth the effort.
Depends on programmer skills in fact. I use threads in Windows in real-world
projects since around 1996, and never had any issues with them, so are the
people I was working with. I never heard about any avoiding threads in Win32
due to them being "too complex". Abusing threads (using a thread when there is
no real need in it) - yes, this is a reality :-)
--
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
maxim@storagecraft.com
http://www.storagecraft.com
| |
| Logan Shaw 2006-02-13, 2:52 am |
| Brian Raiter wrote:
>
> Perhaps this distinction is now mainly archaic, but I believe that the
> original meaning had little to do with threads or processes. It
> specifically meant a function that could be invoked while already in
> the middle of an invocation. In other words, if the function called
> another function during its execution, could that sub-function
> potentionally wind up calling the first function again -- and if so,
> would it work correctly or not?
I think that's a good point, and it seems worth making the distinction
between that and something that's merely thread-safe. One of the
things that often prevents code from being re-entrant is that it
modifies some global state[1]. Code that modifies state can be made
thread-safe by allocating some thread-local state and ensuring that
an invocation only modifies it's thread's state. However, this
code would not be truly re-entrant, since the one thread could enter
that section of code twice (via a recursive call or something along
those lines).
Perhaps a good example of this is strtok(). It uses some hidden
state, and a thread-safe strtok() could be implemented by making
per-thread storage for that hidden state. That would allow two
threads to call strtok() at once without interfering with each
other, but it wouldn't allow a recursive function to use strtok()
freely. For example, if you wanted to break the string
"a:b:1,2,3:c" down into the form {a, b, {1, 2, 3}, c}, you
might have one strtok() sequence breaking things down by colons
and another strtok() sequence breaking things down by commas
nested inside the first strtok() sequence. For this to work
within a single thread, a thread-safe strtok() wouldn't be
sufficient: you'd need a re-entrant one.
- Logan
[1] Or other state which isn't specific to the call to the code.
That is, it wouldn't necessarily have to be global as long as
two invocations can stomp on each other's state.
| |
| Alexei A. Frounze 2006-02-13, 2:52 am |
| "Nick Roberts" <nick.roberts@acm.org> wrote in message
news:84THf.302094$D47.23800@fe3.news.blueyonder.co.uk...
....
> When a thread of a Windows program calls the Win32 API function
> CreateWindow (or CreateWindowEx), a handle is returned to the created
> window. This handle is used for all subsequent interaction with the window
> via the Windows API.
>
> For a long time (several years, I recall), people were trying to do window
> operations using a multi-threaded program and wondering why it didn't
> work. Eventually, Microsoft came clean, and admitted that only the thread
> that created the window could subsequently manipulate that window (in
> particular, only that thread can receive messages from the window).
I think I had that same problem a few years ago when I wrote my first couple
of multithreaded GUI apps for windows. Surprisingly, I either hit an
exception at the point of accessing an MFC object from a different thread or
something of that sort and right at that point I found a comment in the MFC
source saying "don't do that". To me it was also unexpected, probably I
didn't know where in the documentation I should have read about what to
expect if I try doing that. I had to implement message communication between
the two threads to do something in one on behalf of the other.
> For this reason (together with the fact that Unix doesn't support
> threading at all), most Windows programs remain single-threaded;
> programmers acquired the impression that multi-threading under Windows was
> such a black art it wasn't worth the effort.
I'm not sure about that. To me it seems that some (or many?) people either
don't think about multithreading and continue to write code in the style of
70s or have hard time understanding the entire concept and its implications
w/o connection to a particular OS.
Alex
| |
| David Schwartz 2006-02-13, 7:49 am |
|
"Nick Roberts" <nick.roberts@acm.org> wrote in message
news:84THf.302094$D47.23800@fe3.news.blueyonder.co.uk...
> For a long time (several years, I recall), people were trying to do window
> operations using a multi-threaded program and wondering why it didn't
> work. Eventually, Microsoft came clean, and admitted that only the thread
> that created the window could subsequently manipulate that window (in
> particular, only that thread can receive messages from the window).
I don't remember this ever being a secret. It was always clear that each
thread had its own event queue. There were even functions to send messages
to a particular thread's queue. It's not that only that thread can receive
messages from the window, it's that windows messages are routed to that
thread's queue.
> For this reason (together with the fact that Unix doesn't support
> threading at all), most Windows programs remain single-threaded;
> programmers acquired the impression that multi-threading under Windows was
> such a black art it wasn't worth the effort.
I totally disagree. The vast majority of Windows programs these days are
multi-threaded, and in many ways the WIN32 API makes this much easier to do
than the UNIX API does. Although, of course, it does have its problems.
You are correct, however, about terrible Microsoft documentation.
Pthreads has its issues too, but Microsoft has forced developers to guess an
awful lot more than they should have.
DS
| |
| David Schwartz 2006-02-13, 7:49 am |
|
"Alexei A. Frounze" <alexfru@chat.ru> wrote in message
news:45avjbF5pnlhU1@individual.net...
[vbcol=seagreen]
> I'm not sure about that. To me it seems that some (or many?) people either
> don't think about multithreading and continue to write code in the style
> of 70s or have hard time understanding the entire concept and its
> implications w/o connection to a particular OS.
A lot of Windows software sucks because programmers are unwilling to
learn how to correctly program to the modern WIN32 API. The biggest problem
is people who do things the UNIX way with the minimal changes needed to get
it to seem to work on Windows. The second-biggest problem is people who
still do horrible things you had to do back on Windows 3.1 thinking that you
still have to.
Today, the WIN32 API is suprisingly clean and surprisingly friends to
threading. A lot of things you have to go out of your way to get even close
to right on pthreads are trivial to do on Windows. (Not that it doesn't have
its own problems, of course.)
Perhaps as more programmers start to write multi-threaded programs on
UNIXes (since it is now very stable on most UNIXes people still care about),
WIN32 will benefit. If nothing else, multi-core CPUs should force people to
multi-thread because you have to if you want to get what the hardware is
capable of.
DS
| |
| Chris Thompson 2006-02-13, 6:04 pm |
| In article <dsl62m$1hvr$1@gavrilo.mtu.ru>,
Maxim S. Shatskih <maxim@storagecraft.com> wrote:
>
>I'm against the whole word of ''reentrant". It is, in fact, something from the
>old time of MS-DOS add-ons which tried to do multitasking from this pathetic
>OS.
MS-DOS? That's practically yesterday! We were talking about "reeentrant" and
"serially reusable" load modules back in OS/360, and it probably wasn't a
new term then.
--
Chris Thompson
Email: cet1 [at] cam.ac.uk
| |
| Nicholas Sherlock 2006-02-13, 6:04 pm |
| Maxim S. Shatskih wrote:
>
> I'm surprised by your answer. Can you _name the exact Win32 API routines by
> Microsoft_ which do not support multithreading?
There are a few, I think, but they're not what I'd call "Core APIs". The
ImageHlp library doesn't support multi-threading.
Cheers,
Nicholas Sherlock
| |
| James Harris 2006-02-14, 5:54 pm |
|
"Chris Thompson" <cet1@cus.cam.ac.uk> wrote in message
news:dsqct8$q1r$1@gemini.csx.cam.ac.uk...
> In article <dsl62m$1hvr$1@gavrilo.mtu.ru>,
> Maxim S. Shatskih <maxim@storagecraft.com> wrote:
>
> MS-DOS? That's practically yesterday! We were talking about
> "reeentrant" and
> "serially reusable" load modules back in OS/360, and it probably
> wasn't a
> new term then.
That's where I first came across the term. It was a long time ago. IIRC
it would apply to any module that did not modify part of itself.
| |
| Maxim S. Shatskih 2006-02-14, 9:06 pm |
| > There are a few, I think, but they're not what I'd call "Core APIs". The
> ImageHlp library doesn't support multi-threading.
Is it documented? Can I use apartment threading there - i.e. many threads, but
the entity is only used by the thread which created it?
--
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
maxim@storagecraft.com
http://www.storagecraft.com
| |
| Olumide 2006-02-14, 9:06 pm |
| Rather than start a new thread, I though it better to add a question
here since the thread has already gone a bit OT alteady ;-) (by the
way, thanks to everyone for the naswers).
Just a minor point: I was pondering on the nature of the "conversation"
(or should I say instructions) the driver has with the controller. Is
it correct to term these commands microcode?
Thanks,
- Olumide
| |
| Brian Inglis 2006-02-15, 7:57 am |
| On 14 Feb 2006 18:07:26 -0800 in comp.unix.internals, "Olumide"
<50295@web.de> wrote:
>Rather than start a new thread, I though it better to add a question
>here since the thread has already gone a bit OT alteady ;-) (by the
>way, thanks to everyone for the naswers).
>
>Just a minor point: I was pondering on the nature of the "conversation"
>(or should I say instructions) the driver has with the controller. Is
>it correct to term these commands microcode?
No, they would be device commands and responses.
Some organizations (IBM at least) consider any low level code below
the architectural interface (e.g. on an ethernet card or disk drive)
to be microcode, as opposed to the more widespread view of microcode
as hardwired code used to execute architectural instructions within a
CPU.
--
Thanks. Take care, Brian Inglis Calgary, Alberta, Canada
Brian.Inglis@CSi.com (Brian[dot]Inglis{at}SystematicSW[dot]ab[dot]ca)
fake address use address above to reply
| |
| Olumide 2006-02-17, 10:40 pm |
|
Brian Inglis wrote:
> No, they would be device commands and responses.
> Some organizations (IBM at least) consider any low level code below
> the architectural interface (e.g. on an ethernet card or disk drive)
> to be microcode, as opposed to the more widespread view of microcode
> as hardwired code used to execute architectural instructions within a
> CPU.
Thanks Brian. I'm now of the view that device driver commands to the
controller are not microcode -- at least in the case of memory-mapped
IO, since it by definition does not distinguish between controller
registers and memory locations.
| |
| Nick Roberts 2006-02-17, 10:40 pm |
| Maxim S. Shatskih wrote:
> I'm surprised by your answer. Can you _name the exact Win32 API routines by
> Microsoft_ which do not support multithreading?
Well, no I cannot, and I have to concede defeat as such :-)
> Stupid ancient UNIXen - do not. Good UNIXen - do, and have pthreads
> implementation mapped to real kernel threads (like modern Linux does).
I am not an expert on pthreads, but my impression is that this facility
is really rather limited. I have heard that you cannot use the semaphore
facility without running as root, and that you are limited to 32 semaphores.
> Depends on programmer skills in fact. I use threads in Windows in real-world
> projects since around 1996, and never had any issues with them, so are the
> people I was working with.
You really never had /any/ issues with them?
> Abusing threads (using a thread when there is
> no real need in it) - yes, this is a reality :-)
I'm interested in this point. When you say "using a thread when there is
no real need", do you mean something really daft (e.g. thread B cannot
start any of its work until thread A has completed all of its work) or
do you mean situations that might be considered 'overkill' (e.g. a video
game where every moving object has a thread, so requiring hundreds or
thousands of threads)?
I'm curious about this, because there are programming languages that
could be implemented in a way that tends to use lots of threads, even
when sometimes they are not really necessary. For example, a (modified)
Smalltalk implementation might implement every object as a thread, apart
from some optimisation for primitive operations.
While I have the attention of Windows expert, I'd also like to ask about
the Win32 memory model. I have always found it confusing as to which
parts of the map correspond to what, and how efficient memory management
should be achieved (at the machine code level, not C).
How should a full (generational) garbage collection scheme be
approached? Remember that full GC requires that blocks can be moved
around in memory at any time (to make a contiguous space for a new
allocation). It has to be thread-safe, and it has to be able to cope
with lots of small blocks mixed with a few large blocks. It must be 100%
non-leaking, and it must behave gracefully when memory limitations are
reached. Can this be done under Win32?
Sorry to go off topic here, but I'm eager to take the opportunity!
Thanks in advance.
--
Nick Roberts
| |
| Maxim S. Shatskih 2006-02-17, 10:40 pm |
| > do you mean situations that might be considered 'overkill' (e.g. a video
> game where every moving object has a thread, so requiring hundreds or
> thousands of threads)?
I mean overkill. For instance, using thread instead of the good old nonblocking
socket 
> While I have the attention of Windows expert, I'd also like to ask about
> the Win32 memory model.
Very similar to UNIX one. The kernel even supports fork(), which is used in
Microsoft Interix (UNIX emulation layer for Windows, rather rich).
> How should a full (generational) garbage collection scheme be
> approached?
This is .NET, and not Windows. The details of .NET garbage collector can be
found on msdn.microsoft.com - just google for "CLR garbage collector" or such.
> reached. Can this be done under Win32?
Yes it can. No my area of expertise though (it is .NET), but well-documented.
--
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
maxim@storagecraft.com
http://www.storagecraft.com
| |
| Andrew Gabriel 2006-02-17, 10:40 pm |
| In article <43F3B5B7.3080400@acm.org>,
Nick Roberts <nick.roberts@acm.org> writes:
>
> I am not an expert on pthreads, but my impression is that this facility
> is really rather limited. I have heard that you cannot use the semaphore
> facility without running as root, and that you are limited to 32 semaphores.
That might be a feature of some rather sad (and probably
not standards conforming) implementation, but it's certainly
not inherent in pthreads.
--
Andrew Gabriel
| |
|
| James Harris wrote:
> "Chris Thompson" <cet1@cus.cam.ac.uk> wrote in message
> news:dsqct8$q1r$1@gemini.csx.cam.ac.uk...
>
> That's where I first came across the term. It was a long time ago. IIRC
> it would apply to any module that did not modify part of itself.
Before stacks became commonplace, architectural subroutine linkage
conventions (typically of the 'self-modifying' type, such as storing
the link address in a fixed location[1]) often precluded re-entrancy
and recursion except through explicit emulation of a stack.
[1] e.g. http://www.cs.clemson.edu/~mark/subroutines/pdp8.html
| |
|
| James Harris wrote:
> "Chris Thompson" <cet1@cus.cam.ac.uk> wrote in message
> news:dsqct8$q1r$1@gemini.csx.cam.ac.uk...
>
> That's where I first came across the term. It was a long time ago. IIRC
> it would apply to any module that did not modify part of itself.
Before stacks became an architectural commonplace, subroutine linkage
conventions (typically of the 'self-modifying' type, such as storing
the link address in a fixed location[1]) often precluded re-entrancy
and recursion by default.
As other posters point out, a stack answers both problems by providing
storage for state and return link that is local to any activation.
[1] e.g. http://www.cs.clemson.edu/~mark/subroutines/pdp8.html
| |
|
| James Harris wrote:
> "Chris Thompson" <cet1@cus.cam.ac.uk> wrote in message
> news:dsqct8$q1r$1@gemini.csx.cam.ac.uk...
>
> That's where I first came across the term. It was a long time ago. IIRC
> it would apply to any module that did not modify part of itself.
Before stacks became an architectural commonplace, subroutine linkage
conventions (typically of the 'self-modifying' type, such as storing
the link address in a fixed location[1]) often precluded re-entrancy
and recursion by default.
As other posters point out, a stack answers both problems by providing
storage for state and return link that is local to any activation.
[1] e.g. http://www.cs.clemson.edu/~mark/subroutines/pdp8.html
|
|
|
|
|