1
0

ThreadLoop.cpp 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. #include "ThreadLoop.h"
  2. lifo_t ThreadLoop::procedure_cache = {0,};
  3. lifo_t ThreadLoop::cache_bases= {0,};
  4. #define PROCEDURE_CACHE_SEED 64
  5. ThreadLoop::ThreadLoop()
  6. {
  7. mpscq_init(&procedure_queue);
  8. procedure_notification = CreateSemaphore(0, 0, LONG_MAX, 0);
  9. kill_switch = CreateEvent(0, TRUE, FALSE, 0);
  10. }
  11. void ThreadLoop::RefillCache()
  12. {
  13. threadloop_node_t *cache_seed = (threadloop_node_t *)lifo_malloc(PROCEDURE_CACHE_SEED*sizeof(threadloop_node_t));
  14. if (cache_seed)
  15. {
  16. memset(cache_seed, 0, PROCEDURE_CACHE_SEED*sizeof(threadloop_node_t));
  17. for (int i=0;i<PROCEDURE_CACHE_SEED;i++)
  18. {
  19. lifo_push(&procedure_cache, &cache_seed[i]);
  20. }
  21. lifo_push(&cache_bases, cache_seed);
  22. }
  23. }
  24. void ThreadLoop::Run()
  25. {
  26. HANDLE events[] = {kill_switch, procedure_notification};
  27. while (WaitForMultipleObjects(2, events, FALSE, INFINITE) == WAIT_OBJECT_0 + 1)
  28. {
  29. threadloop_node_t *apc;
  30. for (;;)
  31. {
  32. apc = (threadloop_node_t *)mpscq_pop(&procedure_queue);
  33. if (!apc)
  34. {
  35. Sleep(0);
  36. continue;
  37. }
  38. apc->func(apc->param1, apc->param2, apc->real_value);
  39. }
  40. lifo_push(&procedure_cache, apc);
  41. }
  42. }
  43. threadloop_node_t *ThreadLoop::GetAPC()
  44. {
  45. threadloop_node_t *apc = 0;
  46. do
  47. {
  48. apc = (threadloop_node_t *)lifo_pop(&procedure_cache);
  49. if (!apc)
  50. RefillCache();
  51. } while (!apc);
  52. return apc;
  53. }
  54. void ThreadLoop::Schedule(threadloop_node_t *apc)
  55. {
  56. mpscq_push(&procedure_queue, apc);
  57. ReleaseSemaphore(procedure_notification, 1, 0);
  58. }
  59. void ThreadLoop::Kill()
  60. {
  61. SetEvent(kill_switch);
  62. }