12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970 |
- #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);
- }
|