Re: Explain this about threads
- From: "Willy Denoyette [MVP]" <willy.denoyette@xxxxxxxxxx>
- Date: Sun, 23 Sep 2007 08:48:13 +0200
"Jon Slaughter" <Jon_Slaughter@xxxxxxxxxxx> wrote in message news:N2hJi.39$ih1.31@xxxxxxxxxxxxxxxxxxxxxxx
"Willy Denoyette [MVP]" <willy.denoyette@xxxxxxxxxx> wrote in message news:OLyId6V$HHA.5164@xxxxxxxxxxxxxxxxxxxxxxx"Jon Slaughter" <Jon_Slaughter@xxxxxxxxxxx> wrote in message news:IneJi.8420$JD.6894@xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
"Willy Denoyette [MVP]" <willy.denoyette@xxxxxxxxxx> wrote in message news:%23NKD4tU$HHA.4880@xxxxxxxxxxxxxxxxxxxxxxx"Jon Slaughter" <Jon_Slaughter@xxxxxxxxxxx> wrote in message news:av3Ji.8375$JD.7852@xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"Instead of just waiting for its time slice to expire, a thread can block each time it initiates a time-consuming activity in another thread until the activity finishes. This is better than spinning in a polling loop waiting for completion because it allows other threads to run sooner than they would if the system had to rely solely on expiration of a time slice to turn its attention to some other thread."
I don't get the "a thread can block each time...". What does it mean by blocking? Does it mean that if thread B needs something from thread A that thread A stops thread B from running until its finished but not interfer with some other thread C?
Thanks,
Jon
Adding to what others have said in this thread:
1) You should never SpinWait on a single processor machine, doing so prevents other threads in the system to make progress( unless this is exactly what you are looking for).
Waiting for an event (whatever) from another thread in a SpinWait loop, prevents the other thread to signal the event, so basically you are wasting CPU cycles for nothing.
2) Define the count as such that you spin for less than the time needed to perform a transition to the kernel and back, when waiting for an event. Spinning for a longer period is just a waste of CPU cycles, you better give up your quantum by calling Sleep(1) or PInvoke the Kernel32 "SwitchToThread" API in that case.
Ok, Tell me then how I can do clocked IO in a timely fashion without using without spining?
Lets suppose I have do slow down the rate because it simply to fast for whatever device I'm communicating with if I do not insert delays.
I would be really interested in knowing how I can do this without using spinwaits because it is a problem that I'm having. It seems like its a necessary evil in my case.
Basically I'm trying to do synchronous communication with the parallel port. I have the ability to use in and out which is supplied by a kernel mode driver and dll wrapper. So if I want to output some data to the port I can do "out(data)" and it will output it
if I have something like
for(int i = 0; i < data.Length; i++)
out(data[i]);
Then this will run about 100khz or so(on my machine). Now what if I need to slow it down to 20khz? How can I do this without using spin waits but still do it in a timely fashion? IGNORE ANY DELAYS FROM TASK SWITCHING! I cannot control the delays that other processes and task switching introduce so since its beyond my control I have to ignore it. Whats important is the upper bound that I can get and the average and not the lower bound. So when I say it needs to run at 20khz it means as an upper bound.
for(int i = 0; i < data.Length; i++)
{
out(data[i]);
Thread.SpinWait(X);
}
Where X is something that slows this down enough to run at 20khz. I can figure out X on average by doing some profiling. i.e., if I know how long out takes and how long Thread.SpinWait(1) takes(on average) then I can get an approximate value for X.
But how can I do this without using spin waits?
The data transfer rate on a parallel port is a matter of handshake protocol between the port and the device, basically it's the device who decides the (maximum) rate. The exact transfer rates are defined in the IEE1284 protocol standards (IEE1284.1, 2, 3 , 4..) and the modes (like Compatible, Nibble, Byte and ECP mode) supported by the parallel port peripheral controller chips. All these kind of protocols (par. port , serial ports networks, USB, other peripheral protocols) are exactly invented to be able to control the signaling rates between the system and the device, the PC hardware and the Windows OS is simply not designed for this, they are not real-time capable.
No, this is only for ECP and EPP. There is no handshaking and hardware protocol in SPP which is what I'm using. It is also necessary for me to use SPP because the device that is attached does not use the same protocol that EPP/ECP uses.
Now, if you don't have a device connected that negotiates or respects one of the IEE1284 protocol modes, you have a problem. You can't accurately time the IO transfer rate, all you can do is insert waits in your code user mode or in a driver driver) and as such define a top level rate but no lower rate!
The easiest way (but still a dirty way to do) is by inserting delays like you do in your code, this is not a problem for small bursts (say a few 100 bytes) on a single processor box, and a few KB on multi-cores, assuming that you don't further peg the CPU between each burst, so that other threads don't starve.
Well, thats what I'm doing but I'm trying to find the optimal method. This is also the method that most programs that do similar things I'm trying to do use.
I think I'm going to write a simple kernel mode driver that does all the communications using direct port access(instead of the IOCTRL methodolgy). Its more of a hack but is probably fast as I can get it. Of course that method will cause problems with other drivers and stuff but I don't have to worry about that.
I can also use the interrupt to get information on a regular basis but not sure how well this will work.
I was thinking that maybe I could use an interrupt and then an external clock that will trigger the interrupt very precisely and that would probably give me a pretty accurate method but it would probably starve the system because of all the task switching per clock. I guess I have no choice but to either use something like dos or some hardware proxy that can deal with the latency issues.
SPP uses the status lines (Ack, Busy ... signals) to control the data flow between device and controller, the driver has to read the status of the Ack signal after each byte transferred in order to control the signaling rate.
Writing your own driver won't help you any further as long as you don't use the handshaking protocol as defined in 1284 at the device driver level. Sure you can move the SpinWait loop at the driver level, but this is no different as doing this at the user level, you are burning CPU cycles without any more guarantees that you wont loosing bytes because the device is not ready to accept any more data. I would keep these things in user space anyway, it's simply a matter of trying to find the optimal value for the spin counter.
Willy.
.
- Follow-Ups:
- Re: Explain this about threads
- From: Jon Slaughter
- Re: Explain this about threads
- References:
- Explain this about threads
- From: Jon Slaughter
- Re: Explain this about threads
- From: Willy Denoyette [MVP]
- Re: Explain this about threads
- From: Jon Slaughter
- Re: Explain this about threads
- From: Willy Denoyette [MVP]
- Re: Explain this about threads
- From: Jon Slaughter
- Explain this about threads
- Prev by Date: Re: Out of memory when loading an image file
- Next by Date: Re: Out of memory when loading an image file
- Previous by thread: Re: Explain this about threads
- Next by thread: Re: Explain this about threads
- Index(es):
Relevant Pages
|
Loading