7 SMPI_Global_t smpi_global = NULL;
9 SMPI_MPI_Global_t smpi_mpi_global = NULL;
11 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi,XBT_LOG_ROOT_CAT, "All SMPI categories (see \ref SMPI_API)");
13 int inline smpi_mpi_comm_size(smpi_mpi_communicator_t *comm)
18 // FIXME: smarter algorithm?
19 int smpi_mpi_comm_rank(smpi_mpi_communicator_t *comm, smx_host_t host)
23 for(i = comm->size - 1; i > 0 && host != comm->hosts[i]; i--);
28 int inline smpi_mpi_comm_rank_self(smpi_mpi_communicator_t *comm)
30 return smpi_mpi_comm_rank(comm, SIMIX_host_self());
33 //int smpi_mpi_comm_world_rank_self()
35 // return smpi_mpi_comm_rank(smpi_mpi_global->mpi_comm_world, SIMIX_host_self());
38 int smpi_sender(int argc, char **argv)
44 xbt_fifo_t request_queue;
45 smx_mutex_t request_queue_mutex;
48 int running_hosts_count;
50 smpi_mpi_request_t *request;
54 smx_action_t communicate_action;
56 smpi_received_message_t *message;
60 smx_process_t receiver_process;
62 self = SIMIX_process_self();
63 shost = SIMIX_host_self();
64 rank = smpi_mpi_comm_rank(smpi_mpi_global->mpi_comm_world, shost);
66 // make sure root is done before own initialization
67 SIMIX_mutex_lock(smpi_global->start_stop_mutex);
68 if (!smpi_global->root_ready) {
69 SIMIX_cond_wait(smpi_global->start_stop_cond, smpi_global->start_stop_mutex);
71 SIMIX_mutex_unlock(smpi_global->start_stop_mutex);
73 request_queue = smpi_global->pending_send_request_queues[rank];
74 request_queue_mutex = smpi_global->pending_send_request_queues_mutexes[rank];
75 size = smpi_mpi_comm_size(smpi_mpi_global->mpi_comm_world);
77 smpi_global->sender_processes[rank] = self;
79 // wait for all nodes to signal initializatin complete
80 SIMIX_mutex_lock(smpi_global->start_stop_mutex);
81 smpi_global->ready_process_count++;
82 if (smpi_global->ready_process_count < 3 * size) {
83 SIMIX_cond_wait(smpi_global->start_stop_cond, smpi_global->start_stop_mutex);
85 SIMIX_cond_broadcast(smpi_global->start_stop_cond);
87 SIMIX_mutex_unlock(smpi_global->start_stop_mutex);
91 SIMIX_mutex_lock(request_queue_mutex);
92 request = xbt_fifo_shift(request_queue);
93 SIMIX_mutex_unlock(request_queue_mutex);
95 if (NULL == request) {
96 SIMIX_process_suspend(self);
99 SIMIX_mutex_lock(request->mutex);
101 // copy request to appropriate received queue
102 message = xbt_mallocator_get(smpi_global->message_mallocator);
103 message->comm = request->comm;
104 message->src = request->src;
105 message->dst = request->dst;
106 message->tag = request->tag;
107 message->buf = xbt_malloc(request->datatype->size * request->count);
108 memcpy(message->buf, request->buf, request->datatype->size * request->count);
110 dhost = request->comm->hosts[request->dst];
111 drank = smpi_mpi_comm_rank(smpi_mpi_global->mpi_comm_world, dhost);
113 SIMIX_mutex_lock(smpi_global->received_message_queues_mutexes[drank]);
114 xbt_fifo_push(smpi_global->received_message_queues[drank], message);
115 SIMIX_mutex_unlock(smpi_global->received_message_queues_mutexes[drank]);
117 request->completed = 1;
119 communicate_action = SIMIX_action_communicate(shost, dhost,
120 NULL, request->datatype->size * request->count * 1.0, -1.0);
122 SIMIX_register_action_to_condition(communicate_action, request->cond);
123 SIMIX_cond_wait(request->cond, request->mutex);
124 //SIMIX_unregister_action_to_condition(communicate_action, request->cond);
126 SIMIX_mutex_unlock(request->mutex);
128 // wake up receiver if necessary
129 receiver_process = smpi_global->receiver_processes[drank];
131 if (SIMIX_process_is_suspended(receiver_process)) {
132 SIMIX_process_resume(receiver_process);
137 SIMIX_mutex_lock(smpi_global->running_hosts_count_mutex);
138 running_hosts_count = smpi_global->running_hosts_count;
139 SIMIX_mutex_unlock(smpi_global->running_hosts_count_mutex);
141 } while (0 < running_hosts_count);
143 SIMIX_mutex_lock(smpi_global->start_stop_mutex);
144 smpi_global->ready_process_count--;
145 if (smpi_global->ready_process_count == 0) {
146 SIMIX_cond_broadcast(smpi_global->start_stop_cond);
147 } else if (smpi_global->ready_process_count < 0) {
148 // FIXME: can't happen! abort!
150 SIMIX_mutex_unlock(smpi_global->start_stop_mutex);
155 int smpi_receiver(int argc, char **argv)
160 xbt_fifo_t request_queue;
161 smx_mutex_t request_queue_mutex;
162 xbt_fifo_t message_queue;
163 smx_mutex_t message_queue_mutex;
166 int running_hosts_count;
168 smpi_mpi_request_t *request;
169 smpi_received_message_t *message;
171 xbt_fifo_item_t request_item;
172 xbt_fifo_item_t message_item;
174 self = SIMIX_process_self();
175 rank = smpi_mpi_comm_rank_self(smpi_mpi_global->mpi_comm_world);
177 // make sure root is done before own initialization
178 SIMIX_mutex_lock(smpi_global->start_stop_mutex);
179 if (!smpi_global->root_ready) {
180 SIMIX_cond_wait(smpi_global->start_stop_cond, smpi_global->start_stop_mutex);
182 SIMIX_mutex_unlock(smpi_global->start_stop_mutex);
184 request_queue = smpi_global->pending_recv_request_queues[rank];
185 request_queue_mutex = smpi_global->pending_recv_request_queues_mutexes[rank];
186 message_queue = smpi_global->received_message_queues[rank];
187 message_queue_mutex = smpi_global->received_message_queues_mutexes[rank];
188 size = smpi_mpi_comm_size(smpi_mpi_global->mpi_comm_world);
190 smpi_global->receiver_processes[rank] = self;
192 // wait for all nodes to signal initializatin complete
193 SIMIX_mutex_lock(smpi_global->start_stop_mutex);
194 smpi_global->ready_process_count++;
195 if (smpi_global->ready_process_count < 3 * size) {
196 SIMIX_cond_wait(smpi_global->start_stop_cond, smpi_global->start_stop_mutex);
198 SIMIX_cond_broadcast(smpi_global->start_stop_cond);
200 SIMIX_mutex_unlock(smpi_global->start_stop_mutex);
206 // FIXME: better algorithm, maybe some kind of balanced tree? or a heap?
208 // FIXME: not the best way to request multiple locks...
209 SIMIX_mutex_lock(request_queue_mutex);
210 SIMIX_mutex_lock(message_queue_mutex);
211 for (request_item = xbt_fifo_get_first_item(request_queue);
212 NULL != request_item;
213 request_item = xbt_fifo_get_next_item(request_item)) {
214 request = xbt_fifo_get_item_content(request_item);
215 for (message_item = xbt_fifo_get_first_item(message_queue);
216 NULL != message_item;
217 message_item = xbt_fifo_get_next_item(message_item)) {
218 message = xbt_fifo_get_item_content(message_item);
219 if (request->comm == message->comm &&
220 (MPI_ANY_SOURCE == request->src || request->src == message->src) &&
221 request->tag == message->tag) {
222 xbt_fifo_remove_item(request_queue, request_item);
223 xbt_fifo_remove_item(message_queue, message_item);
229 SIMIX_mutex_unlock(message_queue_mutex);
230 SIMIX_mutex_unlock(request_queue_mutex);
232 if (NULL == request || NULL == message) {
233 SIMIX_process_suspend(self);
235 SIMIX_mutex_lock(request->mutex);
237 memcpy(request->buf, message->buf, request->datatype->size * request->count);
238 request->src = message->src;
239 request->completed = 1;
240 SIMIX_cond_broadcast(request->cond);
242 SIMIX_mutex_unlock(request->mutex);
244 xbt_free(message->buf);
245 xbt_mallocator_release(smpi_global->message_mallocator, message);
248 SIMIX_mutex_lock(smpi_global->running_hosts_count_mutex);
249 running_hosts_count = smpi_global->running_hosts_count;
250 SIMIX_mutex_unlock(smpi_global->running_hosts_count_mutex);
252 } while (0 < running_hosts_count);
254 SIMIX_mutex_lock(smpi_global->start_stop_mutex);
255 smpi_global->ready_process_count--;
256 if (smpi_global->ready_process_count == 0) {
257 SIMIX_cond_broadcast(smpi_global->start_stop_cond);
258 } else if (smpi_global->ready_process_count < 0) {
259 // FIXME: can't happen, abort!
261 SIMIX_mutex_unlock(smpi_global->start_stop_mutex);
266 void *smpi_request_new()
268 smpi_mpi_request_t *request = xbt_new(smpi_mpi_request_t, 1);
270 request->completed = 0;
271 request->mutex = SIMIX_mutex_init();
272 request->cond = SIMIX_cond_init();
277 void smpi_request_free(void *pointer)
280 smpi_mpi_request_t *request = pointer;
282 if (NULL != request) {
283 SIMIX_cond_destroy(request->cond);
284 SIMIX_mutex_destroy(request->mutex);
291 void smpi_request_reset(void *pointer)
297 void *smpi_message_new()
299 return xbt_new(smpi_received_message_t, 1);
302 void smpi_message_free(void *pointer)
304 if (NULL != pointer) {
311 void smpi_message_reset(void *pointer)
316 void smpi_global_init()
320 int size = SIMIX_host_get_number();
322 smpi_global = xbt_new(s_SMPI_Global_t, 1);
325 smpi_global->reference_speed = SMPI_DEFAULT_SPEED;
327 smpi_global->root_ready = 0;
328 smpi_global->ready_process_count = 0;
331 smpi_global->start_stop_mutex = SIMIX_mutex_init();
332 smpi_global->start_stop_cond = SIMIX_cond_init();
335 smpi_global->sender_processes = xbt_new(smx_process_t, size);
336 smpi_global->receiver_processes = xbt_new(smx_process_t, size);
339 smpi_global->running_hosts_count_mutex = SIMIX_mutex_init();
340 smpi_global->running_hosts_count = 0;
343 smpi_global->request_mallocator = xbt_mallocator_new(SMPI_REQUEST_MALLOCATOR_SIZE,
344 smpi_request_new, smpi_request_free, smpi_request_reset);
345 smpi_global->message_mallocator = xbt_mallocator_new(SMPI_MESSAGE_MALLOCATOR_SIZE,
346 smpi_message_new, smpi_message_free, smpi_message_reset);
349 smpi_global->pending_send_request_queues = xbt_new(xbt_fifo_t, size);
350 smpi_global->pending_send_request_queues_mutexes = xbt_new(smx_mutex_t, size);
351 smpi_global->pending_recv_request_queues = xbt_new(xbt_fifo_t, size);
352 smpi_global->pending_recv_request_queues_mutexes = xbt_new(smx_mutex_t, size);
353 smpi_global->received_message_queues = xbt_new(xbt_fifo_t, size);
354 smpi_global->received_message_queues_mutexes = xbt_new(smx_mutex_t, size);
355 smpi_global->timers = xbt_new(xbt_os_timer_t, size);
356 smpi_global->timers_mutexes = xbt_new(smx_mutex_t, size);
358 for(i = 0; i < size; i++) {
359 smpi_global->pending_send_request_queues[i] = xbt_fifo_new();
360 smpi_global->pending_send_request_queues_mutexes[i] = SIMIX_mutex_init();
361 smpi_global->pending_recv_request_queues[i] = xbt_fifo_new();
362 smpi_global->pending_recv_request_queues_mutexes[i] = SIMIX_mutex_init();
363 smpi_global->received_message_queues[i] = xbt_fifo_new();
364 smpi_global->received_message_queues_mutexes[i] = SIMIX_mutex_init();
365 smpi_global->timers[i] = xbt_os_timer_new();
366 smpi_global->timers_mutexes[i] = SIMIX_mutex_init();
371 void smpi_global_destroy()
375 int size = SIMIX_host_get_number();
378 SIMIX_mutex_destroy(smpi_global->start_stop_mutex);
379 SIMIX_cond_destroy(smpi_global->start_stop_cond);
382 xbt_free(smpi_global->sender_processes);
383 xbt_free(smpi_global->receiver_processes);
386 SIMIX_mutex_destroy(smpi_global->running_hosts_count_mutex);
389 xbt_mallocator_free(smpi_global->request_mallocator);
390 xbt_mallocator_free(smpi_global->message_mallocator);
392 for(i = 0; i < size; i++) {
393 xbt_fifo_free(smpi_global->pending_send_request_queues[i]);
394 SIMIX_mutex_destroy(smpi_global->pending_send_request_queues_mutexes[i]);
395 xbt_fifo_free(smpi_global->pending_recv_request_queues[i]);
396 SIMIX_mutex_destroy(smpi_global->pending_recv_request_queues_mutexes[i]);
397 xbt_fifo_free(smpi_global->received_message_queues[i]);
398 SIMIX_mutex_destroy(smpi_global->received_message_queues_mutexes[i]);
399 xbt_os_timer_free(smpi_global->timers[i]);
400 SIMIX_mutex_destroy(smpi_global->timers_mutexes[i]);
403 xbt_free(smpi_global->pending_send_request_queues);
404 xbt_free(smpi_global->pending_send_request_queues_mutexes);
405 xbt_free(smpi_global->pending_recv_request_queues);
406 xbt_free(smpi_global->pending_recv_request_queues_mutexes);
407 xbt_free(smpi_global->received_message_queues);
408 xbt_free(smpi_global->received_message_queues_mutexes);
409 xbt_free(smpi_global->timers);
410 xbt_free(smpi_global->timers_mutexes);
412 xbt_free(smpi_global);
415 int smpi_run_simulation(int argc, char **argv)
417 xbt_fifo_item_t cond_item = NULL;
418 smx_cond_t cond = NULL;
419 smx_action_t action = NULL;
421 xbt_fifo_t actions_failed = xbt_fifo_new();
422 xbt_fifo_t actions_done = xbt_fifo_new();
424 srand(SMPI_RAND_SEED);
426 SIMIX_global_init(&argc, argv);
428 SIMIX_function_register("smpi_simulated_main", smpi_simulated_main);
429 SIMIX_function_register("smpi_sender", smpi_sender);
430 SIMIX_function_register("smpi_receiver", smpi_receiver);
432 // FIXME: ought to verify these files...
433 SIMIX_create_environment(argv[1]);
435 // must initialize globals between creating environment and launching app....
438 SIMIX_launch_application(argv[2]);
440 /* Prepare to display some more info when dying on Ctrl-C pressing */
441 // FIXME: doesn't work
442 //signal(SIGINT, inthandler);
444 /* Clean IO before the run */
448 while (SIMIX_solve(actions_done, actions_failed) != -1.0) {
449 while ((action = xbt_fifo_pop(actions_failed))) {
450 DEBUG1("** %s failed **", action->name);
451 xbt_fifo_foreach(action->cond_list, cond_item, cond, smx_cond_t) {
452 SIMIX_cond_broadcast(cond);
453 SIMIX_unregister_action_to_condition(action, cond);
455 SIMIX_action_destroy(action);
457 while ((action = xbt_fifo_pop(actions_done))) {
458 DEBUG1("** %s done **",action->name);
459 xbt_fifo_foreach(action->cond_list, cond_item, cond, smx_cond_t) {
460 SIMIX_cond_broadcast(cond);
461 SIMIX_unregister_action_to_condition(action, cond);
463 SIMIX_action_destroy(action);
467 xbt_fifo_free(actions_failed);
468 xbt_fifo_free(actions_done);
470 INFO1("simulation time %g", SIMIX_get_clock());
472 smpi_global_destroy();
479 void smpi_mpi_land_func(void *x, void *y, void *z)
481 *(int *)z = *(int *)x && *(int *)y;
484 void smpi_mpi_sum_func(void *x, void *y, void *z)
486 *(int *)z = *(int *)x + *(int *)y;
492 smx_process_t process;
497 SIMIX_mutex_lock(smpi_global->running_hosts_count_mutex);
498 smpi_global->running_hosts_count++;
499 SIMIX_mutex_unlock(smpi_global->running_hosts_count_mutex);
501 // initialize some local variables
502 process = SIMIX_process_self();
503 host = SIMIX_host_self();
504 hosts = SIMIX_host_get_table();
505 size = SIMIX_host_get_number();
507 // node 0 sets the globals
508 if (host == hosts[0]) {
510 smpi_mpi_global = xbt_new(s_SMPI_MPI_Global_t, 1);
512 // global communicator
513 smpi_mpi_global->mpi_comm_world = xbt_new(smpi_mpi_communicator_t, 1);
514 smpi_mpi_global->mpi_comm_world->size = size;
515 smpi_mpi_global->mpi_comm_world->barrier_count = 0;
516 smpi_mpi_global->mpi_comm_world->barrier_mutex = SIMIX_mutex_init();
517 smpi_mpi_global->mpi_comm_world->barrier_cond = SIMIX_cond_init();
518 smpi_mpi_global->mpi_comm_world->hosts = hosts;
519 smpi_mpi_global->mpi_comm_world->processes = xbt_new(smx_process_t, size);
520 smpi_mpi_global->mpi_comm_world->processes[0] = process;
523 smpi_mpi_global->mpi_byte = xbt_new(smpi_mpi_datatype_t, 1);
524 smpi_mpi_global->mpi_byte->size = (size_t)1;
525 smpi_mpi_global->mpi_int = xbt_new(smpi_mpi_datatype_t, 1);
526 smpi_mpi_global->mpi_int->size = sizeof(int);
527 smpi_mpi_global->mpi_double = xbt_new(smpi_mpi_datatype_t, 1);
528 smpi_mpi_global->mpi_double->size = sizeof(double);
531 smpi_mpi_global->mpi_land = xbt_new(smpi_mpi_op_t, 1);
532 smpi_mpi_global->mpi_land->func = smpi_mpi_land_func;
533 smpi_mpi_global->mpi_sum = xbt_new(smpi_mpi_op_t, 1);
534 smpi_mpi_global->mpi_sum->func = smpi_mpi_sum_func;
536 // signal all nodes to perform initialization
537 SIMIX_mutex_lock(smpi_global->start_stop_mutex);
538 smpi_global->root_ready = 1;
539 SIMIX_cond_broadcast(smpi_global->start_stop_cond);
540 SIMIX_mutex_unlock(smpi_global->start_stop_mutex);
544 // make sure root is done before own initialization
545 SIMIX_mutex_lock(smpi_global->start_stop_mutex);
546 if (!smpi_global->root_ready) {
547 SIMIX_cond_wait(smpi_global->start_stop_cond, smpi_global->start_stop_mutex);
549 SIMIX_mutex_unlock(smpi_global->start_stop_mutex);
551 smpi_mpi_global->mpi_comm_world->processes[smpi_mpi_comm_rank_self(smpi_mpi_global->mpi_comm_world)] = process;
554 // wait for all nodes to signal initializatin complete
555 SIMIX_mutex_lock(smpi_global->start_stop_mutex);
556 smpi_global->ready_process_count++;
557 if (smpi_global->ready_process_count < 3 * size) {
558 SIMIX_cond_wait(smpi_global->start_stop_cond, smpi_global->start_stop_mutex);
560 SIMIX_cond_broadcast(smpi_global->start_stop_cond);
562 SIMIX_mutex_unlock(smpi_global->start_stop_mutex);
567 void smpi_mpi_finalize()
571 SIMIX_mutex_lock(smpi_global->running_hosts_count_mutex);
572 i = --smpi_global->running_hosts_count;
573 SIMIX_mutex_unlock(smpi_global->running_hosts_count_mutex);
575 SIMIX_mutex_lock(smpi_global->start_stop_mutex);
576 smpi_global->ready_process_count--;
577 SIMIX_mutex_unlock(smpi_global->start_stop_mutex);
581 // wake up senders/receivers
582 for (i = 0; i < smpi_mpi_global->mpi_comm_world->size; i++) {
583 if (SIMIX_process_is_suspended(smpi_global->sender_processes[i])) {
584 SIMIX_process_resume(smpi_global->sender_processes[i]);
586 if (SIMIX_process_is_suspended(smpi_global->receiver_processes[i])) {
587 SIMIX_process_resume(smpi_global->receiver_processes[i]);
591 // wait for senders/receivers to exit...
592 SIMIX_mutex_lock(smpi_global->start_stop_mutex);
593 if (smpi_global->ready_process_count > 0) {
594 SIMIX_cond_wait(smpi_global->start_stop_cond, smpi_global->start_stop_mutex);
596 SIMIX_mutex_unlock(smpi_global->start_stop_mutex);
598 SIMIX_mutex_destroy(smpi_mpi_global->mpi_comm_world->barrier_mutex);
599 SIMIX_cond_destroy(smpi_mpi_global->mpi_comm_world->barrier_cond);
600 xbt_free(smpi_mpi_global->mpi_comm_world->processes);
601 xbt_free(smpi_mpi_global->mpi_comm_world);
603 xbt_free(smpi_mpi_global->mpi_byte);
604 xbt_free(smpi_mpi_global->mpi_int);
605 xbt_free(smpi_mpi_global->mpi_double);
607 xbt_free(smpi_mpi_global->mpi_land);
608 xbt_free(smpi_mpi_global->mpi_sum);
610 xbt_free(smpi_mpi_global);
615 // FIXME: could cause trouble with multithreaded procs on same host...
616 void smpi_bench_begin()
618 int rank = smpi_mpi_comm_rank_self(smpi_mpi_global->mpi_comm_world);
619 SIMIX_mutex_lock(smpi_global->timers_mutexes[rank]);
620 xbt_os_timer_start(smpi_global->timers[rank]);
624 void smpi_bench_end()
626 int rank = smpi_mpi_comm_rank_self(smpi_mpi_global->mpi_comm_world);
629 smx_action_t compute_action;
633 xbt_os_timer_stop(smpi_global->timers[rank]);
635 duration = xbt_os_timer_elapsed(smpi_global->timers[rank]);
636 SIMIX_mutex_unlock(smpi_global->timers_mutexes[rank]);
638 host = smpi_mpi_global->mpi_comm_world->hosts[rank];
639 compute_action = SIMIX_action_execute(host, NULL, duration * SMPI_DEFAULT_SPEED);
640 mutex = SIMIX_mutex_init();
641 cond = SIMIX_cond_init();
643 SIMIX_mutex_lock(mutex);
644 SIMIX_register_action_to_condition(compute_action, cond);
645 SIMIX_cond_wait(cond, mutex);
646 //SIMIX_unregister_action_to_condition(compute_action, cond);
647 SIMIX_mutex_unlock(mutex);
649 SIMIX_mutex_destroy(mutex);
650 SIMIX_cond_destroy(cond);
652 // FIXME: check for success/failure?
657 void smpi_barrier(smpi_mpi_communicator_t *comm)
660 SIMIX_mutex_lock(comm->barrier_mutex);
661 if(++comm->barrier_count < comm->size) {
662 SIMIX_cond_wait(comm->barrier_cond, comm->barrier_mutex);
664 comm->barrier_count = 0;
665 SIMIX_cond_broadcast(comm->barrier_cond);
667 SIMIX_mutex_unlock(comm->barrier_mutex);
672 // FIXME: smarter algorithm...
673 int smpi_comm_rank(smpi_mpi_communicator_t *comm, smx_host_t host)
676 for(i = 0; i < comm->size && host != comm->hosts[i]; i++);
677 if (i >= comm->size) i = -1;
681 int smpi_create_request(void *buf, int count, smpi_mpi_datatype_t *datatype,
682 int src, int dst, int tag, smpi_mpi_communicator_t *comm, smpi_mpi_request_t **request)
684 int retval = MPI_SUCCESS;
689 retval = MPI_ERR_COUNT;
690 } else if (NULL == buf) {
691 retval = MPI_ERR_INTERN;
692 } else if (NULL == datatype) {
693 retval = MPI_ERR_TYPE;
694 } else if (NULL == comm) {
695 retval = MPI_ERR_COMM;
696 } else if (MPI_ANY_SOURCE != src && (0 > src || comm->size <= src)) {
697 retval = MPI_ERR_RANK;
698 } else if (0 > dst || comm->size <= dst) {
699 retval = MPI_ERR_RANK;
700 } else if (0 > tag) {
701 retval = MPI_ERR_TAG;
703 *request = xbt_mallocator_get(smpi_global->request_mallocator);
704 (*request)->comm = comm;
705 (*request)->src = src;
706 (*request)->dst = dst;
707 (*request)->tag = tag;
708 (*request)->buf = buf;
709 (*request)->count = count;
710 (*request)->datatype = datatype;
715 int smpi_isend(smpi_mpi_request_t *request)
717 int retval = MPI_SUCCESS;
718 int rank = smpi_mpi_comm_rank_self(smpi_mpi_global->mpi_comm_world);
720 if (NULL != request) {
721 SIMIX_mutex_lock(smpi_global->pending_send_request_queues_mutexes[rank]);
722 xbt_fifo_push(smpi_global->pending_send_request_queues[rank], request);
723 SIMIX_mutex_unlock(smpi_global->pending_send_request_queues_mutexes[rank]);
726 if (SIMIX_process_is_suspended(smpi_global->sender_processes[rank])) {
727 SIMIX_process_resume(smpi_global->sender_processes[rank]);
733 int smpi_irecv(smpi_mpi_request_t *request)
735 int retval = MPI_SUCCESS;
736 int rank = smpi_mpi_comm_rank_self(smpi_mpi_global->mpi_comm_world);
738 if (NULL != request) {
739 SIMIX_mutex_lock(smpi_global->pending_recv_request_queues_mutexes[rank]);
740 xbt_fifo_push(smpi_global->pending_recv_request_queues[rank], request);
741 SIMIX_mutex_unlock(smpi_global->pending_recv_request_queues_mutexes[rank]);
744 if (SIMIX_process_is_suspended(smpi_global->receiver_processes[rank])) {
745 SIMIX_process_resume(smpi_global->receiver_processes[rank]);
751 void smpi_wait(smpi_mpi_request_t *request, smpi_mpi_status_t *status)
753 if (NULL != request) {
754 SIMIX_mutex_lock(request->mutex);
755 if (!request->completed) {
756 SIMIX_cond_wait(request->cond, request->mutex);
758 if (NULL != status) {
759 status->MPI_SOURCE = request->src;
761 SIMIX_mutex_unlock(request->mutex);
765 // FIXME: move into own file
766 int smpi_gettimeofday(struct timeval *tv, struct timezone *tz)
774 now = SIMIX_get_clock();
776 tv->tv_usec = ((now - (double)tv->tv_sec) * 1000000.0);
782 unsigned int smpi_sleep(unsigned int seconds)
787 smx_action_t sleep_action;
790 host = SIMIX_host_self();
791 sleep_action = SIMIX_action_sleep(host, seconds);
792 mutex = SIMIX_mutex_init();
793 cond = SIMIX_cond_init();
795 SIMIX_mutex_lock(mutex);
796 SIMIX_register_action_to_condition(sleep_action, cond);
797 SIMIX_cond_wait(cond, mutex);
798 //SIMIX_unregister_action_to_condition(sleep_action, cond);
799 SIMIX_mutex_unlock(mutex);
801 SIMIX_mutex_destroy(mutex);
802 SIMIX_cond_destroy(cond);
804 // FIXME: check for success/failure?
810 void smpi_exit(int status)
813 SIMIX_mutex_lock(smpi_global->running_hosts_count_mutex);
814 smpi_global->running_hosts_count--;
815 SIMIX_mutex_unlock(smpi_global->running_hosts_count_mutex);
816 SIMIX_process_kill(SIMIX_process_self());