From 3fed8dfc00286ce4df0341262e278298df401b78 Mon Sep 17 00:00:00 2001 From: coldpeace Date: Fri, 26 Mar 2010 14:34:29 +0000 Subject: [PATCH] allowing to send tasks containing "ruby task" value plus "the user data" git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@7386 48e7efb5-ca39-0410-a469-dd3cf9ba447f --- src/bindings/ruby/MasterSlaveData.rb | 89 ++++++++++++++++++++++++++++ src/bindings/ruby/PingPong.rb | 17 ++---- src/bindings/ruby/rb_msg_task.c | 51 ++++++++++++++-- src/bindings/ruby/simgrid.rb | 6 +- src/bindings/ruby/simgrid_ruby.c | 3 + src/bindings/ruby_bindings.h | 10 +++- 6 files changed, 157 insertions(+), 19 deletions(-) create mode 100644 src/bindings/ruby/MasterSlaveData.rb diff --git a/src/bindings/ruby/MasterSlaveData.rb b/src/bindings/ruby/MasterSlaveData.rb new file mode 100644 index 0000000000..8d4901aa5c --- /dev/null +++ b/src/bindings/ruby/MasterSlaveData.rb @@ -0,0 +1,89 @@ +# Debug it with this command: +# make -C ../.. && valgrind ruby MasterSlave.rb --log=ruby.thres:debug 2>&1 | less + +require 'simgrid' + +include MSG + +################################################# +# Class Master +################################################# + +class Master < MSG::Process + # main : that function that will be executed when running simulation + + def main(args) # args is an array containing arguments for function master + size = args.size + for i in 0..size-1 + MSG::info("args["+String(i)+"]="+args[i]) + end + + raise "Master needs 3 arguments" if size < 3 + numberOfTask = Integer(args[0]) + taskComputeSize = Float(args[1]) + taskCommunicationSize = Float(args[2]) + slaveCount = Integer(args[3]) + + # Creates and sends the tasks + for i in 0..numberOfTask-1 + task = MSG::Task.new("Task_"+ i.to_s, taskComputeSize , taskCommunicationSize); + task.setData("a messgae..."); + mailbox = "slave " + (i%slaveCount).to_s + MSG::debug("Master Sending "+ task.name + " to " + mailbox + " with Comput Size " + + task.compSize.to_s) + task.send(mailbox) + MSG::debug("Master Done Sending " + task.name + " to " + mailbox) + end + + # Sending Finalize MSG::Tasks + #MSG::info("Master: All "+numberOfTask+" tasks have been dispatched. Let's tell everybody the computation is over.") + MSG::info("Master: All tasks have been dispatched. Let's tell everybody the computation is over.") + for i in 0..slaveCount-1 + mailbox = "slave " + i.to_s + finalize_task = Task.new("finalize",0,0) + finalize_task.send(mailbox) + end + MSG::info("Master : Everything's Done") + end +end + +################################################# +# Class Slave +################################################# +class Slave < MSG::Process + + def main(args) + mailbox = "slave " + args[0] + for i in 0..args.size-1 + MSG::debug("args["+String(i)+"]="+args[i]) + end + + while true + task = MSG::Task.receive(mailbox) + data = task.data if (task.hasData) + MSG::info("The data inside was :" + data) + if (task.name == "finalize") + break + end + task.execute + MSG::debug("Slave '" + mailbox + "' done executing task "+ task.name + ".") + end + MSG::info("I'm done, see you") + end +end + +################################################# +# main chunck +################################################# + +if (ARGV.length == 2) + MSG.createEnvironment(ARGV[0]) + MSG.deployApplication(ARGV[1]) +else + MSG.createEnvironment("platform.xml") + MSG.deployApplication("deploy.xml") +end + +MSG.run +puts "Simulation time : " + MSG.getClock .to_s +MSG.exit diff --git a/src/bindings/ruby/PingPong.rb b/src/bindings/ruby/PingPong.rb index 2281b1d4e3..57adbc42f3 100644 --- a/src/bindings/ruby/PingPong.rb +++ b/src/bindings/ruby/PingPong.rb @@ -8,14 +8,12 @@ include MSG class PingPongTask < MSG::Task - def initialize(*args) + puts "Here is the ping pong initializer" #Has No Role, Since Its The Task Class ( Created from C ) tht will be called , # and any instruction here will be ignored end - - end #################### @@ -38,16 +36,17 @@ class Sender < MSG::Process end for i in 0..hostCount-1 - time = MSG.getClock.to_s # to send as a data >> must be a string + time = MSG.getClock MSG::info("sender time :"+time.to_s) task = PingPongTask.new("PingTask",10000,2000) + MSG::info("task created :" + task.name); task.setData(time) p "mailboxe >>> "+ mailboxes[i] task.send(mailboxes[i]) end - MSG::info("GoodBye !!!") - + MSG::info("GoodBye !!!") + end end @@ -59,17 +58,15 @@ class Sender < MSG::Process class Receiver < MSG::Process def main(args) - MSG::info("Hello from Receiver") time = MSG.getClock MSG::info("Try to get a task") host = MSG::Host.getHostProcess(self) task = PingPongTask.receive(host.name) p "task name recevied : "+ task.name - p "data in the task :" + task.data timeGot = MSG.getClock - timeSent= task.data MSG::info("Got at time: "+timeGot.to_s) + timeSent = task.data MSG::info("Was sent at time "+timeSent.to_s) communicationTime = timeGot - time MSG::info("Communication Time: "+communicationTime.to_s) @@ -77,7 +74,6 @@ class Receiver < MSG::Process MSG::info("GoodBye !!!") end - end ################################################# @@ -90,7 +86,6 @@ if (ARGV.length == 2) else MSG.createEnvironment("ping_pong_platform.xml") MSG.deployApplication("ping_pong_deployment.xml") - end MSG.run diff --git a/src/bindings/ruby/rb_msg_task.c b/src/bindings/ruby/rb_msg_task.c index 855270f205..c6b734aa8e 100644 --- a/src/bindings/ruby/rb_msg_task.c +++ b/src/bindings/ruby/rb_msg_task.c @@ -18,9 +18,12 @@ void rb_task_free(m_task_t tk) { // New Method VALUE rb_task_new(VALUE class, VALUE name,VALUE comp_size,VALUE comm_size) { m_task_t task = MSG_task_create(RSTRING(name)->ptr,NUM2INT(comp_size),NUM2INT(comm_size),NULL); + rb_data_t data = malloc(sizeof(s_ruby_data_t)); + data->ruby_task = NULL; + data->user_data = NULL; + MSG_task_set_data(task,(void*)data); // Wrap m_task_t to a Ruby Value return Data_Wrap_Struct(class, 0, rb_task_free, task); - } //Get Computation Size @@ -55,10 +58,13 @@ VALUE rb_task_execute(VALUE class,VALUE task) { void rb_task_send(VALUE class,VALUE task,VALUE mailbox) { MSG_error_t rv; + rb_data_t data; // Wrap Ruby Value to m_task_t struct m_task_t tk; Data_Get_Struct(task, s_m_task_t, tk); - MSG_task_set_data(tk,(void*)task); + data = MSG_task_get_data(tk); + data->ruby_task =(void*)task; + MSG_task_set_data(tk,(void*)data); DEBUG1("Sending task %p",tk); rv = MSG_task_send(tk,RSTRING(mailbox)->ptr); if(rv != MSG_OK) @@ -82,11 +88,14 @@ VALUE rb_task_receive(VALUE class, VALUE mailbox) { m_task_t *ptask = malloc(sizeof(m_task_t)); m_task_t task; *ptask = NULL; + rb_data_t data =NULL; DEBUG2("Receiving a task on mailbox '%s', store it into %p",RSTRING(mailbox)->ptr,&task); MSG_task_receive(ptask,RSTRING(mailbox)->ptr); task = *ptask; free(ptask); - return (VALUE)MSG_task_get_data(task); + data = MSG_task_get_data(task); + if(data==NULL) printf("Empty task while receving"); + return (VALUE)data->ruby_task; } // It Return a Native Process ( m_process_t ) @@ -138,9 +147,7 @@ VALUE rb_task_listen_host(VALUE class,VALUE task,VALUE alias,VALUE host) { Data_Get_Struct(task,s_m_task_t,tk); Data_Get_Struct(host,s_m_host_t,ht); p_alias = RSTRING(alias)->ptr; - rv = MSG_task_listen_from_host(p_alias,ht); - if (rv) return Qtrue; return Qfalse; @@ -164,6 +171,38 @@ void rb_task_cancel(VALUE class,VALUE task) m_task_t tk; Data_Get_Struct(task,s_m_task_t,tk); MSG_task_cancel(tk); - + +} + +void rb_task_set_data(VALUE class,VALUE task,VALUE data) +{ + m_task_t tk; + rb_data_t rb_data; + Data_Get_Struct(task,s_m_task_t,tk); + rb_data = MSG_task_get_data(tk); + rb_data->user_data = (void*)data; + MSG_task_set_data(tk,(void*)rb_data); + +} + +VALUE rb_task_get_data(VALUE class,VALUE task) +{ + m_task_t tk; + Data_Get_Struct(task,s_m_task_t,tk); + rb_data_t rb_data = MSG_task_get_data(tk); + if(!rb_data->user_data) + ERROR1("the task %s contain no user data",MSG_task_get_name(tk)); + + return (VALUE)rb_data->user_data; +} + +VALUE rb_task_has_data(VALUE class,VALUE task) +{ + m_task_t tk; + Data_Get_Struct(task,s_m_task_t,tk); + rb_data_t rb_data = MSG_task_get_data(tk); + if(!rb_data->user_data) + return Qfalse; + return Qtrue; } diff --git a/src/bindings/ruby/simgrid.rb b/src/bindings/ruby/simgrid.rb index 1fcab4facc..a140f82fc9 100644 --- a/src/bindings/ruby/simgrid.rb +++ b/src/bindings/ruby/simgrid.rb @@ -133,7 +133,7 @@ end class MSG::Task < MSG::RbTask def initialize(*args) - super() + super() #no effect end def setData(value) @@ -184,6 +184,10 @@ class MSG::Task < MSG::RbTask super(self) end + def hasData() + super(self) + end + end #################################################### # Host Extend from the native Class RbHost diff --git a/src/bindings/ruby/simgrid_ruby.c b/src/bindings/ruby/simgrid_ruby.c index 9e09a1853b..82e6dd0025 100644 --- a/src/bindings/ruby/simgrid_ruby.c +++ b/src/bindings/ruby/simgrid_ruby.c @@ -180,6 +180,9 @@ void Init_simgrid_ruby() { rb_define_module_function(rb_task,"listenFromHost",(rb_meth)rb_task_listen_host,3); rb_define_module_function(rb_task,"setPriority",(rb_meth)rb_task_set_priority,2); rb_define_module_function(rb_task,"cancel",(rb_meth)rb_task_cancel,1); + rb_define_module_function(rb_task,"hasData",(rb_meth)rb_task_has_data,1); + rb_define_module_function(rb_task,"setData",(rb_meth)rb_task_set_data,2); + rb_define_module_function(rb_task,"data",(rb_meth)rb_task_get_data,1); //Host Methods rb_define_module_function(rb_host,"getByName",(rb_meth)rb_host_get_by_name,1); diff --git a/src/bindings/ruby_bindings.h b/src/bindings/ruby_bindings.h index 418e1a392f..f004419b42 100644 --- a/src/bindings/ruby_bindings.h +++ b/src/bindings/ruby_bindings.h @@ -102,8 +102,13 @@ VALUE rb_host_process(VALUE Class,VALUE process); VALUE rb_host_get_all_hosts(VALUE Class); /* Functions related to tasks */ + +typedef struct ruby_data { + void *ruby_task; // Pointer to send the ruby_task + void *user_data; // Pointer on the user data +}s_ruby_data_t,*rb_data_t; + void rb_task_free(m_task_t tk); -// New Method >>> Data NULL VALUE rb_task_new(VALUE Class, VALUE name,VALUE comp_size,VALUE comm_size); VALUE rb_task_comp(VALUE Class,VALUE task); // Get Computation Size VALUE rb_task_name(VALUE Class,VALUE task); @@ -117,6 +122,9 @@ VALUE rb_task_listen(VALUE Class,VALUE task,VALUE alias); //Listen From Alias (= VALUE rb_task_listen_host(VALUE Class,VALUE task,VALUE alias,VALUE host); //Listen from Host void rb_task_set_priority(VALUE Class,VALUE task,VALUE priority); // Set Priority void rb_task_cancel(VALUE Class,VALUE task); // Cancel +VALUE rb_task_has_data(VALUE Class,VALUE task); // check if the task contains a data +VALUE rb_task_get_data(VALUE Class,VALUE task); // get data +void rb_task_set_data(VALUE Class,VALUE task,VALUE data); // set data /* Upcalls for the application handler */ void rb_application_handler_on_start_document(void); -- 2.20.1