John M McIntosh said:
> Likely I should point out this code is not 100% percent thread safe. > > People doing thousands of signal events per second from an async > thread should think carefully about the code. I'm really interested in this problem, as SqueakNOS relies 100% on signalSemaphoreWithIndex() to handle IRQs properly (see http://minnow.cc.gatech.edu/squeak/1762 for more detailed info). However, after reading Andreas' comment in Win32 sources I think this problem is only present when the underlying native code is multithreaded, what doesn't apply to SqueakNOS... however, what I think will present a similar situation is if two IRQs (different or not) arrive in a very short period of time, both of them signaling Semaphores (same for same IRQs, different for different IRQs). What do you think? Where can I read an explanation of this problem to see if it applies and if we can somehow solve it? I guess we'll need to implement some type of locking mechanism, even when the underlying code is single threaded. thanks a lot gera |
Well having written these two routines 6 or 7 years ago, let me
comment if I can remember. The two routines of interest are: signalSemaphoreWithIndex: index "Record the given semaphore index in the double buffer semaphores array to be signaled at the next convenient moment. Force a real interrupt check as soon as possible." index <= 0 ifTrue: [^ nil]. "bad index; ignore it" semaphoresUseBufferA ifTrue: [semaphoresToSignalCountA < SemaphoresToSignalSize ifTrue: [ semaphoresToSignalCountA := semaphoresToSignalCountA + 1. semaphoresToSignalA at: semaphoresToSignalCountA put: index]] ifFalse: [semaphoresToSignalCountB < SemaphoresToSignalSize ifTrue: [ semaphoresToSignalCountB := semaphoresToSignalCountB + 1. semaphoresToSignalB at: semaphoresToSignalCountB put: index]]. self forceInterruptCheck and the one below which is called from checkForInterrupts and happens every 1-2 milliseconds or as soon as possible via being triggered by the forceInterruptCheck call. Thus on a signalSemaphoreWithIndex: we should call signalExternalSemaphores fairly soon, that 'nots' the semaphoresUseBufferA which flips the buffers to allow the checkForInterrupts logic to process the semaphores in buffer 'A' as an interrupt driven processes fill buffer 'B'. Of course if you don't have any process threads calling signalSemaphoreWithIndex: we don't have a problem because normally this code is only processed by the single squeak thread. The risks is on dual processor machines such that decisions based on semaphoresUseBufferA collide between the main squeak thread running signalExternalSemaphores, and an other thread pounding on signalSemaphoreWithIndex: and we miss a semaphoresToSignalCountX increment. signalExternalSemaphores "Signal all requested semaphores" | xArray xSize index sema | semaphoresUseBufferA := semaphoresUseBufferA not. xArray := self splObj: ExternalObjectsArray. xSize := self stSizeOf: xArray. semaphoresUseBufferA ifTrue: ["use opposite buffer during read" 1 to: semaphoresToSignalCountB do: [:i | index := semaphoresToSignalB at: i. index <= xSize ifTrue: [sema := self fetchPointer: index - 1 ofObject: xArray. "Note: semaphore indices are 1-based" (self fetchClassOf: sema) = (self splObj: ClassSemaphore) ifTrue: [self synchronousSignal: sema]]]. semaphoresToSignalCountB := 0] ifFalse: [1 to: semaphoresToSignalCountA do: [:i | index := semaphoresToSignalA at: i. index <= xSize ifTrue: [sema := self fetchPointer: index - 1 ofObject: xArray. "Note: semaphore indices are 1-based" (self fetchClassOf: sema) = (self splObj: ClassSemaphore) ifTrue: [self synchronousSignal: sema]]]. semaphoresToSignalCountA := 0] On 9-Jun-06, at 7:29 PM, Gerardo Richarte wrote: > John M McIntosh said: >> Likely I should point out this code is not 100% percent thread safe. >> >> People doing thousands of signal events per second from an async >> thread should think carefully about the code. > I'm really interested in this problem, as SqueakNOS relies 100% on > signalSemaphoreWithIndex() to handle IRQs properly (see http:// > minnow.cc.gatech.edu/squeak/1762 for more detailed info). > However, after reading Andreas' comment in Win32 sources I think > this problem is only present when the underlying native code is > multithreaded, what doesn't apply to SqueakNOS... however, what I > think will present a similar situation is if two IRQs (different or > not) arrive in a very short period of time, both of them signaling > Semaphores (same for same IRQs, different for different IRQs). > What do you think? > > Where can I read an explanation of this problem to see if it > applies and if we can somehow solve it? I guess we'll need to > implement some type of locking mechanism, even when the underlying > code is single threaded. > > thanks a lot > gera > > -- ======================================================================== === John M. McIntosh <[hidden email]> 1-800-477-2659 Corporate Smalltalk Consulting Ltd. http://www.smalltalkconsulting.com ======================================================================== === |
Free forum by Nabble | Edit this page |