memory_nodes.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /*
  2. * StarPU
  3. * Copyright (C) INRIA 2008-2009 (see AUTHORS file)
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU Lesser General Public License as published by
  7. * the Free Software Foundation; either version 2.1 of the License, or (at
  8. * your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. *
  14. * See the GNU Lesser General Public License in COPYING.LGPL for more details.
  15. */
  16. #include <pthread.h>
  17. #include <common/config.h>
  18. #include <core/policies/sched_policy.h>
  19. #include <datawizard/datastats.h>
  20. #include <common/fxt.h>
  21. #include "copy-driver.h"
  22. #include "memalloc.h"
  23. static starpu_mem_node_descr descr;
  24. static pthread_key_t memory_node_key;
  25. void starpu_init_memory_nodes(void)
  26. {
  27. /* there is no node yet, subsequent nodes will be
  28. * added using _starpu_register_memory_node */
  29. descr.nnodes = 0;
  30. pthread_key_create(&memory_node_key, NULL);
  31. unsigned i;
  32. for (i = 0; i < STARPU_MAXNODES; i++)
  33. descr.nodes[i] = STARPU_UNUSED;
  34. _starpu_init_mem_chunk_lists();
  35. starpu_init_data_request_lists();
  36. pthread_rwlock_init(&descr.attached_queues_rwlock, NULL);
  37. descr.total_queues_count = 0;
  38. }
  39. void starpu_deinit_memory_nodes(void)
  40. {
  41. starpu_deinit_data_request_lists();
  42. _starpu_deinit_mem_chunk_lists();
  43. pthread_key_delete(memory_node_key);
  44. }
  45. void starpu_set_local_memory_node_key(unsigned *node)
  46. {
  47. pthread_setspecific(memory_node_key, node);
  48. }
  49. unsigned starpu_get_local_memory_node(void)
  50. {
  51. unsigned *memory_node;
  52. memory_node = pthread_getspecific(memory_node_key);
  53. /* in case this is called by the programmer, we assume the STARPU_RAM node
  54. is the appropriate memory node ... so we return 0 XXX */
  55. if (STARPU_UNLIKELY(!memory_node))
  56. return 0;
  57. return *memory_node;
  58. }
  59. inline starpu_mem_node_descr *starpu_get_memory_node_description(void)
  60. {
  61. return &descr;
  62. }
  63. inline starpu_node_kind starpu_get_node_kind(uint32_t node)
  64. {
  65. return descr.nodes[node];
  66. }
  67. unsigned starpu_get_memory_nodes_count(void)
  68. {
  69. return descr.nnodes;
  70. }
  71. unsigned _starpu_register_memory_node(starpu_node_kind kind)
  72. {
  73. unsigned nnodes;
  74. /* ATOMIC_ADD returns the new value ... */
  75. nnodes = STARPU_ATOMIC_ADD(&descr.nnodes, 1);
  76. descr.nodes[nnodes-1] = kind;
  77. TRACE_NEW_MEM_NODE(nnodes-1);
  78. /* for now, there is no queue related to that newly created node */
  79. descr.queues_count[nnodes-1] = 0;
  80. return (nnodes-1);
  81. }
  82. /* TODO move in a more appropriate file !! */
  83. /* attach a queue to a memory node (if it's not already attached) */
  84. void starpu_memory_node_attach_queue(struct jobq_s *q, unsigned nodeid)
  85. {
  86. unsigned queue;
  87. unsigned nqueues_total, nqueues;
  88. pthread_rwlock_wrlock(&descr.attached_queues_rwlock);
  89. /* we only insert the queue if it's not already in the list */
  90. nqueues = descr.queues_count[nodeid];
  91. for (queue = 0; queue < nqueues; queue++)
  92. {
  93. if (descr.attached_queues_per_node[nodeid][queue] == q)
  94. {
  95. /* the queue is already in the list */
  96. pthread_rwlock_unlock(&descr.attached_queues_rwlock);
  97. return;
  98. }
  99. }
  100. /* it was not found locally */
  101. descr.attached_queues_per_node[nodeid][nqueues] = q;
  102. descr.queues_count[nodeid]++;
  103. /* do we have to add it in the global list as well ? */
  104. nqueues_total = descr.total_queues_count;
  105. for (queue = 0; queue < nqueues_total; queue++)
  106. {
  107. if (descr.attached_queues_all[queue] == q)
  108. {
  109. /* the queue is already in the global list */
  110. pthread_rwlock_unlock(&descr.attached_queues_rwlock);
  111. return;
  112. }
  113. }
  114. /* it was not in the global queue either */
  115. descr.attached_queues_all[nqueues_total] = q;
  116. descr.total_queues_count++;
  117. pthread_rwlock_unlock(&descr.attached_queues_rwlock);
  118. }
  119. unsigned starpu_get_worker_memory_node(unsigned workerid)
  120. {
  121. struct worker_s *worker = _starpu_get_worker_struct(workerid);
  122. return worker->memory_node;
  123. }