PDA

View Full Version : Thread safe FIFO



Ron
October 13th, 2002, 12:55 PM
Mark, first of all get well soon!!!

Secondly thanks for the ideas, I've been watching "tomorrow never dies" and because this is such a trilling ( yeah right ) movie my mind wandered over this problem. I think I have a nice way of keeping compatibility and making a good queue. This is my idea:

I'll keep the current shared memory, this is protected by the semaphore as it is now.

The plugin sends the event to a completely separate window running in a completely separate thread that ONLY processes these events, thus processing should be very quick.

This event collection thread immediately copies the shared memory into a circular buffer ( some depth like 10 or 20 events should be plenty ) and releases the Semaphore ( Currently Girder locks the semaphore if there is an event running already,.. BAAAAAD, so a third incoming event will fail ),

Now the collection thread is ready for the next event.

This will only take a few microseconds,... if it proves insufficient I can always extend it and export some function that directly adds an event to the queue instead of using the windows message passing. Really blazing fast.

If the executing thread is waiting for a new event the collection thread will set an event to wake up the execution thread. The execution thread will also remove old events from the circular buffer.

Of course the circular buffer is protected by a mutex.

This will be the first thing I'll start to work on tomorrow morning.

Does anyone see any fundamental problems with this approach ? If so speak up now or forever hold your peace! :evil:

Note: this will also solve some problems with the antirepeat not working 100% (Dave)

Ron
October 13th, 2002, 12:55 PM
No worries Mark, both the handles will be the same, although a different window from what it was now.

About the UI thread,... I think they already spawn their own thread, if not they would block the current Girder as well.

I'm trying to keep compatibility and it looks as it will work. I'm currently completely separating the UI from the Core. The last step proved to be a bigger one then I anticipated. ( lots of threading problems, the VCL is not thread safe ) You know what that means .... 'betas' again,.. progress sometimes means taking a step back.

Ron
October 13th, 2002, 12:55 PM
Maybe you'll have to modify your plugins just a little, I've noticed that you sometimes use the Girder window as the parent for the MFC windows. This is fine, however I have a habit of changing the title of the window :-),.. maybe you could switch to the "GirderEventSink" window in the next release, this window is not version dependent and is always there, the main girder window will eventually be completely closeable. ( So we can finally run girder as a service )

Mark F
October 13th, 2002, 12:55 PM
I'm tired and sick (physically ill) and need to go home. This post will come across as preachy or arrogant or something bad, I'm sure. I'm not the world's only programmer and everyone has their own way of doing these things. Sorry, in advance, if this offends or misleads someone. :(

First, I'm not sure how you will be able to maintain compatibility with old plugins if you implement a queue of events rather than the single shared memory element you use now.

I'm going to talk about structures but you can substitute Objects or whatever you want from the programmers jargon handbook. ;)

To accomplish this under Windows means you need to think about a couple of things.

The FIFO data structures must be in memory that any thread can touch without an exception. This will allow you to expose an interface that lets the hardware plugin threads add elements without requiring a thread context switch.
The FIFO data structures must be protected by a mutex. This means there is a handle involved. As long as we limit this to not cross process boundaries, you SHOULD be able to get a handle that all threads can use.

The structure, itself, needs to keep track of the first and last element in the FIFO and possibly the current size of the FIFO. The implementation can be a linked list or array or whatever you think is most efficient.

There are really only two public interfaces (methods) for this structure: Enqueue (put something at the end of the queue) and Dequeue (remove something from the front of the queue)

Internally, you may need: Empty (returns TRUE if the structure represents an empty FIFO) and, if the implementation has a memory limit, Full (returns TRUE if the structure represents a full FIFO)

I implemented a thread safe FIFO in the UserEvent plugin by utilizing an existing MFC class and a mutex. See the TSF.c and TSF.h files in the source package.

I need some sleep. :)

Mark F
October 13th, 2002, 12:55 PM
Aaaah. What a night of sleep will do! I feel 100% better. :D

I don't see any fundemental problems with your solution. As a matter of fact, I like it a lot!

I do have two concerns with your solution. Both are for plugins *I* have written and both are caused by assumptions on my part. :(

Up until now, the windows handle passed to both sides of an extended plugin has been the same. Now it will be different. My assumption was these handles would always be the same.

First concern, I have kept only one global handle variable in my extended plugins. Right now, I'll have to see which handle I keep, HW or Action. I'll need to change the code to keep both.

I use the thread of the passed in windows handle for my dialog box's messages.

Second concern, my HW only plugins will need to spawn their own UI thread so the event thread remains responsive.

Neither of these is a show stopper, by itself (I'll fix my plugins); however, I have published the source for these plugins and am afraid that any derivative works will be affected the same way.