workers.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2009, 2010, 2011 Université de Bordeaux 1
  4. * Copyright (C) 2010, 2011 Centre National de la Recherche Scientifique
  5. * Copyright (C) 2010, 2011 Institut National de Recherche en Informatique et Automatique
  6. * Copyright (C) 2011 Télécom-SudParis
  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. #include <stdlib.h>
  20. #include <stdio.h>
  21. #include <common/config.h>
  22. #include <common/utils.h>
  23. #include <core/workers.h>
  24. #include <core/debug.h>
  25. #include <core/task.h>
  26. #include <profiling/profiling.h>
  27. #include <starpu_task_list.h>
  28. #ifdef __MINGW32__
  29. #include <windows.h>
  30. #endif
  31. /* acquire/release semantic for concurrent initialization/de-initialization */
  32. static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;
  33. static pthread_cond_t init_cond = PTHREAD_COND_INITIALIZER;
  34. static int init_count;
  35. static enum { UNINITIALIZED, CHANGING, INITIALIZED } initialized = UNINITIALIZED;
  36. static pthread_key_t worker_key;
  37. static struct starpu_machine_config_s config;
  38. struct starpu_machine_config_s *_starpu_get_machine_config(void)
  39. {
  40. return &config;
  41. }
  42. /* in case a task is submitted, we may check whether there exists a worker
  43. that may execute the task or not */
  44. uint32_t _starpu_worker_exists(uint32_t task_mask)
  45. {
  46. return (task_mask & config.worker_mask);
  47. }
  48. uint32_t _starpu_may_submit_cuda_task(void)
  49. {
  50. return (STARPU_CUDA & config.worker_mask);
  51. }
  52. uint32_t _starpu_may_submit_cpu_task(void)
  53. {
  54. return (STARPU_CPU & config.worker_mask);
  55. }
  56. uint32_t _starpu_may_submit_opencl_task(void)
  57. {
  58. return (STARPU_OPENCL & config.worker_mask);
  59. }
  60. static int _starpu_may_use_nth_implementation(enum starpu_archtype arch, struct starpu_codelet_t *cl, unsigned nimpl)
  61. {
  62. switch(arch) {
  63. case STARPU_CPU_WORKER:
  64. return !(cl->cpu_func == STARPU_MULTIPLE_CPU_IMPLEMENTATIONS &&
  65. cl->cpu_funcs[nimpl] == NULL);
  66. case STARPU_CUDA_WORKER:
  67. return !(cl->cuda_func == STARPU_MULTIPLE_CUDA_IMPLEMENTATIONS &&
  68. cl->cuda_funcs[nimpl] == NULL);
  69. case STARPU_OPENCL_WORKER:
  70. return !(cl->opencl_func == STARPU_MULTIPLE_OPENCL_IMPLEMENTATIONS &&
  71. cl->opencl_funcs[nimpl] == NULL);
  72. case STARPU_GORDON_WORKER:
  73. return !(cl->gordon_func == STARPU_MULTIPLE_GORDON_IMPLEMENTATIONS &&
  74. cl->gordon_funcs[nimpl] == 0);
  75. default:
  76. return 0;
  77. }
  78. }
  79. int starpu_worker_may_execute_task(unsigned workerid, struct starpu_task *task, unsigned nimpl)
  80. {
  81. /* TODO: check that the task operand sizes will fit on that device */
  82. /* TODO: call application-provided function for various cases like
  83. * double support, shared memory size limit, etc. */
  84. return !!((task->cl->where & config.workers[workerid].worker_mask) &&
  85. _starpu_may_use_nth_implementation(config.workers[workerid].arch, task->cl, nimpl));
  86. }
  87. int starpu_combined_worker_may_execute_task(unsigned workerid, struct starpu_task *task, unsigned nimpl)
  88. {
  89. /* TODO: check that the task operand sizes will fit on that device */
  90. /* TODO: call application-provided function for various cases like
  91. * double support, shared memory size limit, etc. */
  92. struct starpu_codelet_t *cl = task->cl;
  93. unsigned nworkers = config.topology.nworkers;
  94. /* Is this a parallel worker ? */
  95. if (workerid < nworkers)
  96. {
  97. return !!((task->cl->where & config.workers[workerid].worker_mask) &&
  98. _starpu_may_use_nth_implementation(config.workers[workerid].arch, task->cl, nimpl));
  99. }
  100. else {
  101. if ((cl->type == STARPU_SPMD) || (cl->type == STARPU_FORKJOIN))
  102. {
  103. /* TODO we should add other types of constraints */
  104. /* Is the worker larger than requested ? */
  105. int worker_size = (int)config.combined_workers[workerid - nworkers].worker_size;
  106. return !!((worker_size <= task->cl->max_parallelism) &&
  107. _starpu_may_use_nth_implementation(config.workers[workerid].arch, task->cl, nimpl));
  108. }
  109. else
  110. {
  111. /* We have a sequential task but a parallel worker */
  112. return 0;
  113. }
  114. }
  115. }
  116. /*
  117. * Runtime initialization methods
  118. */
  119. #ifdef STARPU_USE_GORDON
  120. static unsigned gordon_inited = 0;
  121. static struct starpu_worker_set_s gordon_worker_set;
  122. #endif
  123. static void _starpu_init_worker_queue(struct starpu_worker_s *workerarg)
  124. {
  125. pthread_cond_t *cond = workerarg->sched_cond;
  126. pthread_mutex_t *mutex = workerarg->sched_mutex;
  127. unsigned memory_node = workerarg->memory_node;
  128. _starpu_memory_node_register_condition(cond, mutex, memory_node);
  129. }
  130. static void _starpu_launch_drivers(struct starpu_machine_config_s *config)
  131. {
  132. config->running = 1;
  133. pthread_key_create(&worker_key, NULL);
  134. unsigned nworkers = config->topology.nworkers;
  135. /* Launch workers asynchronously (except for SPUs) */
  136. unsigned worker;
  137. for (worker = 0; worker < nworkers; worker++)
  138. {
  139. struct starpu_worker_s *workerarg = &config->workers[worker];
  140. workerarg->config = config;
  141. PTHREAD_MUTEX_INIT(&workerarg->mutex, NULL);
  142. PTHREAD_COND_INIT(&workerarg->ready_cond, NULL);
  143. workerarg->worker_size = 1;
  144. workerarg->combined_workerid = workerarg->workerid;
  145. workerarg->current_rank = 0;
  146. /* if some codelet's termination cannot be handled directly :
  147. * for instance in the Gordon driver, Gordon tasks' callbacks
  148. * may be executed by another thread than that of the Gordon
  149. * driver so that we cannot call the push_codelet_output method
  150. * directly */
  151. workerarg->terminated_jobs = starpu_job_list_new();
  152. starpu_task_list_init(&workerarg->local_tasks);
  153. workerarg->status = STATUS_INITIALIZING;
  154. _STARPU_DEBUG("initialising worker %u\n", worker);
  155. _starpu_init_worker_queue(workerarg);
  156. switch (workerarg->arch) {
  157. #ifdef STARPU_USE_CPU
  158. case STARPU_CPU_WORKER:
  159. workerarg->set = NULL;
  160. workerarg->worker_is_initialized = 0;
  161. pthread_create(&workerarg->worker_thread,
  162. NULL, _starpu_cpu_worker, workerarg);
  163. break;
  164. #endif
  165. #ifdef STARPU_USE_CUDA
  166. case STARPU_CUDA_WORKER:
  167. workerarg->set = NULL;
  168. workerarg->worker_is_initialized = 0;
  169. pthread_create(&workerarg->worker_thread,
  170. NULL, _starpu_cuda_worker, workerarg);
  171. break;
  172. #endif
  173. #ifdef STARPU_USE_OPENCL
  174. case STARPU_OPENCL_WORKER:
  175. workerarg->set = NULL;
  176. workerarg->worker_is_initialized = 0;
  177. pthread_create(&workerarg->worker_thread,
  178. NULL, _starpu_opencl_worker, workerarg);
  179. break;
  180. #endif
  181. #ifdef STARPU_USE_GORDON
  182. case STARPU_GORDON_WORKER:
  183. /* we will only launch gordon once, but it will handle
  184. * the different SPU workers */
  185. if (!gordon_inited)
  186. {
  187. gordon_worker_set.nworkers = config->ngordon_spus;
  188. gordon_worker_set.workers = &config->workers[worker];
  189. gordon_worker_set.set_is_initialized = 0;
  190. pthread_create(&gordon_worker_set.worker_thread, NULL,
  191. _starpu_gordon_worker, &gordon_worker_set);
  192. PTHREAD_MUTEX_LOCK(&gordon_worker_set.mutex);
  193. while (!gordon_worker_set.set_is_initialized)
  194. PTHREAD_COND_WAIT(&gordon_worker_set.ready_cond,
  195. &gordon_worker_set.mutex);
  196. PTHREAD_MUTEX_UNLOCK(&gordon_worker_set.mutex);
  197. gordon_inited = 1;
  198. }
  199. workerarg->set = &gordon_worker_set;
  200. gordon_worker_set.joined = 0;
  201. workerarg->worker_is_running = 1;
  202. break;
  203. #endif
  204. default:
  205. STARPU_ABORT();
  206. }
  207. }
  208. for (worker = 0; worker < nworkers; worker++)
  209. {
  210. struct starpu_worker_s *workerarg = &config->workers[worker];
  211. switch (workerarg->arch) {
  212. case STARPU_CPU_WORKER:
  213. case STARPU_CUDA_WORKER:
  214. case STARPU_OPENCL_WORKER:
  215. PTHREAD_MUTEX_LOCK(&workerarg->mutex);
  216. while (!workerarg->worker_is_initialized)
  217. PTHREAD_COND_WAIT(&workerarg->ready_cond, &workerarg->mutex);
  218. PTHREAD_MUTEX_UNLOCK(&workerarg->mutex);
  219. break;
  220. #ifdef STARPU_USE_GORDON
  221. case STARPU_GORDON_WORKER:
  222. /* the initialization of Gordon worker is
  223. * synchronous for now */
  224. break;
  225. #endif
  226. default:
  227. STARPU_ABORT();
  228. }
  229. }
  230. }
  231. void _starpu_set_local_worker_key(struct starpu_worker_s *worker)
  232. {
  233. pthread_setspecific(worker_key, worker);
  234. }
  235. struct starpu_worker_s *_starpu_get_local_worker_key(void)
  236. {
  237. return (struct starpu_worker_s *) pthread_getspecific(worker_key);
  238. }
  239. /* Initialize the starpu_conf with default values */
  240. int starpu_conf_init(struct starpu_conf *conf)
  241. {
  242. if (!conf)
  243. return -EINVAL;
  244. conf->sched_policy_name = getenv("STARPU_SCHED");
  245. conf->sched_policy = NULL;
  246. /* Note that starpu_get_env_number returns -1 in case the variable is
  247. * not defined */
  248. conf->ncpus = starpu_get_env_number("STARPU_NCPUS");
  249. conf->ncuda = starpu_get_env_number("STARPU_NCUDA");
  250. conf->nopencl = starpu_get_env_number("STARPU_NOPENCL");
  251. conf->nspus = starpu_get_env_number("STARPU_NGORDON");
  252. conf->calibrate = starpu_get_env_number("STARPU_CALIBRATE");
  253. conf->use_explicit_workers_bindid = 0; /* TODO */
  254. conf->use_explicit_workers_cuda_gpuid = 0; /* TODO */
  255. conf->use_explicit_workers_opencl_gpuid = 0; /* TODO */
  256. conf->single_combined_worker = starpu_get_env_number("STARPU_SINGLE_COMBINED_WORKER");
  257. return 0;
  258. }
  259. int starpu_init(struct starpu_conf *user_conf)
  260. {
  261. int ret;
  262. PTHREAD_MUTEX_LOCK(&init_mutex);
  263. while (initialized == CHANGING)
  264. /* Wait for the other one changing it */
  265. PTHREAD_COND_WAIT(&init_cond, &init_mutex);
  266. init_count++;
  267. if (initialized == INITIALIZED) {
  268. /* He initialized it, don't do it again, and let the others get the mutex */
  269. PTHREAD_MUTEX_UNLOCK(&init_mutex);
  270. return 0;
  271. }
  272. /* initialized == UNINITIALIZED */
  273. initialized = CHANGING;
  274. PTHREAD_MUTEX_UNLOCK(&init_mutex);
  275. #ifdef __MINGW32__
  276. WSADATA wsadata;
  277. WSAStartup(MAKEWORD(1,0), &wsadata);
  278. #endif
  279. srand(2008);
  280. #ifdef STARPU_USE_FXT
  281. _starpu_start_fxt_profiling();
  282. #endif
  283. _starpu_open_debug_logfile();
  284. _starpu_data_interface_init();
  285. _starpu_timing_init();
  286. _starpu_profiling_init();
  287. _starpu_load_bus_performance_files();
  288. /* store the pointer to the user explicit configuration during the
  289. * initialization */
  290. config.user_conf = user_conf;
  291. ret = _starpu_build_topology(&config);
  292. if (ret) {
  293. PTHREAD_MUTEX_LOCK(&init_mutex);
  294. init_count--;
  295. initialized = UNINITIALIZED;
  296. /* Let somebody else try to do it */
  297. PTHREAD_COND_SIGNAL(&init_cond);
  298. PTHREAD_MUTEX_UNLOCK(&init_mutex);
  299. return ret;
  300. }
  301. /* We need to store the current task handled by the different
  302. * threads */
  303. _starpu_initialize_current_task_key();
  304. /* initialize the scheduling policy */
  305. _starpu_init_sched_policy(&config);
  306. _starpu_initialize_registered_performance_models();
  307. /* Launch "basic" workers (ie. non-combined workers) */
  308. _starpu_launch_drivers(&config);
  309. PTHREAD_MUTEX_LOCK(&init_mutex);
  310. initialized = INITIALIZED;
  311. /* Tell everybody that we initialized */
  312. PTHREAD_COND_BROADCAST(&init_cond);
  313. PTHREAD_MUTEX_UNLOCK(&init_mutex);
  314. return 0;
  315. }
  316. /*
  317. * Handle runtime termination
  318. */
  319. static void _starpu_terminate_workers(struct starpu_machine_config_s *config)
  320. {
  321. int status STARPU_ATTRIBUTE_UNUSED;
  322. unsigned workerid;
  323. for (workerid = 0; workerid < config->topology.nworkers; workerid++)
  324. {
  325. starpu_wake_all_blocked_workers();
  326. _STARPU_DEBUG("wait for worker %u\n", workerid);
  327. struct starpu_worker_set_s *set = config->workers[workerid].set;
  328. struct starpu_worker_s *worker = &config->workers[workerid];
  329. /* in case StarPU termination code is called from a callback,
  330. * we have to check if pthread_self() is the worker itself */
  331. if (set){
  332. if (!set->joined) {
  333. if (!pthread_equal(pthread_self(), set->worker_thread))
  334. {
  335. status = pthread_join(set->worker_thread, NULL);
  336. #ifdef STARPU_VERBOSE
  337. if (status) {
  338. _STARPU_DEBUG("pthread_join -> %d\n", status);
  339. }
  340. #endif
  341. }
  342. set->joined = 1;
  343. }
  344. }
  345. else {
  346. if (!pthread_equal(pthread_self(), worker->worker_thread))
  347. {
  348. status = pthread_join(worker->worker_thread, NULL);
  349. #ifdef STARPU_VERBOSE
  350. if (status) {
  351. _STARPU_DEBUG("pthread_join -> %d\n", status);
  352. }
  353. #endif
  354. }
  355. }
  356. STARPU_ASSERT(starpu_task_list_empty(&worker->local_tasks));
  357. starpu_job_list_delete(worker->terminated_jobs);
  358. }
  359. }
  360. unsigned _starpu_machine_is_running(void)
  361. {
  362. return config.running;
  363. }
  364. unsigned _starpu_worker_can_block(unsigned memnode STARPU_ATTRIBUTE_UNUSED)
  365. {
  366. #ifdef STARPU_NON_BLOCKING_DRIVERS
  367. return 0;
  368. #else
  369. unsigned can_block = 1;
  370. if (!_starpu_check_that_no_data_request_exists(memnode))
  371. can_block = 0;
  372. if (!_starpu_machine_is_running())
  373. can_block = 0;
  374. if (!_starpu_execute_registered_progression_hooks())
  375. can_block = 0;
  376. return can_block;
  377. #endif
  378. }
  379. static void _starpu_kill_all_workers(struct starpu_machine_config_s *config)
  380. {
  381. /* set the flag which will tell workers to stop */
  382. config->running = 0;
  383. starpu_wake_all_blocked_workers();
  384. }
  385. void starpu_shutdown(void)
  386. {
  387. const char *stats;
  388. PTHREAD_MUTEX_LOCK(&init_mutex);
  389. init_count--;
  390. if (init_count)
  391. /* Still somebody needing StarPU, don't deinitialize */
  392. return;
  393. /* We're last */
  394. initialized = CHANGING;
  395. PTHREAD_MUTEX_UNLOCK(&init_mutex);
  396. _starpu_display_msi_stats();
  397. _starpu_display_alloc_cache_stats();
  398. /* tell all workers to shutdown */
  399. _starpu_kill_all_workers(&config);
  400. #ifdef STARPU_MEMORY_STATUS
  401. if ((stats = getenv("STARPU_MEMORY_STATS")) && atoi(stats))
  402. _starpu_display_data_stats();
  403. #endif
  404. #ifdef STARPU_DATA_STATS
  405. _starpu_display_comm_amounts();
  406. #endif
  407. if ((stats = getenv("STARPU_BUS_STATS")) && atoi(stats))
  408. starpu_bus_profiling_helper_display_summary();
  409. if ((stats = getenv("STARPU_WORKER_STATS")) && atoi(stats))
  410. starpu_worker_profiling_helper_display_summary();
  411. _starpu_deinitialize_registered_performance_models();
  412. /* wait for their termination */
  413. _starpu_terminate_workers(&config);
  414. _starpu_deinit_sched_policy(&config);
  415. _starpu_destroy_topology(&config);
  416. #ifdef STARPU_USE_FXT
  417. _starpu_stop_fxt_profiling();
  418. #endif
  419. _starpu_data_interface_shutdown();
  420. _starpu_close_debug_logfile();
  421. PTHREAD_MUTEX_LOCK(&init_mutex);
  422. initialized = UNINITIALIZED;
  423. /* Let someone else that wants to initialize it again do it */
  424. PTHREAD_COND_SIGNAL(&init_cond);
  425. PTHREAD_MUTEX_UNLOCK(&init_mutex);
  426. }
  427. unsigned starpu_worker_get_count(void)
  428. {
  429. return config.topology.nworkers;
  430. }
  431. int starpu_worker_get_count_by_type(enum starpu_archtype type)
  432. {
  433. switch (type)
  434. {
  435. case STARPU_CPU_WORKER:
  436. return config.topology.ncpus;
  437. case STARPU_CUDA_WORKER:
  438. return config.topology.ncudagpus;
  439. case STARPU_OPENCL_WORKER:
  440. return config.topology.nopenclgpus;
  441. case STARPU_GORDON_WORKER:
  442. return config.topology.ngordon_spus;
  443. default:
  444. return -EINVAL;
  445. }
  446. }
  447. unsigned starpu_combined_worker_get_count(void)
  448. {
  449. return config.topology.ncombinedworkers;
  450. }
  451. unsigned starpu_cpu_worker_get_count(void)
  452. {
  453. return config.topology.ncpus;
  454. }
  455. unsigned starpu_cuda_worker_get_count(void)
  456. {
  457. return config.topology.ncudagpus;
  458. }
  459. unsigned starpu_opencl_worker_get_count(void)
  460. {
  461. return config.topology.nopenclgpus;
  462. }
  463. unsigned starpu_spu_worker_get_count(void)
  464. {
  465. return config.topology.ngordon_spus;
  466. }
  467. /* When analyzing performance, it is useful to see what is the processing unit
  468. * that actually performed the task. This function returns the id of the
  469. * processing unit actually executing it, therefore it makes no sense to use it
  470. * within the callbacks of SPU functions for instance. If called by some thread
  471. * that is not controlled by StarPU, starpu_worker_get_id returns -1. */
  472. int starpu_worker_get_id(void)
  473. {
  474. struct starpu_worker_s * worker;
  475. worker = _starpu_get_local_worker_key();
  476. if (worker)
  477. {
  478. return worker->workerid;
  479. }
  480. else {
  481. /* there is no worker associated to that thread, perhaps it is
  482. * a thread from the application or this is some SPU worker */
  483. return -1;
  484. }
  485. }
  486. int starpu_combined_worker_get_id(void)
  487. {
  488. struct starpu_worker_s *worker;
  489. worker = _starpu_get_local_worker_key();
  490. if (worker)
  491. {
  492. return worker->combined_workerid;
  493. }
  494. else {
  495. /* there is no worker associated to that thread, perhaps it is
  496. * a thread from the application or this is some SPU worker */
  497. return -1;
  498. }
  499. }
  500. int starpu_combined_worker_get_size(void)
  501. {
  502. struct starpu_worker_s *worker;
  503. worker = _starpu_get_local_worker_key();
  504. if (worker)
  505. {
  506. return worker->worker_size;
  507. }
  508. else {
  509. /* there is no worker associated to that thread, perhaps it is
  510. * a thread from the application or this is some SPU worker */
  511. return -1;
  512. }
  513. }
  514. int starpu_combined_worker_get_rank(void)
  515. {
  516. struct starpu_worker_s *worker;
  517. worker = _starpu_get_local_worker_key();
  518. if (worker)
  519. {
  520. return worker->current_rank;
  521. }
  522. else {
  523. /* there is no worker associated to that thread, perhaps it is
  524. * a thread from the application or this is some SPU worker */
  525. return -1;
  526. }
  527. }
  528. int starpu_worker_get_devid(int id)
  529. {
  530. return config.workers[id].devid;
  531. }
  532. struct starpu_worker_s *_starpu_get_worker_struct(unsigned id)
  533. {
  534. return &config.workers[id];
  535. }
  536. struct starpu_combined_worker_s *_starpu_get_combined_worker_struct(unsigned id)
  537. {
  538. unsigned basic_worker_count = starpu_worker_get_count();
  539. STARPU_ASSERT(id >= basic_worker_count);
  540. return &config.combined_workers[id - basic_worker_count];
  541. }
  542. enum starpu_archtype starpu_worker_get_type(int id)
  543. {
  544. return config.workers[id].arch;
  545. }
  546. int starpu_worker_get_ids_by_type(enum starpu_archtype type, int *workerids, int maxsize)
  547. {
  548. unsigned nworkers = starpu_worker_get_count();
  549. int cnt = 0;
  550. unsigned id;
  551. for (id = 0; id < nworkers; id++)
  552. {
  553. if (starpu_worker_get_type(id) == type)
  554. {
  555. /* Perhaps the array is too small ? */
  556. if (cnt >= maxsize)
  557. return -ERANGE;
  558. workerids[cnt++] = id;
  559. }
  560. }
  561. return cnt;
  562. }
  563. void starpu_worker_get_name(int id, char *dst, size_t maxlen)
  564. {
  565. char *name = config.workers[id].name;
  566. snprintf(dst, maxlen, "%s", name);
  567. }
  568. /* Retrieve the status which indicates what the worker is currently doing. */
  569. starpu_worker_status _starpu_worker_get_status(int workerid)
  570. {
  571. return config.workers[workerid].status;
  572. }
  573. /* Change the status of the worker which indicates what the worker is currently
  574. * doing (eg. executing a callback). */
  575. void _starpu_worker_set_status(int workerid, starpu_worker_status status)
  576. {
  577. config.workers[workerid].status = status;
  578. }
  579. void starpu_worker_set_sched_condition(int workerid, pthread_cond_t *sched_cond, pthread_mutex_t *sched_mutex)
  580. {
  581. config.workers[workerid].sched_cond = sched_cond;
  582. config.workers[workerid].sched_mutex = sched_mutex;
  583. }