Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
bf24c2107b37bbcfc2568cb19a522e92c4be6e56
[simgrid.git] / src / bindings / ruby / rb_msg_task.c
1 /* Task-related bindings to ruby  */
2
3 /* Copyright (c) 2010. The SimGrid Team.
4  * All rights reserved.                                                     */
5
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. */
8
9
10 #include "bindings/ruby_bindings.h"
11
12 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(ruby);
13
14 // Free Method
15 void rb_task_free(m_task_t tk)
16 {
17   //MSG_task_destroy(tk); ( This cause a bug !! is it really necessary ?!! not really sure !! )
18 }
19
20 // New Method
21 VALUE rb_task_new(VALUE class, VALUE name, VALUE comp_size,
22                   VALUE comm_size)
23 {
24   m_task_t task = MSG_task_create(RSTRING_PTR(name), NUM2INT(comp_size),
25                                   NUM2INT(comm_size), NULL);
26   rb_data_t data = malloc(sizeof(s_ruby_data_t));
27   data->ruby_task = NULL;
28   data->user_data = NULL;
29   MSG_task_set_data(task, (void *) data);
30   // Wrap m_task_t to a Ruby Value
31   return Data_Wrap_Struct(class, 0, rb_task_free, task);
32 }
33
34 //Get Computation Size
35 VALUE rb_task_comp(VALUE class, VALUE task)
36 {
37   double size;
38   m_task_t tk;
39   // Wrap Ruby Value to m_task_t struct
40   Data_Get_Struct(task, s_m_task_t, tk);
41   size = MSG_task_get_compute_duration(tk);
42   return rb_float_new(size);
43 }
44
45 //Get Name
46 VALUE rb_task_name(VALUE class, VALUE task)
47 {
48
49   // Wrap Ruby Value to m_task_t struct
50   m_task_t tk;
51   Data_Get_Struct(task, s_m_task_t, tk);
52   return rb_str_new2(MSG_task_get_name(tk));
53 }
54
55 // Execute Task
56 VALUE rb_task_execute(VALUE class, VALUE task)
57 {
58
59   // Wrap Ruby Value to m_task_t struct
60   m_task_t tk;
61   Data_Get_Struct(task, s_m_task_t, tk);
62   return INT2NUM(MSG_task_execute(tk));
63 }
64
65 // Sending Task
66 void rb_task_send(VALUE class, VALUE task, VALUE mailbox)
67 {
68
69   MSG_error_t rv;
70   rb_data_t data;
71   // Wrap Ruby Value to m_task_t struct
72   m_task_t tk;
73   Data_Get_Struct(task, s_m_task_t, tk);
74   data = MSG_task_get_data(tk);
75   data->ruby_task = (void *) task;
76   MSG_task_set_data(tk, (void *) data);
77   XBT_DEBUG("Sending task %p", tk);
78   rv = MSG_task_send(tk, RSTRING_PTR(mailbox));
79   if (rv != MSG_OK) {
80     if (rv == MSG_TRANSFER_FAILURE)
81       rb_raise(rb_eRuntimeError, "Transfer failure while Sending");
82     else if (rv == MSG_HOST_FAILURE)
83       rb_raise(rb_eRuntimeError, "Host failure while Sending");
84     else if (rv == MSG_TIMEOUT)
85       rb_raise(rb_eRuntimeError, "Timeout failure while Sending");
86     else
87       rb_raise(rb_eRuntimeError, "MSG_task_send failed");
88   }
89 }
90
91 // Receiving Task (returns a Task)
92 VALUE rb_task_receive(VALUE class, VALUE mailbox)
93 {
94   // We must put the location where we copy the task
95   // pointer to on the heap, because the stack may move
96   // during the context switches (damn ruby internals)
97   m_task_t *ptask = malloc(sizeof(m_task_t));
98   m_task_t task;
99   *ptask = NULL;
100   rb_data_t data = NULL;
101   XBT_DEBUG("Receiving a task on mailbox '%s', store it into %p",
102          RSTRING_PTR(mailbox), &task);
103   MSG_task_receive(ptask, RSTRING_PTR(mailbox));
104   task = *ptask;
105   free(ptask);
106   data = MSG_task_get_data(task);
107   if (data == NULL)
108     printf("Empty task while receving");
109   return (VALUE) data->ruby_task;
110 }
111
112 // It Return a Native Process ( m_process_t )
113 VALUE rb_task_sender(VALUE class, VALUE task)
114 {
115   m_task_t tk;
116   Data_Get_Struct(task, s_m_task_t, tk);
117   THROW_UNIMPLEMENTED;
118   return 0;                     //MSG_task_get_sender(tk);
119 }
120
121 // it return a Host 
122 VALUE rb_task_source(VALUE class, VALUE task)
123 {
124   m_task_t tk;
125   Data_Get_Struct(task, s_m_task_t, tk);
126
127   m_host_t host = MSG_task_get_source(tk);
128   if (!host->data) {
129     rb_raise(rb_eRuntimeError, "MSG_task_get_source() failed");
130     return Qnil;
131   }
132   THROW_UNIMPLEMENTED;
133   return 0;                     //host;
134 }
135
136 // Return Boolean
137 VALUE rb_task_listen(VALUE class, VALUE task, VALUE alias)
138 {
139   m_task_t tk;
140   const char *p_alias;
141   int rv;
142
143   Data_Get_Struct(task, s_m_task_t, tk);
144   p_alias = RSTRING_PTR(alias);
145
146   rv = MSG_task_listen(p_alias);
147
148   if (rv)
149     return Qtrue;
150
151   return Qfalse;
152 }
153
154 // return Boolean
155 VALUE rb_task_listen_host(VALUE class, VALUE task, VALUE alias, VALUE host)
156 {
157
158   m_task_t tk;
159   m_host_t ht;
160   const char *p_alias;
161   int rv;
162
163   Data_Get_Struct(task, s_m_task_t, tk);
164   Data_Get_Struct(host, s_m_host_t, ht);
165   p_alias = RSTRING_PTR(alias);
166   rv = MSG_task_listen_from_host(p_alias, ht);
167   if (rv)
168     return Qtrue;
169   return Qfalse;
170 }
171
172
173 // Set Priority
174 void rb_task_set_priority(VALUE class, VALUE task, VALUE priority)
175 {
176
177   m_task_t tk;
178   double prt = NUM2DBL(priority);
179   Data_Get_Struct(task, s_m_task_t, tk);
180   MSG_task_set_priority(tk, prt);
181
182 }
183
184 // Cancel
185 void rb_task_cancel(VALUE class, VALUE task)
186 {
187   m_task_t tk;
188   Data_Get_Struct(task, s_m_task_t, tk);
189   MSG_task_cancel(tk);
190
191 }
192
193 void rb_task_set_data(VALUE class, VALUE task, VALUE data)
194 {
195   m_task_t tk;
196   rb_data_t rb_data;
197   Data_Get_Struct(task, s_m_task_t, tk);
198   rb_data = MSG_task_get_data(tk);
199   rb_data->user_data = (void *) data;
200   MSG_task_set_data(tk, (void *) rb_data);
201
202 }
203
204 VALUE rb_task_get_data(VALUE class, VALUE task)
205 {
206   m_task_t tk;
207   Data_Get_Struct(task, s_m_task_t, tk);
208   rb_data_t rb_data = MSG_task_get_data(tk);
209   if (!rb_data->user_data)
210     XBT_ERROR("the task %s contain no user data", MSG_task_get_name(tk));
211
212   return (VALUE) rb_data->user_data;
213 }
214
215 VALUE rb_task_has_data(VALUE class, VALUE task)
216 {
217   m_task_t tk;
218   Data_Get_Struct(task, s_m_task_t, tk);
219   rb_data_t rb_data = MSG_task_get_data(tk);
220   if (!rb_data->user_data)
221     return Qfalse;
222   return Qtrue;
223 }