71 lines
1.5 KiB
C++
71 lines
1.5 KiB
C++
|
#include "ThreadLoop.h"
|
||
|
|
||
|
lifo_t ThreadLoop::procedure_cache = {0,};
|
||
|
lifo_t ThreadLoop::cache_bases= {0,};
|
||
|
|
||
|
#define PROCEDURE_CACHE_SEED 64
|
||
|
ThreadLoop::ThreadLoop()
|
||
|
{
|
||
|
mpscq_init(&procedure_queue);
|
||
|
procedure_notification = CreateSemaphore(0, 0, LONG_MAX, 0);
|
||
|
kill_switch = CreateEvent(0, TRUE, FALSE, 0);
|
||
|
}
|
||
|
|
||
|
void ThreadLoop::RefillCache()
|
||
|
{
|
||
|
threadloop_node_t *cache_seed = (threadloop_node_t *)lifo_malloc(PROCEDURE_CACHE_SEED*sizeof(threadloop_node_t));
|
||
|
if (cache_seed)
|
||
|
{
|
||
|
memset(cache_seed, 0, PROCEDURE_CACHE_SEED*sizeof(threadloop_node_t));
|
||
|
for (int i=0;i<PROCEDURE_CACHE_SEED;i++)
|
||
|
{
|
||
|
lifo_push(&procedure_cache, &cache_seed[i]);
|
||
|
}
|
||
|
lifo_push(&cache_bases, cache_seed);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ThreadLoop::Run()
|
||
|
{
|
||
|
HANDLE events[] = {kill_switch, procedure_notification};
|
||
|
while (WaitForMultipleObjects(2, events, FALSE, INFINITE) == WAIT_OBJECT_0 + 1)
|
||
|
{
|
||
|
threadloop_node_t *apc;
|
||
|
for (;;)
|
||
|
{
|
||
|
apc = (threadloop_node_t *)mpscq_pop(&procedure_queue);
|
||
|
if (!apc)
|
||
|
{
|
||
|
Sleep(0);
|
||
|
continue;
|
||
|
}
|
||
|
apc->func(apc->param1, apc->param2, apc->real_value);
|
||
|
}
|
||
|
lifo_push(&procedure_cache, apc);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
threadloop_node_t *ThreadLoop::GetAPC()
|
||
|
{
|
||
|
threadloop_node_t *apc = 0;
|
||
|
|
||
|
do
|
||
|
{
|
||
|
apc = (threadloop_node_t *)lifo_pop(&procedure_cache);
|
||
|
if (!apc)
|
||
|
RefillCache();
|
||
|
} while (!apc);
|
||
|
return apc;
|
||
|
}
|
||
|
|
||
|
void ThreadLoop::Schedule(threadloop_node_t *apc)
|
||
|
{
|
||
|
mpscq_push(&procedure_queue, apc);
|
||
|
ReleaseSemaphore(procedure_notification, 1, 0);
|
||
|
}
|
||
|
|
||
|
void ThreadLoop::Kill()
|
||
|
{
|
||
|
SetEvent(kill_switch);
|
||
|
}
|