command_queue.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2010-2012 University of Bordeaux
  4. * Copyright (C) 2012 CNRS
  5. * Copyright (C) 2012 Vincent Danjean <Vincent.Danjean@ens-lyon.org>
  6. *
  7. * StarPU is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU Lesser General Public License as published by
  9. * the Free Software Foundation; either version 2.1 of the License, or (at
  10. * your option) any later version.
  11. *
  12. * StarPU is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  15. *
  16. * See the GNU Lesser General Public License in COPYING.LGPL for more details.
  17. */
  18. #include "socl.h"
  19. #include "task.h"
  20. #include "gc.h"
  21. /**
  22. * WARNING: command queues do NOT hold references on events. Only events hold references
  23. * on command queues. This way, event release will automatically remove the event from
  24. * its command queue.
  25. */
  26. void command_queue_enqueue_ex(cl_command_queue cq, cl_command cmd, cl_uint num_events, const cl_event * events) {
  27. /* Check if the command is a barrier */
  28. int is_barrier = (cmd->typ == CL_COMMAND_BARRIER || !(cq->properties & CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE));
  29. /* Add references to the command queue */
  30. gc_entity_store(&cmd->cq, cq);
  31. gc_entity_store(&cmd->event->cq, cq);
  32. /* Lock command queue */
  33. pthread_mutex_lock(&cq->mutex);
  34. /*** Number of dependencies ***/
  35. int ndeps = num_events;
  36. /* Add dependency to last barrier if applicable */
  37. if (cq->barrier != NULL)
  38. ndeps++;
  39. /* Add dependencies to out-of-order events (if any) */
  40. if (is_barrier) {
  41. command_list cl = cq->commands;
  42. while (cl != NULL) {
  43. ndeps++;
  44. cl = cl->next;
  45. }
  46. }
  47. /*** Dependencies ***/
  48. cl_event * deps = malloc(ndeps * sizeof(cl_event));
  49. int n = 0;
  50. /* Add dependency to last barrier if applicable */
  51. if (cq->barrier != NULL) deps[n++] = cq->barrier->event;
  52. /* Add dependencies to out-of-order events (if any) */
  53. if (is_barrier) {
  54. command_list cl = cq->commands;
  55. while (cl != NULL) {
  56. deps[n++] = cl->cmd->event;
  57. cl = cl->next;
  58. }
  59. }
  60. /* Add explicit dependencies */
  61. unsigned i;
  62. for (i=0; i<num_events; i++) {
  63. deps[n++] = events[i];
  64. }
  65. /* Make all dependencies explicit for the command */
  66. cmd->num_events = ndeps;
  67. cmd->events = deps;
  68. /* Increment event ref count */
  69. gc_entity_retain(cmd->event);
  70. /* Insert command in the queue */
  71. if (is_barrier) {
  72. /* Remove out-of-order commands */
  73. cq->commands = NULL;
  74. /* Register the command as the last barrier */
  75. cq->barrier = cmd;
  76. }
  77. else {
  78. /* Add command to the list of out-of-order commands */
  79. cq->commands = command_list_cons(cmd, cq->commands);
  80. }
  81. /* Unlock command queue */
  82. pthread_mutex_unlock(&cq->mutex);
  83. /* Submit command */
  84. command_submit_ex(cmd);
  85. }