Re: MT Design Question
"Chris M. Thomasson" <cristom@charter.net> wrote in message
news:6oweo.76824$1F6.66279@newsfe01.iad...
"Joshua Maurice" <joshuamaurice@gmail.com> wrote in message
[...]
Could you write up a simple example of multiple producers and multiple
consumers without conditions variables?
Here is a simple multi-producer/consumer queue using a single manual reset
event for waiters:
[...]
Don't forget, Windows has kernel semaphore objects. We can use the
interlocked API and a single kernel semaphore to build a "fast-pathed"
semaphore:
<pseudo-code sketch>
______________________________________________________________
struct fsem
{
LONG m_count; // = 0
HANDLE m_waitset; // = Windows semaphore; value of zero
void post()
{
if (InterlockedIncrement(&m_count) < 1)
{
ReleaseSemaphore(m_waitset, 1, NULL);
}
}
void wait()
{
if (InterlockedDecrement(&m_count) < 0)
{
WaitForSingleObject(m_waitset, INFINITE);
}
}
};
______________________________________________________________
Now we can build the simple queue using the synchronization primitive above:
<pseudo-code sketch>
______________________________________________________________
struct node
{
node* m_next;
};
struct queue
{
node* m_head; // = NULL;
node* m_tail;
fsem m_waitset;
CRITICAL_SECTION m_lock;
void push(node* n)
{
n->m_next = NULL;
EnterCriticalSection(&m_lock);
if (! m_head)
{
m_head = n;
}
else
{
m_tail->m_next = n;
}
m_tail = n;
LeaveCriticalSection(&m_lock);
m_waitset.post();
}
node* pop()
{
m_waitset.wait();
EnterCriticalSection(&m_lock);
node* n = m_head;
assert(n);
m_head = n->m_next;
LeaveCriticalSection(&m_lock);
return n;
}
};
______________________________________________________________
IMHO, the Windows synchronization primitives are fairly flexible indeed. The
standardized interlocked API is _very_ nice as well.
IMVHO, one of the coolest features Windows provides is the ability to issue
a process-wide memory barrier. That is it makes every CPU in the processes
affinity mask execute a memory barrier by broadcasting an IPI:
http://msdn.microsoft.com/en-us/library/ms683148(VS.85).aspx
To damn bad it's only for Vista and higher.