Hi, So I've been following along with the series and Casey introduced the concept of a work queue and the fact that a thread could try to pull info off of it before it was actually filled out.
The way he proposed to solve that was using a write barrier like so
internal void PushString(char *String) { Assert(EntryCount < ArrayCount(Entries)); // TODO(casey): These writes are not in order! work_queue_entry *Entry = Entries + EntryCount; Entry->StringToPrint = String; CompletePastWritesBeforeFutureWrites EntryCount++; }
Even after this modification I still have the issue occur like so
Thread 4: String 0
Thread 3:
Thread 1: String 3
Thread 2: String 2
Thread 4: String 6
Thread 3: String 8
Thread 4: String 9
Thread 1: String 7
Thread 6: String 1
Thread 0:
Why is this still happening? Shouldn't the write barrier make this impossible? I am assuming this is exactly the issue where the thread prints out the string before it is actually filled out, but maybe something else is going on? To be clear I tried this at first with my own code and also with Casey's exact code from those days and I still have the issue. Why do I have this issue with the exact same code when he didn't?
After looking at it for a while I was wondering if the problem was coming from this part of the code
DWORD WINAPI ThreadProc(LPVOID lpParameter) { win32_thread_info *ThreadInfo = (win32_thread_info *)lpParameter; for(;;) { if(NextEntryToDo < EntryCount) { // TODO(casey): This line is not interlocked, so two threads could see the same value. // TODO(casey): Compiler doesn't know that multiple threads could write this value! int EntryIndex = InterlockedIncrement((LONG volatile*)&NextEntryToDo) - 1; CompletePastReadsBeforeFutureReads //int EntryIndex = NextEntryToDo++; // TODO(casey): These reads are not in order! work_queue_entry *Entry = Entries + EntryIndex; char Buffer[256]; wsprintf(Buffer, "Thread %u: %s\n", ThreadInfo->LogicalThreadIndex, Entry->StringToPrint); OutputDebugStringA(Buffer); } } // return(0); }
Can two threads see NextEntryToDo < EnrtyCount and enter here? I know we have an InterlockedIncrement on NextEntryToDo, but does that prevent more than one thread from entering the if block?
Also just to note, I couldn't format the code proper so I am sorry if it is hard to read I don't know how to make it proper on here.