Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

150 lignes
3.3 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net>
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the Do What The Fuck You Want To
  7. // Public License, Version 2, as published by Sam Hocevar. See
  8. // http://www.wtfpl.net/ for more details.
  9. //
  10. //
  11. // The ThreadBase class
  12. // --------------------
  13. //
  14. #if !defined __LOL_THREADBASE_H__
  15. #define __LOL_THREADBASE_H__
  16. #include <sys/ppu_thread.h>
  17. #include <sys/event.h>
  18. namespace lol
  19. {
  20. class MutexBase
  21. {
  22. public:
  23. MutexBase()
  24. {
  25. sys_lwmutex_attribute_t attr;
  26. sys_lwmutex_attribute_initialize(attr);
  27. sys_lwmutex_create(&m_mutex, &attr);
  28. }
  29. ~MutexBase()
  30. {
  31. while (sys_lwmutex_destroy(&m_mutex) == EBUSY)
  32. ;
  33. }
  34. void Lock()
  35. {
  36. sys_lwmutex_lock(&m_mutex, 0);
  37. }
  38. void Unlock()
  39. {
  40. sys_lwmutex_unlock(&m_mutex);
  41. }
  42. private:
  43. sys_lwmutex_t m_mutex;
  44. };
  45. template<typename T, int N> class QueueBase
  46. {
  47. public:
  48. QueueBase()
  49. {
  50. m_start = m_count = 0;
  51. m_poppers = m_pushers = 0;
  52. sys_lwmutex_attribute_t mattr;
  53. sys_lwmutex_attribute_initialize(mattr);
  54. sys_lwmutex_create(&m_mutex, &mattr);
  55. sys_lwcond_attribute_t cattr;
  56. sys_lwcond_attribute_initialize(cattr);
  57. sys_lwcond_create(&m_empty_cond, &m_mutex, &cattr);
  58. sys_lwcond_create(&m_full_cond, &m_mutex, &cattr);
  59. }
  60. ~QueueBase()
  61. {
  62. while (sys_lwcond_destroy(&m_empty_cond) == EBUSY)
  63. ;
  64. while (sys_lwcond_destroy(&m_full_cond) == EBUSY)
  65. ;
  66. while (sys_lwmutex_destroy(&m_mutex) == EBUSY)
  67. ;
  68. }
  69. void Push(T value)
  70. {
  71. /* FIXME: this is a copy of the pthread implementation, but we
  72. * should really use libsync2 instead. */
  73. sys_lwmutex_lock(&m_mutex, 0);
  74. m_pushers++;
  75. while (m_count == CAPACITY)
  76. sys_lwcond_wait(&m_full_cond, 0);
  77. m_pushers--;
  78. m_values[(m_start + m_count) % CAPACITY] = value;
  79. m_count++;
  80. if (m_poppers)
  81. sys_lwcond_signal(&m_empty_cond);
  82. sys_lwmutex_unlock(&m_mutex);
  83. }
  84. T Pop()
  85. {
  86. sys_lwmutex_lock(&m_mutex, 0);
  87. m_poppers++;
  88. while (m_count == 0)
  89. sys_lwcond_wait(&m_empty_cond, 0);
  90. m_poppers--;
  91. T ret = m_values[m_start];
  92. m_start = (m_start + 1) % CAPACITY;
  93. m_count--;
  94. if (m_pushers)
  95. sys_lwcond_signal(&m_full_cond);
  96. sys_lwmutex_unlock(&m_mutex);
  97. return ret;
  98. }
  99. private:
  100. static size_t const CAPACITY = N;
  101. T m_values[CAPACITY];
  102. size_t m_start, m_count;
  103. size_t m_poppers, m_pushers;
  104. sys_lwmutex_t m_mutex;
  105. sys_lwcond_t m_empty_cond, m_full_cond;
  106. };
  107. class ThreadBase
  108. {
  109. public:
  110. ThreadBase(void *(*fn)(void *), void *data)
  111. {
  112. size_t stack_size = 128 * 1024;
  113. char const *thread_name = "new thread";
  114. /* FIXME: choose priority more wisely */
  115. sys_ppu_thread_create(&m_thread, (void (*)(uint64_t))fn,
  116. (uint64_t)data, 1000, stack_size, 0, thread_name);
  117. }
  118. virtual ~ThreadBase()
  119. {
  120. sys_ppu_thread_join(m_thread, NULL);
  121. }
  122. private:
  123. sys_ppu_thread_t m_thread;
  124. };
  125. } /* namespace lol */
  126. #endif // __LOL_THREADBASE_H__