Hi all,
Just finished watching episode 124 of handmade hero.
Casey shows what use can we make of InterlockedIncrement to Synchronize threads.
The mechanism of InterlockedIncrement per se is clear enough to me, what makes me think is this piece of code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 | global_variable nextEntryIndex;
global_variable countEntries;
DWORD WINAPI ThreadProc( LPVOID lpParameter )
{
Win32ThreadInfo* myInfo = ( Win32ThreadInfo* ) lpParameter;
for(;;)
{
if( nextEntryIndex < countEntries )
{
uint32 entryIndex =InterlockedIncrement( ( LONG volatile* ) &nextEntryIndex ) - 1;
DOStuff();
}
}
}
|
Let's say nextEntryIndex is 0, while countEntries is 1.
Thread 0 surpasses the if, but then, before making the InterlockedIncrement, is blocked and now it's thread 1 time.
Of course, thread 1 it's also going to pass the if, and so at this point everything is gone.
I mean, it's a really remote possibility that thread 0 gets interrupted EXACTLY after the if but between the InterlockedIncrement, but it could happen right?
Considering this remote case, my solution has been:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 | DWORD WINAPI ThreadProc( LPVOID lpParameter )
{
Win32ThreadInfo* myInfo = ( Win32ThreadInfo* ) lpParameter;
for(;;)
{
if( nextEntryIndex < countEntries )
{
uint32 oldEntryIndex = nextEntryIndex;
uint32 nextIndex =InterlockedIncrement( ( LONG volatile* ) &nextEntryIndex );
if( nextIndex > oldEntryIndex )
{
DOStuff();
}
}
}
}
|
This way, even in that remote case, the second if will fail because InterlockedIncrement will return the old value.
Again, probably just me misunderstanding something, in fact I opened this post just to clarify this thing.
Thank you.
Leonardo