So, I have been looking through the source code recently trying to understand the Asset system implemented and found this small issue in LoadBitmap code when passing Immediate = false
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 | internal void
LoadBitmap(game_assets *Assets, bitmap_id ID, b32 Immediate)
{
TIMED_FUNCTION();
asset *Asset = Assets->Assets + ID.Value;
if(ID.Value)
{
if(AtomicCompareExchangeUInt32((uint32 *)&Asset->State, AssetState_Queued, AssetState_Unloaded) ==
AssetState_Unloaded)
{
task_with_memory *Task = 0;
if(!Immediate)
{
Task = BeginTaskWithMemory(Assets->TranState, false);
}
if(Immediate || Task)
{
//... do stuff
}
else
{
Asset->State = AssetState_Unloaded;
}
}
else if(Immediate)
{
// TODO(casey): Do we want to have a more coherent story here
// for what happens when two force-load people hit the load
// at the same time?
asset_state volatile *State = (asset_state volatile *)&Asset->State;
while(*State == AssetState_Queued) {}
}
}
}
|
When AtomicCompareExchangeUInt32 is executed and if Asset->State is indeed equals to AssetState_Unloaded it will change to AssetState_Queued, Aftherwards it will request a Task, but if there are not Tasks available the Work is not going to be added to the queue and thus the bitmap is not going to be loaded. The thing is, the next time the same bitmap_id is pushed, it will try to load it, as it hasnt been loaded yet, but AtomicCompareExchangeUInt32 will fail as the current state of the Asset is going to be AssetState_Queued instead of AssetState_Unloaded making that particular Asset that couldnt find an available Task, to never load
Maybe I am wrong, so please correct me if so.