3 /* Copyright (c) 2008, 2009, 2010. The SimGrid Team.
4 * All rights reserved. */
6 /* This program is free software; you can redistribute it and/or modify it
7 * under the terms of the license (GNU LGPL) which comes with this package. */
10 #include "msg/private.h"
12 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(msg_mailbox, msg,
13 "Logging specific to MSG (mailbox)");
15 static xbt_dict_t msg_mailboxes = NULL;
17 void MSG_mailbox_mod_init(void)
19 msg_mailboxes = xbt_dict_new();
22 void MSG_mailbox_mod_exit(void)
24 xbt_dict_free(&msg_mailboxes);
27 msg_mailbox_t MSG_mailbox_create(const char *alias)
29 msg_mailbox_t mailbox = xbt_new0(s_msg_mailbox_t, 1);
32 mailbox->alias = alias ? xbt_strdup(alias) : NULL;
33 mailbox->rdv = SIMIX_rdv_create(alias);
38 msg_mailbox_t MSG_mailbox_new(const char *alias)
40 msg_mailbox_t mailbox = MSG_mailbox_create(alias);
42 /* add the mbox in the dictionary */
43 xbt_dict_set(msg_mailboxes, alias, mailbox, MSG_mailbox_free);
48 void MSG_mailbox_free(void *mailbox)
50 msg_mailbox_t _mailbox = (msg_mailbox_t) mailbox;
52 free(_mailbox->alias);
53 SIMIX_rdv_destroy(_mailbox->rdv);
58 smx_cond_t MSG_mailbox_get_cond(msg_mailbox_t mailbox)
63 int MSG_mailbox_is_empty(msg_mailbox_t mailbox)
65 return (NULL == SIMIX_rdv_get_head(mailbox->rdv));
68 m_task_t MSG_mailbox_get_head(msg_mailbox_t mailbox)
70 smx_comm_t comm = SIMIX_rdv_get_head(mailbox->rdv);
75 return (m_task_t)SIMIX_communication_get_data(comm);
79 MSG_mailbox_get_count_host_waiting_tasks(msg_mailbox_t mailbox, m_host_t host)
81 return SIMIX_rdv_get_count_waiting_comm (mailbox->rdv, host->simdata->smx_host);
84 void MSG_mailbox_set_cond(msg_mailbox_t mailbox, smx_cond_t cond)
89 const char *MSG_mailbox_get_alias(msg_mailbox_t mailbox)
91 return mailbox->alias;
94 msg_mailbox_t MSG_mailbox_get_by_alias(const char *alias)
97 msg_mailbox_t mailbox = xbt_dict_get_or_null(msg_mailboxes, alias);
100 mailbox = MSG_mailbox_new(alias);
105 msg_mailbox_t MSG_mailbox_get_by_channel(m_host_t host, m_channel_t channel)
107 xbt_assert0((host != NULL), "Invalid host");
108 xbt_assert1((channel >= 0)
109 && (channel < msg_global->max_channel), "Invalid channel %d",
112 return host->simdata->mailboxes[(size_t) channel];
116 MSG_mailbox_get_task_ext(msg_mailbox_t mailbox, m_task_t *task, m_host_t host,
120 MSG_error_t ret = MSG_OK;
123 double start_time = 0;
125 /* We no longer support getting a task from a specific host */
126 if (host) THROW_UNIMPLEMENTED;
130 TRACE_msg_task_get_start ();
131 start_time = MSG_get_clock();
134 memset(&comm,0,sizeof(comm));
136 /* Kept for compatibility with older implementation */
137 xbt_assert1(!MSG_mailbox_get_cond(mailbox),
138 "A process is already blocked on this channel %s",
139 MSG_mailbox_get_alias(mailbox));
142 xbt_assert0(task, "Null pointer for the task storage");
145 CRITICAL0("MSG_task_get() was asked to write in a non empty task struct.");
147 /* Try to receive it by calling SIMIX network layer */
149 SIMIX_network_recv(mailbox->rdv, timeout, task, NULL, &comm);
150 //INFO2("Got task %s from %s",(*task)->name,mailbox->alias);
151 (*task)->simdata->refcount--;
156 ret = MSG_HOST_FAILURE;
159 ret = MSG_TRANSFER_FAILURE;
165 xbt_die(bprintf("Unhandled SIMIX network exception: %s",e.msg));
170 if (ret != MSG_HOST_FAILURE &&
171 ret != MSG_TRANSFER_FAILURE &&
174 TRACE_msg_task_get_end (start_time, *task);
181 MSG_mailbox_put_with_timeout(msg_mailbox_t mailbox, m_task_t task,
185 MSG_error_t ret = MSG_OK;
186 simdata_task_t t_simdata = NULL;
187 m_process_t process = MSG_process_self();
194 call_end = TRACE_msg_task_put_start (task); //must be after CHECK_HOST()
198 /* Prepare the task to send */
199 t_simdata = task->simdata;
200 t_simdata->sender = process;
201 t_simdata->source = MSG_host_self();
203 xbt_assert0(t_simdata->refcount == 1,
204 "This task is still being used somewhere else. You cannot send it now. Go fix your code!");
206 t_simdata->refcount++;
207 msg_global->sent_msg++;
209 process->simdata->waiting_task = task;
211 /* Try to send it by calling SIMIX network layer */
213 /* Kept for semantical compatibility with older implementation */
215 SIMIX_cond_signal(mailbox->cond);
217 SIMIX_network_send(mailbox->rdv, t_simdata->message_size, t_simdata->rate,
218 timeout, task, sizeof(void*), &t_simdata->comm, task);
224 ret = MSG_HOST_FAILURE;
227 ret = MSG_TRANSFER_FAILURE;
233 xbt_die(bprintf("Unhandled SIMIX network exception: %s",e.msg));
237 /* Decrement the refcount only on failure */
238 t_simdata->refcount--;
241 process->simdata->waiting_task = NULL;
243 if (call_end) TRACE_msg_task_put_end ();