Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class FreeQueue
- {
- const static int BUFFERS = 2;
- const static int SIZE = 128;
- FixedVector<void*,SIZE> ptrs[BUFFERS];
- int currentQueue;
- Atomic ownedByJob[BUFFERS];
- public:
- FreeQueue() : currentQueue() {}
- void Push(void* ptr)
- {
- while(1)
- {
- if( currentQueue==-1 ) // worst case, all buffers are full and jobs haven't completed yet
- {
- ThreadPool::WaitUntil( IsFalse(ownedByJob, BUFFERS) ); // go idle and/or run available jobs
- for( int i=0; i!=BUFFERS && currentQueue==-1; ++i )
- if( ownedByJob[i] == 0 )
- currentQueue = i;
- }
- assert( currentQueue!=-1 );
- if( ptrs[currentQueue]->Push(ptr) )
- return;//actualy pushed the ptr into a buffer
- else//failed to push, this buffer is full
- {
- //mark this buffer as being owned by a job, kick of the async call to actually free the pointers in that buffer
- ownedByJob[currentQueue] = 1;
- ThreadPool::PushJob( ActuallyCallFree(ptrs[currentQueue], ownedByJob[currentQueue]) );
- // ActuallyCallFree does: foreach ptr in arg0: _real_free_(ptr); arg0.clear(); arg1 = 0;
- currentQueue = (currentQueue+1) % BUFFERS;//try to move to the next buffer
- if( ownedByJob[currentQueue] )// next buffer is still waiting for it's job to complete, try find another one
- {
- currentQueue = -1;
- for( int i=0; i!=BUFFERS && currentQueue==-1; ++i )
- if( ownedByJob[i] == 0 )
- currentQueue = i;
- }
- }
- }
- }
- };
- static ThreadLocal<FreeQueue> g_toFree;
- void free(void* p)
- {
- g_toFree->push(p);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement