worker_list.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. #include <starpu.h>
  2. #include <pthread.h>
  3. static unsigned list_has_next(struct worker_collection *workers)
  4. {
  5. int nworkers = (int)workers->nworkers;
  6. int *cursor = (int*)pthread_getspecific(workers->cursor_key);
  7. unsigned ret = cursor ? *cursor < nworkers : 0;
  8. if(!ret && cursor) *cursor = 0;
  9. return ret;
  10. }
  11. static int list_get_next(struct worker_collection *workers)
  12. {
  13. int *workerids = (int *)workers->workerids;
  14. int nworkers = (int)workers->nworkers;
  15. int *cursor = (int*)pthread_getspecific(workers->cursor_key);
  16. STARPU_ASSERT(*cursor < nworkers);
  17. int ret = workerids[(*cursor)++];
  18. return ret;
  19. }
  20. static unsigned _worker_belongs_to_ctx(struct worker_collection *workers, int workerid)
  21. {
  22. int *workerids = (int *)workers->workerids;
  23. unsigned nworkers = workers->nworkers;
  24. int i;
  25. for(i = 0; i < nworkers; i++)
  26. {
  27. if(workerids[i] == workerid)
  28. return 1;
  29. }
  30. return 0;
  31. }
  32. static int list_add(struct worker_collection *workers, int worker)
  33. {
  34. int *workerids = (int *)workers->workerids;
  35. unsigned *nworkers = &workers->nworkers;
  36. STARPU_ASSERT(*nworkers < STARPU_NMAXWORKERS - 1);
  37. if(!_worker_belongs_to_ctx(workers, worker))
  38. {
  39. workerids[(*nworkers)++] = worker;
  40. return worker;
  41. }
  42. else
  43. return -1;
  44. }
  45. static int _get_first_free_worker(int *workerids, int nworkers)
  46. {
  47. int i;
  48. for(i = 0; i < nworkers; i++)
  49. if(workerids[i] == -1)
  50. return i;
  51. return -1;
  52. }
  53. /* rearange array of workerids in order not to have {-1, -1, 5, -1, 7}
  54. and have instead {5, 7, -1, -1, -1}
  55. it is easier afterwards to iterate the array
  56. */
  57. static void _rearange_workerids(int *workerids, int old_nworkers)
  58. {
  59. int first_free_id = -1;
  60. int i;
  61. for(i = 0; i < old_nworkers; i++)
  62. {
  63. if(workerids[i] != -1)
  64. {
  65. first_free_id = _get_first_free_worker(workerids, old_nworkers);
  66. if(first_free_id != -1)
  67. {
  68. workerids[first_free_id] = workerids[i];
  69. workerids[i] = -1;
  70. }
  71. }
  72. }
  73. }
  74. static int list_remove(struct worker_collection *workers, int worker)
  75. {
  76. int *workerids = (int *)workers->workerids;
  77. unsigned nworkers = workers->nworkers;
  78. int found_worker = -1;
  79. unsigned i;
  80. for(i = 0; i < nworkers; i++)
  81. {
  82. if(workerids[i] == worker)
  83. {
  84. workerids[i] = -1;
  85. found_worker = worker;
  86. break;
  87. }
  88. }
  89. _rearange_workerids(workerids, nworkers);
  90. if(found_worker != -1)
  91. workers->nworkers--;
  92. return found_worker;
  93. }
  94. static void _init_workers(int *workerids)
  95. {
  96. unsigned i;
  97. for(i = 0; i < STARPU_NMAXWORKERS; i++)
  98. workerids[i] = -1;
  99. return;
  100. }
  101. static void* list_init(struct worker_collection *workers)
  102. {
  103. int *workerids = (int*)malloc(STARPU_NMAXWORKERS * sizeof(int));
  104. _init_workers(workerids);
  105. pthread_key_create(&workers->cursor_key, NULL);
  106. return (void*)workerids;
  107. }
  108. static void list_deinit(struct worker_collection *workers)
  109. {
  110. free(workers->workerids);
  111. pthread_key_delete(workers->cursor_key);
  112. }
  113. static void list_init_cursor(struct worker_collection *workers)
  114. {
  115. int *cursor = (int*)malloc(sizeof(int));
  116. *cursor = 0;
  117. pthread_setspecific(workers->cursor_key, (void*)cursor);
  118. }
  119. static void list_deinit_cursor(struct worker_collection *workers)
  120. {
  121. int *cursor = (int*)pthread_getspecific(workers->cursor_key);
  122. *cursor = 0;
  123. free(cursor);
  124. }
  125. struct worker_collection worker_list = {
  126. .has_next = list_has_next,
  127. .get_next = list_get_next,
  128. .add = list_add,
  129. .remove = list_remove,
  130. .init = list_init,
  131. .deinit = list_deinit,
  132. .init_cursor = list_init_cursor,
  133. .deinit_cursor = list_deinit_cursor,
  134. .type = WORKER_LIST
  135. };