prio_deque.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2013 Simon Archipoff
  4. * Copyright (C) 2013 Inria
  5. * Copyright (C) 2017 CNRS
  6. * Copyright (C) 2014,2017-2018 Université de Bordeaux
  7. *
  8. * StarPU is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU Lesser General Public License as published by
  10. * the Free Software Foundation; either version 2.1 of the License, or (at
  11. * your option) any later version.
  12. *
  13. * StarPU is distributed in the hope that it will be useful, but
  14. * WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  16. *
  17. * See the GNU Lesser General Public License in COPYING.LGPL for more details.
  18. */
  19. #ifndef __PRIO_DEQUE_H__
  20. #define __PRIO_DEQUE_H__
  21. #include <starpu.h>
  22. #include <starpu_scheduler.h>
  23. #include <core/task.h>
  24. struct _starpu_prio_deque
  25. {
  26. struct starpu_task_prio_list list;
  27. unsigned ntasks;
  28. unsigned nprocessed;
  29. // Assumptions:
  30. // exp_len is the sum of predicted_length + predicted_tansfer of all tasks in list
  31. // exp_start is the time at which the first task of list can start
  32. // exp_end = exp_start + exp_end
  33. // Careful: those are NOT maintained by the prio_queue operations
  34. double exp_start, exp_end, exp_len;
  35. };
  36. static inline void _starpu_prio_deque_init(struct _starpu_prio_deque *pdeque)
  37. {
  38. memset(pdeque,0,sizeof(*pdeque));
  39. starpu_task_prio_list_init(&pdeque->list);
  40. }
  41. static inline void _starpu_prio_deque_destroy(struct _starpu_prio_deque *pdeque)
  42. {
  43. starpu_task_prio_list_deinit(&pdeque->list);
  44. }
  45. /* return 0 iff the struct _starpu_prio_deque is not empty */
  46. static inline int _starpu_prio_deque_is_empty(struct _starpu_prio_deque *pdeque)
  47. {
  48. return pdeque->ntasks == 0;
  49. }
  50. static inline void _starpu_prio_deque_erase(struct _starpu_prio_deque *pdeque, struct starpu_task *task)
  51. {
  52. starpu_task_prio_list_erase(&pdeque->list, task);
  53. }
  54. /* push a task in O(lg(nb priorities)) */
  55. static inline int _starpu_prio_deque_push_front_task(struct _starpu_prio_deque *pdeque, struct starpu_task *task)
  56. {
  57. starpu_task_prio_list_push_front(&pdeque->list, task);
  58. pdeque->ntasks++;
  59. return 0;
  60. }
  61. static inline int _starpu_prio_deque_push_back_task(struct _starpu_prio_deque *pdeque, struct starpu_task *task)
  62. {
  63. starpu_task_prio_list_push_back(&pdeque->list, task);
  64. pdeque->ntasks++;
  65. return 0;
  66. }
  67. int _starpu_prio_deque_push_back_task(struct _starpu_prio_deque *, struct starpu_task *);
  68. static inline struct starpu_task * _starpu_prio_deque_highest_task(struct _starpu_prio_deque *pdeque)
  69. {
  70. struct starpu_task *task;
  71. if (starpu_task_prio_list_empty(&pdeque->list))
  72. return NULL;
  73. task = starpu_task_prio_list_front_highest(&pdeque->list);
  74. return task;
  75. }
  76. /* all _starpu_prio_deque_pop/deque_task function return a task or a NULL pointer if none are available
  77. * in O(lg(nb priorities))
  78. */
  79. static inline struct starpu_task * _starpu_prio_deque_pop_task(struct _starpu_prio_deque *pdeque)
  80. {
  81. struct starpu_task *task;
  82. if (starpu_task_prio_list_empty(&pdeque->list))
  83. return NULL;
  84. task = starpu_task_prio_list_pop_front_highest(&pdeque->list);
  85. pdeque->ntasks--;
  86. return task;
  87. }
  88. static inline int _starpu_prio_deque_pop_this_task(struct _starpu_prio_deque *pdeque, int workerid, struct starpu_task *task)
  89. {
  90. unsigned nimpl = 0;
  91. #ifdef STARPU_DEBUG
  92. STARPU_ASSERT(starpu_task_prio_list_ismember(&pdeque->list, task));
  93. #endif
  94. if (workerid < 0 || starpu_worker_can_execute_task_first_impl(workerid, task, &nimpl))
  95. {
  96. starpu_task_set_implementation(task, nimpl);
  97. starpu_task_prio_list_erase(&pdeque->list, task);
  98. pdeque->ntasks--;
  99. return 1;
  100. }
  101. return 0;
  102. }
  103. /* return a task that can be executed by workerid
  104. */
  105. struct starpu_task * _starpu_prio_deque_pop_task_for_worker(struct _starpu_prio_deque *, int workerid, int *skipped);
  106. /* deque a task of the higher priority available */
  107. static inline struct starpu_task * _starpu_prio_deque_deque_task(struct _starpu_prio_deque *pdeque)
  108. {
  109. struct starpu_task *task;
  110. if (starpu_task_prio_list_empty(&pdeque->list))
  111. return NULL;
  112. task = starpu_task_prio_list_pop_back_highest(&pdeque->list);
  113. pdeque->ntasks--;
  114. return task;
  115. }
  116. /* return a task that can be executed by workerid
  117. */
  118. struct starpu_task * _starpu_prio_deque_deque_task_for_worker(struct _starpu_prio_deque *, int workerid, int *skipped);
  119. #endif /* __PRIO_DEQUE_H__ */