From: mquinson Date: Tue, 9 Feb 2010 17:21:34 +0000 (+0000) Subject: First version of ruby bindings by Medhi X-Git-Tag: SVN~663 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/b37127a6689ffbb75a19fa61f9cf0c2253960d4d First version of ruby bindings by Medhi git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@7071 48e7efb5-ca39-0410-a469-dd3cf9ba447f --- diff --git a/src/bindings/ruby/ApplicationHandler.rb b/src/bindings/ruby/ApplicationHandler.rb new file mode 100644 index 0000000000..0ac51da8d2 --- /dev/null +++ b/src/bindings/ruby/ApplicationHandler.rb @@ -0,0 +1,89 @@ +require 'ProcessFactory' + +$debug = true + +class ApplicationHandler + + @processFactory + +# Initialize + def initialize() + + end + + +# onStartDocument + def onStartDocument() + + @processFactory = ProcessFactory.new + + if ($debug) + puts "onStartDocument" + end + + + end + +# onBeginProcess + def onBeginProcess (hostName ,function) + + @processFactory.setProcessIdentity(hostName,function) + + if ($debug) + puts "onBeginProcess" + end + + end + +# onProperty + + def onProperty(id,value) + + @processFactory.setProperty(id,value) + + if ($debug) + puts "onProperty" + end + + end + +# RegisterProcessArg + + def onProcessArg(arg) + + @processFactory.registerProcessArg(arg) + + if ($debug) + puts "onProcessArg" + end + + end + +# OnEndProcess + + def onEndProcess() + + @processFactory.createProcess() + + if ($debug) + puts "onEndProcess" + end + + end + + + # onEndDocument + + def onEndDocument() +# Euh...Actually Nothin' to Do !! + + if($debug) + puts "onEndDocument" + end + end + + +# End Class + +end + diff --git a/src/bindings/ruby/Makefile b/src/bindings/ruby/Makefile new file mode 100644 index 0000000000..23389e4dd0 --- /dev/null +++ b/src/bindings/ruby/Makefile @@ -0,0 +1,157 @@ + +SHELL = /bin/sh + +#### Start of system configuration section. #### + +srcdir = . +topdir = /usr/lib/ruby/1.8/i486-linux +hdrdir = $(topdir) +VPATH = $(srcdir):$(topdir):$(hdrdir) +exec_prefix = $(prefix) +prefix = $(DESTDIR)/usr +sharedstatedir = $(prefix)/com +mandir = $(prefix)/share/man +psdir = $(docdir) +oldincludedir = $(DESTDIR)/usr/include +localedir = $(datarootdir)/locale +bindir = $(exec_prefix)/bin +libexecdir = $(prefix)/lib/ruby1.8 +sitedir = $(DESTDIR)/usr/local/lib/site_ruby +htmldir = $(docdir) +vendorarchdir = $(vendorlibdir)/$(sitearch) +includedir = $(prefix)/include +infodir = $(prefix)/share/info +vendorlibdir = $(vendordir)/$(ruby_version) +sysconfdir = $(DESTDIR)/etc +libdir = $(exec_prefix)/lib +sbindir = $(exec_prefix)/sbin +rubylibdir = $(libdir)/ruby/$(ruby_version) +docdir = $(datarootdir)/doc/$(PACKAGE) +dvidir = $(docdir) +vendordir = $(libdir)/ruby/vendor_ruby +datarootdir = $(prefix)/share +pdfdir = $(docdir) +archdir = $(rubylibdir)/$(arch) +sitearchdir = $(sitelibdir)/$(sitearch) +datadir = $(datarootdir) +localstatedir = $(DESTDIR)/var +sitelibdir = $(sitedir)/$(ruby_version) + +CC = gcc +LIBRUBY = $(LIBRUBY_SO) +LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a +LIBRUBYARG_SHARED = -l$(RUBY_SO_NAME) -lsimgrid +LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static + +RUBY_EXTCONF_H = +CFLAGS = -fPIC -fno-strict-aliasing -g -g -O2 -fPIC $(cflags) +INCFLAGS = -I. -I$(topdir) -I$(hdrdir) -I$(srcdir) +DEFS = -D_FILE_OFFSET_BITS=64 +CPPFLAGS = $(DEFS) $(cppflags) +CXXFLAGS = $(CFLAGS) +ldflags = -L. -Wl,-Bsymbolic-functions -rdynamic -Wl,-export-dynamic +dldflags = +archflag = +DLDFLAGS = $(ldflags) $(dldflags) $(archflag) +LDSHARED = $(CC) -shared +AR = ar +EXEEXT = + +RUBY_INSTALL_NAME = ruby1.8 +RUBY_SO_NAME = ruby1.8 +arch = i486-linux +sitearch = i486-linux +ruby_version = 1.8 +ruby = /usr/bin/ruby1.8 +RUBY = $(ruby) +RM = rm -f +MAKEDIRS = mkdir -p +INSTALL = /usr/bin/install -c +INSTALL_PROG = $(INSTALL) -m 0755 +INSTALL_DATA = $(INSTALL) -m 644 +COPY = cp + +#### End of system configuration section. #### + +preload = + +libpath = . $(libdir) +LIBPATH = -L. -L$(libdir) +DEFFILE = + +CLEANFILES = mkmf.log +DISTCLEANFILES = + +extout = +extout_prefix = +target_prefix = +LOCAL_LIBS = +LIBS = $(LIBRUBYARG_SHARED) -lpthread -lrt -ldl -lcrypt -lm -lc +SRCS = rb_application_handler.c rb_msg_task.c rb_msg_process.c rb_msg_host.c rb_msg.c +OBJS = rb_application_handler.o rb_msg_task.o rb_msg_process.o rb_msg_host.o rb_msg.o +TARGET = msg +DLLIB = $(TARGET).so +EXTSTATIC = +STATIC_LIB = + +BINDIR = $(bindir) +RUBYCOMMONDIR = $(sitedir)$(target_prefix) +RUBYLIBDIR = $(sitelibdir)$(target_prefix) +RUBYARCHDIR = $(sitearchdir)$(target_prefix) + +TARGET_SO = $(DLLIB) +CLEANLIBS = $(TARGET).so $(TARGET).il? $(TARGET).tds $(TARGET).map +CLEANOBJS = *.o *.a *.s[ol] *.pdb *.exp *.bak + +all: $(DLLIB) +static: $(STATIC_LIB) + +clean: + @-$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) + +distclean: clean + @-$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log + @-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES) + +realclean: distclean +install: install-so install-rb + +install-so: $(RUBYARCHDIR) +install-so: $(RUBYARCHDIR)/$(DLLIB) +$(RUBYARCHDIR)/$(DLLIB): $(DLLIB) + $(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR) +install-rb: pre-install-rb install-rb-default +install-rb-default: pre-install-rb-default +pre-install-rb: Makefile +pre-install-rb-default: Makefile +$(RUBYARCHDIR): + $(MAKEDIRS) $@ + +site-install: site-install-so site-install-rb +site-install-so: install-so +site-install-rb: install-rb + +.SUFFIXES: .c .m .cc .cxx .cpp .C .o + +.cc.o: + $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $< + +.cxx.o: + $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $< + +.cpp.o: + $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $< + +.C.o: + $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $< + +.c.o: + $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) -c $< + +$(DLLIB): $(OBJS) Makefile + @-$(RM) $@ + $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS) + + + +$(OBJS): ruby.h defines.h diff --git a/src/bindings/ruby/Master.rb b/src/bindings/ruby/Master.rb new file mode 100644 index 0000000000..f96c5b21f4 --- /dev/null +++ b/src/bindings/ruby/Master.rb @@ -0,0 +1,63 @@ +require 'msg' +require 'RubyProcess' + +include MSG + +class Master < RbProcess + + + + + + def initialize(*args) + + super() + channel = 0 + puts "Hey ..from Master"#info("Hey") + + slaves = Array.new() + + size = args.size + + puts "Args = " + size + + for i in 0..size-1 + puts "argv :" + args[1] + end + + raise "Master needs 3 arguments" if size < 3 + + numberOfTask = args[0] #convert to int + taskComputeSize = args[1] #convert to double + taskCommunicationSize = args[2] #convert to double + slaveCount = args[3] #convert to int + + +# todo = Array.new(numberOfTask) + + #Creating & Sending Task + for i in 0..numberOfTask + + task = RbTask.new("Task_" + i.to_s, taskComputeSize , taskCommunicationSize ); + s_alias = "slave " + (i%slaveCount).to_s + puts "Master Sending "+ RbTask.name(task) + " to " + s_alias + RbTask.send(task,s_alias) + puts "Master Done Sending " +RbTask.name(task) + " to " + s_alias + + end + + # Sending Finalize Tasks + puts "Master: All tasks have been dispatched. Let's tell everybody the computation is over." + for i in 0..slaveCount-1 + s_alias = "slave " + i.to_s + puts "Master Sending Finalize to " + s_alias + RbTask.send(RbTask.new("finalize",0,0),s_alias) + end + + puts "Master : Everything's Done" + + end + +end + + diff --git a/src/bindings/ruby/MasterSlave.rb b/src/bindings/ruby/MasterSlave.rb new file mode 100644 index 0000000000..419f513c73 --- /dev/null +++ b/src/bindings/ruby/MasterSlave.rb @@ -0,0 +1,79 @@ +require 'msg' +require 'RubyProcess' + +def Master(*args) + + puts "Hey ..from Master"#info("Hey") + + slaves = Array.new() + + size = args.size + + puts "Args = " + size + + for i in 0..size-1 + puts "argv :" + args[1] + end + + raise "Master needs 3 arguments" if size < 3 + + numberOfTask = args[0] #convert to int + taskComputeSize = args[1] #convert to double + taskCommunicationSize = args[2] #convert to double + slaveCount = args[3] #convert to int + + +# todo = Array.new(numberOfTask) + + #Creating & Sending Task + for i in 0..numberOfTask + + task = RbTask.new("Task_" + i.to_s, taskComputeSize , taskCommunicationSize ); + s_alias = "slave " + (i%slaveCount).to_s + puts "Master Sending "+ RbTask.name(task) + " to " + s_alias + RbTask.send(task,s_alias) + puts "Master Done Sending " +RbTask.name(task) + " to " + s_alias + + end + + # Sending Finalize Tasks + puts "Master: All tasks have been dispatched. Let's tell everybody the computation is over." + for i in 0..slaveCount-1 + s_alias = "slave " + i.to_s + puts "Master Sending Finalize to " + s_alias + RbTask.send(RbTask.new("finalize",0,0),s_alias) + end + + puts "Master : Everything's Done" + + + +end + + +def Slave(*args) + + puts "Hello From Slave" + s_mailbox = "slave" + args[0] + + + while true + + task = RbTask.recieve(s_mailbox) + + task_name = RbTask.name(task) + + if ( task_name == "finalize" ) + puts "Slave" + s_mailbox + "got finalize msg" + break + end + + puts "Slave " + s_mailbox + "Processing" + RbTask.name(task) + RbTask.execute(task) + + end + + puts "Slave " + s_mailbox + "I'm Done , See You !!" + + +end \ No newline at end of file diff --git a/src/bindings/ruby/ProcessFactory.rb b/src/bindings/ruby/ProcessFactory.rb new file mode 100644 index 0000000000..3201ecf608 --- /dev/null +++ b/src/bindings/ruby/ProcessFactory.rb @@ -0,0 +1,90 @@ +require 'RubyProcess' +require 'RubyHost' +class ProcessFactory + +# Attributes + attr_accessor :args, :proprieties, :hostName, :function + + +# Initlialize + def initialize() + + @args = Array.new + @proprieties = Hash.new + @hostName = nil + @function = nil + + end + +# setProcessIdentity + + def setProcessIdentity( hostName , function) + @hostName = hostName + @function = function + + if !args.empty? + args.clear + end + + if !proprieties.empty? + proprieties.clear + end + + + end + +# RegisterProcess + + def registerProcessArg( arg ) + + args.push(arg) + + end + +# CreateProcess + + def createProcess() + + + + process = RbProcess.new() + + + + process.name = @function + + + process.id = process.nextId() # This increment Automaticly The Static ProcessNextId for The Class RbProcess + + + + + host = rbHost.getByName(@hostName) + + Process.createProcess(process,host) + + size = @args.size + + for i in 0..size-1 + + process.pargs.push(@args[i]) + + end + + process.proprieties = @proprieties + + @proprieties = Hash.new + + end + + +# SetProperty + + def setProperty( id , value ) + + @proprieties[id] = value + + end + +# End Class + end \ No newline at end of file diff --git a/src/bindings/ruby/RubyHost.rb b/src/bindings/ruby/RubyHost.rb new file mode 100644 index 0000000000..e6149c4d15 --- /dev/null +++ b/src/bindings/ruby/RubyHost.rb @@ -0,0 +1,19 @@ +require 'msg' +include MSG + +class RbHost < Host + + +# Attributes + attr_accessor :bind, :data + + +# Initialize + def initialize() + @bind = 0 + @data = nil + end + + + +end \ No newline at end of file diff --git a/src/bindings/ruby/RubyProcess.rb b/src/bindings/ruby/RubyProcess.rb new file mode 100644 index 0000000000..ed92544d0e --- /dev/null +++ b/src/bindings/ruby/RubyProcess.rb @@ -0,0 +1,300 @@ +require 'msg' +require 'Semaphore' +include MSG + +$debug = true # This is a Gloabl Variable Useful for Debbuging + + +class RbProcess < Thread + + + + + @@nextProcessId = 0 +# Attributes + attr_accessor :bind, :id, :proprieties, :name, + :pargs, :schedBegin, :schedEnd + + + +# Initialize + + + # Used in ApplicationHandler to Initialize it + + + + def initialize(*args) + + + argc = args.size + + + +# Default Init + if argc == 0 #>>> new() + super() { + + @id = 0 + @bind = 0 + @name = "" + @pargs = Array.new() + + init_var() + + + + if $debug + puts "Init Default Initialzer..." + end + +# Thread.pass #yield ?!! +# sleep # Sleep Forever ... To Keep Thread Alive ?!! + + } + end + + + # Initi with 2 arguments + + if argc == 2 # >>>(HostName,Name) Or (Host , Name) + super(){ + + + type = args[0].type() + + if ( type.to_s == "String") + + host = Host.getByName(args[0]) + + end + + if ( type.to_s == "MSG::Host") + host = args[0] + end + + + if $debug + puts host + end + + + + + raise "Process Name Cannot Be Null" if args[1].empty? + + @name = args[1] # First Arg + + if $debug + puts @name + end + + + @pargs = Array.new() # No Args[] Passed in Arguments + + @@nextProcessId += 1 + @id = @@nextProcessId + + init_var() + + createProcess(self,host) #TODO >> MSG::Process + if $debug + puts "Initilize with 2 args" + end + +# sleep # Keep The Thread Runin' + } + + + end + + +# Init with 3 arguments + + if argc == 3 #(hostName,Name,args[]) or # (Host,Name,args[]) + super(){ + + type = args[0].type() + + if( type.to_s == "String") +# host = Host.getByName(args[0]) + host ="Host.getByName(args[0])" + end + + if ( type.to_s == "MSG::Host" ) + host = args[0] + end + + if $debug + puts host + end + + + raise "Process Name Cannot Be Null" if args[0].empty? + + @name = args[1] + + type = args[2].type() + + raise "Third Argument Should be an Array" if type != "Array" + + @pargs = args[3] + + + @@nextProcessId +=1 + @id = @@nextProcessId + + init_var() + + createProcess(self,host) #TODO RubyMsg + + if $debug + puts "Initilize with 3 args" + end + +# sleep #keep the thread running + } + end + + end + + + # Init_var Called By Initialize + + + def init_var() + + + @proprieties = Hash.new() + # Process Synchronization Tools + @schedBegin = Semaphore.new(0) + @schedEnd = Semaphore.new(0) + + end + + + + +# NetxId + def nextId () + + @@nextProcessId +=1 + return @@nextProcessId + + end + + + + + + + if $debug + #Process List + def processList() + + Thread.list.each {|t| p t} + + end + end + + + #Get Own ID + + def getID() + + return @id + + end + + # set Id + + def setID(id) + + @id = id + + end + + #Get a Process ID + + def processID(process) + + return process.id + + end + + + #get Own Name + + def getName() + + return @name + + end + + #get a Process Name + + def processName(process) + + return process.name + + end + + #get Bind + def getBind() + + return @bind + + end + + #set Binds + def setBind(bind) + + @bind = bind + + end + + + + # Stop + + def unschedule() + + Thread.pass + + end + + + #C Simualateur Process Equivalent Management + # After Binding Ruby Process to C Process + +# pause + def pause() + + processSuspend(self) + + end + +# restart + def restart() + + processResume(self) + + end + +# isSuspended + def isSuspended() + + processIsSuspended(self) + + end + +# getHost + def getHost() + + processGetHost(self) + + end + +# The Rest of Methods !!! To be Continued ... + +end \ No newline at end of file diff --git a/src/bindings/ruby/RubySem.rb b/src/bindings/ruby/RubySem.rb new file mode 100644 index 0000000000..2860167511 --- /dev/null +++ b/src/bindings/ruby/RubySem.rb @@ -0,0 +1,52 @@ +class Sem + + + attr_accessor :permits, :mutex, :cv + + Thread.abort_on_exception = true + + + +# Initialize + def initialize ( permits ) + + @permits = permits + @mutex = Mutex.new + @cv = ConditionVariable.new + + end + + + +# Aquire + def acquire() + + if(!Thread.current.alive?) #Thread.interrupted in Java + raise "Exception : Thread Interrupted" + end + + mutex.synchronize { + + while @permits <= 0 + + @cv.wait(mutex) #or Thread.stop ???!! + + end + + @permits -=1 + } + + end + + + def release() + + mutex.synchronize { + + @permits +=1 + @cv.signal #Notify ??!! + + } + + +end \ No newline at end of file diff --git a/src/bindings/ruby/RubyTask.rb b/src/bindings/ruby/RubyTask.rb new file mode 100644 index 0000000000..5b0a3130cb --- /dev/null +++ b/src/bindings/ruby/RubyTask.rb @@ -0,0 +1,21 @@ +require 'msg' +include MSG + +class RbTask < Task + + +# Attributes + attr_accessor :bind + + +# Initialize + def initialize(name,comp_size,comm_size) +# @bind = 10 + super(name,comp_size,comm_size) + end + + + + + +end \ No newline at end of file diff --git a/src/bindings/ruby/RubyXML.rb b/src/bindings/ruby/RubyXML.rb new file mode 100644 index 0000000000..821b25fb39 --- /dev/null +++ b/src/bindings/ruby/RubyXML.rb @@ -0,0 +1,58 @@ +require 'rubygems' +require 'nokogiri' +require 'open-uri' + + + +class RubyXML + + attr_accessor :host, :function, :args, :file, :doc + + def initialize() + + @host = Array.new() + @function = Array.new() + @args = Array.new() + + end + +# Parse Application File + + def parseApplication(fileName) + @file = File.new(fileName); + @doc = Nokogiri::XML(@file) + index = 0 + for process in @doc.root.xpath("//process") + + @host[index] = process['host'] + @function[index] = process['function'] + @args[index] = Array.new() + arg_index = 0 + for arg in process.xpath("./argument") + + @args[index][arg_index] = arg['value'] + arg_index += 1 + end + index += 1 + end + + + + @file.close(); + end + +# Print All + def printAll() + +# puts @host.size + for i in 0..@host.size-1 + puts "> Host :" + @host[i] + puts ">> Function :" + @function[i] + for j in 0..@args[i].size-1 + puts ">>> Arguments :" + @args[i][j] + end + end + end +end + + diff --git a/src/bindings/ruby/Semaphore.rb b/src/bindings/ruby/Semaphore.rb new file mode 100644 index 0000000000..8da1c423bc --- /dev/null +++ b/src/bindings/ruby/Semaphore.rb @@ -0,0 +1,45 @@ +require 'thread' +class Semaphore + + + Thread.abort_on_exception = true + + attr_accessor :permits, :mutex, :cv + + + + def initialize ( permits ) + + + @permits = permits + @mutex = Mutex.new + @cv = ConditionVariable.new + + end + + + def acquire() + + raise "Interrupted Thread " if (!Thread.current.alive?) + @mutex.synchronize { + while @permits < 1 + @cv.wait(mutex) + end + @permits = @permits - 1 + } + end + + + def release() + @mutex.synchronize{ + @value = @value + 1 + @cv.signal + + } + + end + + + + +end \ No newline at end of file diff --git a/src/bindings/ruby/Slave.rb b/src/bindings/ruby/Slave.rb new file mode 100644 index 0000000000..3029590509 --- /dev/null +++ b/src/bindings/ruby/Slave.rb @@ -0,0 +1,41 @@ +require 'msg' +require 'RubyProcess' +require 'RubyTask' +include MSG + +class Slave < RbProcess + + def initialize(*args) + + + puts "Hello From Slave" + s_mailbox = "slave" + args[0] + + + while true + + task = RbTask.recieve(s_mailbox) + + task_name = RbTask.name(task) + + if ( task_name == "finalize" ) + puts "Slave" + s_mailbox + "got finalize msg" + break + end + + puts "Slave " + s_mailbox + "Processing" + RbTask.name(task) + RbTask.execute(task) + + end + + puts "Slave " + s_mailbox + "I'm Done , See You !!" + + + end + + + end + + + +# slave = Slave.new \ No newline at end of file diff --git a/src/bindings/ruby/client.rb b/src/bindings/ruby/client.rb new file mode 100644 index 0000000000..af5fad9f6b --- /dev/null +++ b/src/bindings/ruby/client.rb @@ -0,0 +1,83 @@ +require 'msg' +include MSG + + +array = Array.new() + +# puts array.empty? +array << "Peace!!" << "Hey" << "Euh..."<< "Hey2" << "Euh...2" + + +# array.clear +# puts array.empty? + +mehdi = "Hey...this is my name" + +hash = Hash.new + + +var = "name" + +hash[var] = mehdi + + +# puts hash["name"] + +array.push(mehdi) + + +# info("Hey...") +# puts array[0] + +array2 = array + +# puts array2[0] + +size = array2.size + + + + + + +task = Task.new('ninou',12,23) +#task2 =RbTask.new('task2') +# task = RbTask.new() +# host = Host.new("Brad") + + + #host2 = Host.new() +# task_2 = Task.new('task2',12,23) +# name1 = task_2.name() +# name2 = Task.name(task) +# size = Task.compSize(task) + name = Task.name(task) +# task.bind +number = 56 + +# process = RbProcess.new() +# name = process.name +puts name +# puts process.alive? +# Thread.stop +# process2 = RbProcess.new() +# process2.name = "Hope" + +# reader = RubyXML.new(); +# reader.parseApplication("application.xml") +# reader.printAll() + + + +# name2 = Task.test() +# puts name +# process2 = RbProcess.new() + + + + # puts (name) +# init(array) +# createEnvironment(name); +# Task.goodbye + + diff --git a/src/bindings/ruby/essai2.c b/src/bindings/ruby/essai2.c new file mode 100644 index 0000000000..18a35161da --- /dev/null +++ b/src/bindings/ruby/essai2.c @@ -0,0 +1,92 @@ +#include +#include +#include + + + + + +VALUE oProcess; + +void r_init() +{ + + ruby_init(); + ruby_init_loadpath(); + rb_require("RubyProcess.rb"); + oProcess = rb_funcall3(rb_const_get(rb_cObject, rb_intern("RbProcess")), rb_intern("new"), 0, 0); + +} + + +VALUE getID(VALUE current) +{ + + + + return rb_funcall(current,rb_intern("getID"),0); + + +} + +VALUE isAlive(VALUE current) +{ + + + + return rb_funcall(current,rb_intern("alive?"),0); + + +} + +void List(VALUE current) +{ + + rb_funcall(current,rb_intern("processList"),0); + +} + + +int main(int argc, char ** argv) +{ + + + + + r_init(); + VALUE test = isAlive(oProcess); + + if (TYPE(test) == T_TRUE) + printf("Aliiiive\n"); + + getID(oProcess); + List(oProcess); + + + + + //keep... + VALUE current = rb_thread_current(); + test = isAlive(current); + + if(TYPE(test) == T_TRUE) + printf("The Current Thread is Alive\n"); + + + + /*application_handler_on_start_document(); + application_handler_on_end_document(); + application_handler_on_begin_process(); + application_handler_property(); + application_handler_on_process_arg(); + + application_handler_on_end_process(); + + */ + +} + +// compile command : gcc -I/usr/lib/ruby/1.8/i486-linux essai2.c -o essai2 -lruby1.8 + +// gcc -o libProcess.so -I/usr/lib/ruby/1.8/i486-linux -lruby1.8 -lsimgrid -shared rb_msg_process.c + diff --git a/src/bindings/ruby/extconfig.rb b/src/bindings/ruby/extconfig.rb new file mode 100644 index 0000000000..026fe9061c --- /dev/null +++ b/src/bindings/ruby/extconfig.rb @@ -0,0 +1,4 @@ +require 'mkmf' +extension_name ='msg' +dir_config(extension_name) +create_makefile(extension_name) diff --git a/src/bindings/ruby/rb_application_handler.c b/src/bindings/ruby/rb_application_handler.c new file mode 100644 index 0000000000..8404a25cb4 --- /dev/null +++ b/src/bindings/ruby/rb_application_handler.c @@ -0,0 +1,81 @@ +#include "rb_application_handler.h" +#include "surf/surfxml_parse.h" +#include + +static void r_init() +{ + + ruby_init(); + ruby_init_loadpath(); + rb_require("ApplicationHandler.rb"); + +} + +static void application_handler_on_start_document(void) +{ + + r_init(); + //current One + current = rb_funcall3(rb_const_get(rb_cObject, rb_intern("ApplicationHandler")), rb_intern("new"), 0, 0); + rb_funcall(current,rb_intern("onStartDocument"),0); + + +} + +static void application_handler_on_end_document(void) +{ + + //r_init(); + rb_funcall(current,rb_intern("onEndDocument"),0); + +} + +static void application_handler_on_begin_process(void) +{ + + + //r_init(); + + VALUE hostName = rb_str_new2(A_surfxml_process_host); + VALUE function = rb_str_new2(A_surfxml_process_function); + + rb_funcall(current,rb_intern("onBeginProcess"),2,hostName,function); + + +} + +static void application_handler_on_process_arg(void) +{ + + //r_init(); + + VALUE arg = rb_str_new2(A_surfxml_argument_value); + + rb_funcall(current,rb_intern("onProcessArg"),1,arg); + + +} + +static void application_handler_on_property(void) +{ + + //r_init(); + + VALUE id = rb_str_new2(A_surfxml_prop_id); + VALUE val = rb_str_new2(A_surfxml_prop_value); + + rb_funcall(current,rb_intern("onProperty"),2,id,val); + + +} + + +static void application_handler_on_end_process(void) +{ + + //r_init(); + + rb_funcall(current,rb_intern("onEndProcess"),0); + + +} diff --git a/src/bindings/ruby/rb_application_handler.h b/src/bindings/ruby/rb_application_handler.h new file mode 100644 index 0000000000..d030b0fc4c --- /dev/null +++ b/src/bindings/ruby/rb_application_handler.h @@ -0,0 +1,26 @@ +#ifndef _RB_APPLICATION_HANDLER_H_ +#define _RB_APPLICATION_HANDLER_H_ + +#include +#include "msg/msg.h" + + + +VALUE current; // The Current Instance of ApplicationHandler Class ,is it the same as Current Thread ??!! + +static void r_init(void); + +static void application_handler_on_start_document(void); + +static void application_handler_on_end_document(void); + +static void application_handler_on_begin_process(void); + +static void application_handler_on_process_arg(void); + +static void application_handler_on_property(void); + +static void application_handler_on_end_process(void); + + +#endif diff --git a/src/bindings/ruby/rb_msg.c b/src/bindings/ruby/rb_msg.c new file mode 100644 index 0000000000..4a9a8f6de0 --- /dev/null +++ b/src/bindings/ruby/rb_msg.c @@ -0,0 +1,264 @@ +#include "rb_msg.h" +#include "msg/msg.h" +#include "msg/datatypes.h" +#include "xbt/sysdep.h" +#include "xbt/log.h" +#include "xbt/asserts.h" +#include "surf/surfxml_parse.h" + + +#include "rb_msg_task.c" +#include "rb_msg_host.c" +#include "rb_msg_process.c" +#include "rb_application_handler.c" + + + +//Init Msg_Init From Ruby + + +static void msg_init(VALUE Class,VALUE args) +{ + + char **argv=NULL; + const char *tmp; + int argc,type,i; + VALUE *ptr ; + + + + // Testing The Args Type + type = TYPE(args); + + if (type != T_ARRAY ) + { + rb_raise(rb_eRuntimeError,"Argh!! Bad Arguments to msg_init"); + return; + } + + ptr= RARRAY(args)->ptr; + argc= RARRAY(args)->len; + +// Create C Array to Hold Data_Get_Struct + argv = xbt_new0(char *, argc); // argc or argc +1 + + argv[0] = strdup("ruby"); + + + for (i=0;iptr; + argv[i+1] = strdup(tmp); + + } + + // Calling C Msg_Init Method + MSG_global_init(&argc,argv); + MSG_set_channel_number(10); // Okey !! Okey !! This Must Be Fixed Dynamiclly , But Later ;) + SIMIX_context_select_factory("ruby"); + + // Free Stuffs + for (i=0;ihost, item, host, m_host_t) { + + //rbHost = (VALUE)host->data;// ??!! + + } + + if (MSG_OK != MSG_clean()){ + + rb_raise(rb_eRuntimeError,"MSG_clean() failed"); + } + + return; + +} + + + + +// Create Environment +static void msg_createEnvironment(VALUE class,VALUE plateformFile) +{ + + + int type = TYPE(plateformFile); + + if ( type != T_STRING ) + rb_raise(rb_eRuntimeError,"Bad Argument's Type"); + + const char * platform = RSTRING(plateformFile)->ptr; + + MSG_create_environment(platform); + + return; + +} + + +// deploy Application + +static void msg_deployApplication(VALUE class,VALUE deploymentFile ) +{ + + int type = TYPE(deploymentFile); + + if ( type != T_STRING ) + rb_raise(rb_eRuntimeError,"Bad Argument's Type"); + + const char *dep_file = RSTRING(deploymentFile)->ptr; + + + surf_parse_reset_parser(); + + surfxml_add_callback(STag_surfxml_process_cb_list, + application_handler_on_begin_process); + + surfxml_add_callback(STag_surfxml_argument_cb_list, + application_handler_on_process_arg); + + surfxml_add_callback(STag_surfxml_prop_cb_list, + application_handler_on_property); + + surfxml_add_callback(STag_surfxml_process_cb_list, + application_handler_on_end_process); + + surf_parse_open(dep_file); + + application_handler_on_start_document(); + + if(surf_parse()) + rb_raise(rb_eRuntimeError,"surf_parse() failed"); + + surf_parse_close(); + + application_handler_on_end_document(); + + +} + + + +static void msg_registerFunction(VALUE class,VALUE function_name,VALUE code) +{ + + char * fct_name = RSTRING(function_name)->ptr; + xbt_main_func_t fct_code + +} +// INFO +static void msg_info(VALUE class,VALUE msg) +{ + const char *s = RSTRING(msg)->ptr; + INFO("%s",s); +} + + +// Get Clock +static VALUE msg_get_clock(VALUE class) +{ + + return DBL2NUM(MSG_get_clock()); + +} + +//pajeOutput +static void msg_paje_out(VALUE class,VALUE pajeFile) +{ + const char *pfile = RSTRING(pajeFile)->ptr; + MSG_paje_output(pfile); + +} + +/***************************************************************************************************************** + +Wrapping MSG module and its Class ( Task,Host) & Methods ( Process's method...ect) +To Ruby + + the part after "Init_" is the name of the C extension specified in extconf.rb , not the name of C source file + +*****************************************************************************************************************/ + +void Init_msg() +{ + + // Modules + rb_msg = rb_define_module("MSG"); + + //Associated Environment Methods! + rb_define_method(rb_msg,"init",msg_init,1); + rb_define_method(rb_msg,"run",msg_run,0); + rb_define_method(rb_msg,"createEnvironment",msg_createEnvironment,1); + rb_define_method(rb_msg,"deployApplication",msg_deployApplication,1); + rb_define_method(rb_msg,"info",msg_info,1); + rb_define_method(rb_msg,"getClock",msg_get_clock,0); + rb_define_method(rb_msg,"pajeOutput",msg_paje_out,1); + + // Associated Process Methods +// rb_define_method(rb_msg,"processCreate",processCreate,2); + rb_define_method(rb_msg,"processSuspend",processSuspend,1); + rb_define_method(rb_msg,"processResume",processResume,1); + rb_define_method(rb_msg,"processIsSuspend",processIsSuspend,1); + rb_define_method(rb_msg,"processKill",processKill,1); + rb_define_method(rb_msg,"processGetHost",processGetHost,1); + + //Classes + rb_task = rb_define_class_under(rb_msg,"Task",rb_cObject); + rb_host = rb_define_class_under(rb_msg,"Host",rb_cObject); + + //Task Methods + rb_define_module_function(rb_task,"new",task_new,3); + rb_define_module_function(rb_task,"compSize",task_comp,1); + rb_define_module_function(rb_task,"name",task_name,1); + rb_define_module_function(rb_task,"execute",task_execute,1); + rb_define_module_function(rb_task,"send",task_send,2); + rb_define_module_function(rb_task,"receive",task_receive,1); + rb_define_module_function(rb_task,"receive2",task_receive2,2); + rb_define_module_function(rb_task,"sender",task_sender,1); + rb_define_module_function(rb_task,"source",task_source,1); + rb_define_module_function(rb_task,"listen",task_listen,2); + rb_define_module_function(rb_task,"listenFromHost",task_listen_host,3); + + //Host Methods + rb_define_module_function(rb_host,"getByName",host_get_by_name,1); + rb_define_module_function(rb_host,"name",host_name,1); + rb_define_module_function(rb_host,"speed",host_speed,1); + rb_define_module_function(rb_host,"number",host_number,0); + rb_define_module_function(rb_host,"setData",host_set_data,2); + rb_define_module_function(rb_host,"getData",host_get_data,1); +// rb_define_module_function(rb_host,"hasData",host_has_data,1); + rb_define_module_function(rb_host,"isAvail",host_is_avail,1); + +} diff --git a/src/bindings/ruby/rb_msg.h b/src/bindings/ruby/rb_msg.h new file mode 100644 index 0000000000..d6e3dc4b48 --- /dev/null +++ b/src/bindings/ruby/rb_msg.h @@ -0,0 +1,47 @@ +#ifndef RB_MSG +#define RB_MSG +#include +#include "msg/msg.h" +#include + + +// #include "msg/private.h" +// #include "simix/private.h" +// #include "simix/smx_context_ruby.h" + +// MSG Module +VALUE rb_msg; +// MSG Classes +VALUE rb_task; +VALUE rb_host; + +//init_Msg Called When The Ruby Interpreter loads this C extension +void Init_msg(); + +// Msg_Init From Ruby +static void msg_init(VALUE Class,VALUE args); + +// Msg_Run From Ruby +static void msg_run(VALUE Class); + +// Create Environment +static void msg_createEnvironment(VALUE Class,VALUE plateformFile); + +// deploy Application +static void msg_deployApplication(VALUE Class,VALUE deploymntFile); + + +// Register Function +static void msg_registerFunction(VALUE Class,VALUE function_name,VALUE code); + +// Tools +static void msg_info(VALUE Class,VALUE msg); + +//get Clock +static VALUE msg_get_clock(VALUE Class); + +//pajeOutput +static void msg_paje_output(VALUE Class,VALUE pajeFile); + + +#endif \ No newline at end of file diff --git a/src/bindings/ruby/rb_msg_host.c b/src/bindings/ruby/rb_msg_host.c new file mode 100644 index 0000000000..27eefcefe2 --- /dev/null +++ b/src/bindings/ruby/rb_msg_host.c @@ -0,0 +1,86 @@ +#include "rb_msg_host.h" + +// Free Method +static void host_free(m_host_t ht) { + //Nothing to do !!? +} + + +// New Method : return a Host +static VALUE host_get_by_name(VALUE class, VALUE name) +{ + + m_host_t host = MSG_get_host_by_name(RSTRING(name)->ptr); + if(!host) + + rb_raise(rb_eRuntimeError,"MSG_get_host_by_name() failled"); + + return Data_Wrap_Struct(class, 0, host_free, host); + +} + + +//Get Name + +static VALUE host_name(VALUE class,VALUE host) +{ + + // Wrap Ruby Value to m_host_t struct + + m_host_t ht; + Data_Get_Struct(host, m_host_t, ht); + return rb_str_new2(MSG_host_get_name(ht)); + +} + +// Get Number +static VALUE host_number(VALUE class) +{ + + return MSG_get_host_number(); + +} + +// Host Speed ( Double ) +static VALUE host_speed(VALUE class,VALUE host) +{ + m_host_t ht ; + Data_Get_Struct(host,m_host_t,ht); + return MSG_get_host_speed(ht); + +} + + +// Host Set Data +static void host_set_data(VALUE class,VALUE host,VALUE data) +{ + //... +} + +// Host Get Data +static VALUE host_get_data(VALUE class,VALUE host) +{ + //... + return Qnil; +} + + + + +// Host is Avail +static VALUE host_is_avail(VALUE class,VALUE host) +{ + + m_host_t ht; + Data_Get_Struct(host,m_host_t,ht); + if (!ht) + { + rb_raise(rb_eRuntimeError,"Host not Bound"); + return Qnil; + } + + if(MSG_host_is_avail(ht)) + return Qtrue; + + return Qfalse; +} diff --git a/src/bindings/ruby/rb_msg_host.h b/src/bindings/ruby/rb_msg_host.h new file mode 100644 index 0000000000..911ac533aa --- /dev/null +++ b/src/bindings/ruby/rb_msg_host.h @@ -0,0 +1,32 @@ +#ifndef RB_MSG_HOST +#define RB_MSG_HOST + +#include +#include "msg/msg.h" + +// Free Method +static void host_free(m_host_t ht); + +// New Method +static VALUE host_get_by_name(VALUE Class, VALUE name); + +//Get Name +static VALUE host_name(VALUE Class,VALUE host); + +//Get Number +static VALUE host_number(VALUE Class); + +// get Speed +static VALUE host_speed(VALUE Class,VALUE host); + +// Set Data +static void host_set_data(VALUE Class,VALUE host,VALUE data); + +// Get Data +static VALUE host_get_data( VALUE Class,VALUE host); + + +//is Available +static VALUE host_is_avail(VALUE Class,VALUE host); + +#endif \ No newline at end of file diff --git a/src/bindings/ruby/rb_msg_process.c b/src/bindings/ruby/rb_msg_process.c new file mode 100644 index 0000000000..6fada0a8f9 --- /dev/null +++ b/src/bindings/ruby/rb_msg_process.c @@ -0,0 +1,354 @@ +#include "rb_msg_process.h" + +// Init Ruby + +static void initRuby() +{ + + ruby_init(); + ruby_init_loadpath(); + rb_require("RubyProcess.rb"); + +} + + +/*********************************************** + +Functions for Ruby Process Management ( Up Call) + +Idependant Methods + +************************************************/ + + +// get Ruby Process Name +static VALUE process_getName( VALUE ruby_process ) +{ + + initRuby(); + // instance = rb_funcall3(rb_const_get(rb_cObject, rb_intern("RbProcess")), rb_intern("new"), 0, 0); + return rb_funcall(ruby_process,rb_intern("getName"),0); + + +} + +// Get Process ID + +static VALUE process_getID(VALUE ruby_process) +{ + + initRuby(); + return rb_funcall(ruby_process,rb_intern("getID"),0); + +} + +// Get Bind + +static VALUE process_getBind(VALUE ruby_process) +{ + + initRuby(); + return rb_funcall(ruby_process,rb_intern("getBind"),0); + + +} + + +// Set Bind + +static void process_setBind(VALUE ruby_process,long bind) +{ + + initRuby(); + + VALUE r_bind = LONG2FIX(bind); + + rb_funcall(ruby_process,rb_intern("setBind"),1,r_bind); + + + +} + +// isAlive +static VALUE process_isAlive(VALUE ruby_process) +{ + + initRuby(); + return rb_funcall(ruby_process,rb_intern("alive?"),0); + +} + +// Kill Process + +static void process_kill(VALUE ruby_process) +{ + + initRuby(); + rb_funcall(ruby_process,rb_intern("kill"),0); + +} + +// join Process + +static void process_join( VALUE ruby_process ) +{ + + initRuby(); + + rb_funcall(ruby_process,rb_intern("join"),0); + +} + +// unschedule Process + +static void process_unschedule( VALUE ruby_process ) +{ + + initRuby(); + + rb_funcall(ruby_process,rb_intern("unschedule"),0); + +} + +// schedule Process + +static void process_schedule( VALUE ruby_process ) +{ + + initRuby(); + + rb_funcall(ruby_process,rb_intern("run"),0); + +} + + + + + +/*************************************************** + +Function for Native Process ( Bound ) Management + +Methods Belong to MSG Module + +****************************************************/ + +// Process To Native + +static m_process_t process_to_native(VALUE ruby_process) +{ + + VALUE id = process_getBind(ruby_process); + + if (!id) + { + rb_raise(rb_eRuntimeError,"Process Not Bound >>> id_Bind Null"); + return NULL; + } + + long l_id= FIX2LONG(id); + + return (m_process_t)l_id; + +} + +// Bind Process + +static void processBind(VALUE ruby_process,m_process_t process) +{ + + long bind = (long)(process); + + process_setBind(ruby_process,bind); + + +} + + +// processCreate + +static void processCreate(VALUE class,VALUE ruby_process,VALUE host) +{ + + VALUE rbName; // Name of Java Process instance + m_process_t process; // Native Process to Create + const char * name ; // Name of C Native Process + + + char alias[MAX_ALIAS_NAME + 1 ] = {0}; + + msg_mailbox_t mailbox; + + rbName = process_getName(ruby_process); + + if(!rbName) + { + + rb_raise(rb_eRuntimeError,"Internal error : Process Name Cannot be NULL"); + return; + + } + // Allocate the data for the simulation + process = xbt_new0(s_m_process_t,1); + process->simdata = xbt_new0(s_simdata_process_t,1); + + // Do we Really Need to Create Ruby Process Instance , >> process is already a Ruby Process !! So..Keep on ;) + + // Bind The Ruby Process instance to The Native Process + processBind(ruby_process,process); + + name = RSTRING(rbName)->ptr; + process->name = xbt_strdup(name); + + Data_Get_Struct(host,m_host_t,process->simdata->m_host); + + if(!(process->simdata->m_host)) // Not Binded + { + free(process->simdata); + free(process->data); + free(process); + rb_raise(rb_eRuntimeError,"Host not bound"); + return; + } + + + process->simdata->PID = msg_global->PID++; // msg_global ?? + + DEBUG + ("fil in process %s/%s (pid=%d) %p (sd=%p, host=%p, host->sd=%p) ", + process->name ,process->simdata->m_host->name,process->simdata->PID, + process,process->simdata, process->simdata->m_host, + process->simdata->m_host->simdata); + + + process->simdata->s_process = + SIMIX_process_create(process->name, + (xbt_main_func_t)ruby_process, + (void *) process, + process->simdata->m_host->simdata->smx_host->name, + 0,NULL,NULL); + + + DEBUG ( "context created (s_process=%p)",process->simdata->s_process); + + if (SIMIX_process_self()) { // SomeOne Created Me !! + process->simdata->PPID = MSG_process_get_PID(SIMIX_process_self()->data); + } + else + { + process->simdata->PPID = -1; + } + + process->simdata->last_errno = MSG_OK; + + // let's Add the Process to the list of the Simulation's Processes + + xbt_fifo_unshift(msg_global->process_list,process); + + sprintf(alias,"%s:%s",(process->simdata->m_host->simdata->smx_host)->name, + process->name); + + mailbox = MSG_mailbox_new(alias); + +} + + +// Process Management + +static void processSuspend(VALUE class,VALUE ruby_process) +{ + + m_process_t process = process_to_native(ruby_process); + + if (!process) + { + rb_raise(rb_eRuntimeError,"Process Not Bound"); + return; + } + + // Trying to suspend The Process + + if ( MSG_OK != MSG_process_suspend(process)) + rb_raise(rb_eRuntimeError,"MSG_process_suspend() failed"); + + +} + +static void processResume(VALUE class,VALUE ruby_process) +{ + + m_process_t process = process_to_native(ruby_process); + + if (!process) + { + rb_raise(rb_eRuntimeError,"Process not Bound"); + return ; + } + + // Trying to resume the process + if ( MSG_OK != MSG_process_resume(process)) + rb_raise(rb_eRuntimeError,"MSG_process_resume() failed"); + +} + +static VALUE processIsSuspend(VALUE class,VALUE ruby_process) +{ + + m_process_t process = process_to_native(ruby_process); + + if (!process) + { + rb_raise (rb_eRuntimeError,"Process not Bound"); + return; + } + + // 1 is The Process is Suspended , 0 Otherwise + if(MSG_process_is_suspended(process)) + return Qtrue; + + return Qfalse; + +} + + +static void processKill(VALUE class,VALUE ruby_process) +{ + m_process_t process = process_to_native(ruby_process); + + if(!process) + { + rb_raise (rb_eRuntimeError,"Process Not Bound"); + return ; + } + // Delete The Global Reference / Ruby Process + process_kill(ruby_process); + // Delete the Native Process + MSG_process_kill(process); + +} + +static VALUE processGetHost(VALUE class,VALUE ruby_process) +{ + + m_process_t process = process_to_native(ruby_process); + + m_host_t host; + + if (!process) + { + rb_raise(rb_eRuntimeError,"Process Not Bound"); + return Qnil; // NULL + } + + host = MSG_process_get_host(process); + + if(!host->data) + { + rb_raise (rb_eRuntimeError,"MSG_process_get_host() failed"); + return Qnil; + + } + + return Data_Wrap_Struct(class, 0, host_free, host); + +} \ No newline at end of file diff --git a/src/bindings/ruby/rb_msg_process.h b/src/bindings/ruby/rb_msg_process.h new file mode 100644 index 0000000000..d51b3985cf --- /dev/null +++ b/src/bindings/ruby/rb_msg_process.h @@ -0,0 +1,106 @@ +#ifndef RB_MSG_PROCESS +#define RB_MSG_PROCESS + +#include +#include +#include "msg/msg.h" +#include "msg/datatypes.h" + +#include "msg/private.h" +#include "msg/mailbox.h" +#include "surf/surfxml_parse.h" +#include "simix/simix.h" +#include "simix/private.h" +#include "xbt/sysdep.h" +#include "xbt/log.h" +#include "xbt/asserts.h" + +#include "rb_msg_host.h" + + +/************************************************************************** +There are 2 section in This File: + +1 - Functions to Manage The Ruby Process >> Up Call +2 - Functions to Manage The Native Process Simulation Bound >> Down Call + +***************************************************************************/ + + +// Init Ruby : To Call Ruby Methods From C + +static void initRuby(); + +/*********************************************** + +Functions for Ruby Process Management ( Up Call ) + +Independant Methods + +************************************************/ + +// Get Name +static VALUE process_getName( VALUE ruby_process ); + +// Get Process ID +static VALUE process_getID(VALUE ruby_process); + +// Get Bind : return the ID of Bind member +static VALUE process_getBind(VALUE ruby_class); + +// Set Bind +static void process_setBind(VALUE ruby_class,long bind); + +// isAlive +static VALUE process_isAlive(VALUE ruby_process); + +// Kill Process +static void process_kill(VALUE ruby_process); + +// join Process +static void process_join( VALUE ruby_process ); + +// unschedule Process +static void process_unschedule( VALUE ruby_process ); + +// schedule Process +static void process_schedule( VALUE ruby_process ); + + + + +/*************************************************** + +Function for Native Process ( Bound ) Management + +Methods Belong to The MSG Module +****************************************************/ + +// ProcessBind Method ; Process Ruby >> Process C + +//friend Method // Not belong to the Class but Called within !! +static m_process_t process_to_native(VALUE ruby_process); + +// Binding Process >> Friend Method +static void processBind(VALUE ruby_class,m_process_t process); + +// CreateProcess Method +static void processCreate(VALUE Class,VALUE rb_process,VALUE host); + +// ProcessSuspend +static void processSuspend(VALUE Class,VALUE ruby_process); + +// ProcessResume +static void processResume(VALUE Class,VALUE ruby_process); + +//ProcessIsSuspend return Boolean ( Qtrue / Qfalse ) +static VALUE processIsSuspend(VALUE Class,VALUE ruby_process); + +//Processkill +static void processKill(VALUE Class,VALUE ruby_process); + +//ProcessGetHost +static VALUE processGetHost(VALUE Class,VALUE ruby_process); + + +#endif \ No newline at end of file diff --git a/src/bindings/ruby/rb_msg_task.c b/src/bindings/ruby/rb_msg_task.c new file mode 100644 index 0000000000..d54b5429d4 --- /dev/null +++ b/src/bindings/ruby/rb_msg_task.c @@ -0,0 +1,162 @@ +#include "rb_msg_task.h" + + +// Free Method +static void task_free(m_task_t tk) { + MSG_task_destroy(tk); +} + +// New Method +static VALUE task_new(VALUE class, VALUE name,VALUE comp_size,VALUE comm_size) +{ + + //char * t_name = RSTRING(name)->ptr; + m_task_t task = MSG_task_create(RSTRING(name)->ptr,NUM2INT(comp_size),NUM2INT(comm_size),NULL); + // Wrap m_task_t to a Ruby Value + return Data_Wrap_Struct(class, 0, task_free, task); + +} + +//Get Computation Size +static VALUE task_comp(VALUE class,VALUE task) +{ + double size; + m_task_t tk; + // Wrap Ruby Value to m_task_t struct + Data_Get_Struct(task, m_task_t, tk); + size = MSG_task_get_compute_duration(tk); + return rb_float_new(size); +} + + +//Get Name + +static VALUE task_name(VALUE class,VALUE task) +{ + + // Wrap Ruby Value to m_task_t struct + + m_task_t tk; + Data_Get_Struct(task, m_task_t, tk); + return rb_str_new2(MSG_task_get_name(tk)); + +} + + + + +// Execute Task + +static VALUE task_execute(VALUE class,VALUE task) +{ + + // Wrap Ruby Value to m_task_t struct + m_task_t tk; + Data_Get_Struct(task, m_task_t, tk); + return INT2NUM(MSG_task_execute(tk)); + + +} + +// Sending Task + +static VALUE task_send(VALUE class,VALUE task,VALUE mailbox) +{ + + // Wrap Ruby Value to m_task_t struct + m_task_t tk; + Data_Get_Struct(task, m_task_t, tk); + return INT2NUM(MSG_task_send(tk,RSTRING(mailbox)->ptr)); + + +} + +// Recieving Task + +/** +*It Return a Task +*/ + +static VALUE task_receive(VALUE class,VALUE mailbox) +{ + m_task_t tk; + MSG_task_receive(tk,RSTRING(mailbox)->ptr); + return Data_Wrap_Struct(class, 0, task_free, tk); +} + +// Recieve Task 2 +// Not Appreciated +static VALUE task_receive2(VALUE class,VALUE task,VALUE mailbox) +{ + m_task_t tk; + Data_Get_Struct(task, m_task_t, tk); + return INT2NUM(MSG_task_receive(tk,RSTRING(mailbox)->ptr)); + +} + + +// It Return a Native Process ( m_process_t ) +static VALUE task_sender(VALUE class,VALUE task) +{ + m_task_t tk; + Data_Get_Struct(task,m_task_t,tk); + return MSG_task_get_sender(tk); + +} + +// it return a Host +static VALUE task_source(VALUE class,VALUE task) +{ + m_task_t tk; + Data_Get_Struct(task,m_task_t,tk); + + m_host_t host = MSG_task_get_source(tk); + if(!host->data) + { + rb_raise(rb_eRuntimeError,"MSG_task_get_source() failed"); + return Qnil; + } + return host; + +} + +// Return Boolean +static VALUE task_listen(VALUE class,VALUE task,VALUE alias) +{ + m_task_t tk; + const char *p_alias; + int rv; + + Data_Get_Struct(task,m_task_t,tk); + p_alias = RSTRING(alias)->ptr; + + rv = MSG_task_listen(p_alias); + + if(rv) return Qtrue; + + return Qfalse; + +} + +// return Boolean +static VALUE task_listen_host(VALUE class,VALUE task,VALUE alias,VALUE host) +{ + + m_task_t tk; + m_host_t ht; + const char *p_alias; + int rv; + + Data_Get_Struct(task,m_task_t,tk); + Data_Get_Struct(host,m_host_t,ht); + p_alias = RSTRING(alias)->ptr; + + rv = MSG_task_listen_from_host(p_alias,ht); + + if (rv) return Qtrue; + + return Qfalse; + + + +} \ No newline at end of file diff --git a/src/bindings/ruby/rb_msg_task.h b/src/bindings/ruby/rb_msg_task.h new file mode 100644 index 0000000000..f8d8170831 --- /dev/null +++ b/src/bindings/ruby/rb_msg_task.h @@ -0,0 +1,48 @@ +#ifndef RB_MSG_TASK_H +#define RB_MSG_TASK_H + +#include +#include +#include "msg/msg.h" +#include "msg/datatypes.h" +#include "xbt/sysdep.h" +#include "xbt/log.h" +#include "xbt/asserts.h" + +// Free Method +static void task_free(m_task_t tk); + +// New Method >>> Data NULL +static VALUE task_new(VALUE Class, VALUE name,VALUE comp_size,VALUE comm_size); + +//Get Computation Size +static VALUE task_comp(VALUE Class,VALUE task); + +//Get Name +static VALUE task_name(VALUE Class,VALUE task); + +// Execute Task +static VALUE task_execute(VALUE Class,VALUE task); + +// Sending Task +static VALUE task_send(VALUE Class,VALUE task,VALUE mailbox); + +// Recieve : return a task +static VALUE task_receive(VALUE Class,VALUE mailbox); + +// Recieve Task 2 << Not Appreciated +static VALUE task_receive2(VALUE Class,VALUE task,VALUE mailbox); + +// Get Sender +static VALUE task_sender(VALUE Class,VALUE task); + +// Get Source +static VALUE task_source(VALUE Class,VALUE task); + +//Listen From Alias +static VALUE task_listen(VALUE Class,VALUE task,VALUE alias); + +//Listen from Host +static VALUE task_listen_host(VALUE Class,VALUE task,VALUE alias,VALUE host); + +#endif \ No newline at end of file diff --git a/src/bindings/ruby/smx_context_ruby.c b/src/bindings/ruby/smx_context_ruby.c new file mode 100644 index 0000000000..be91199427 --- /dev/null +++ b/src/bindings/ruby/smx_context_ruby.c @@ -0,0 +1,193 @@ +/* $Id$ */ + +/* context_Ruby - implementation of context switching with lua coroutines */ + +/* Copyright (c) 2004-2008 the SimGrid team. All right reserved */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ +#include +#include "provate.h" +#include "xbt/function_types.h" +#include "context_sysv_config.h" + +typedef struct s_smx_ctx_ruby +{ + SMX_CTX_BASE_T; + VALUE process; // The Process Ruby Instance + //... +}s_smx_ctx_ruby_t,*smx_ctx_ruby_t; + +static smx_context_t +smx_ctx_ruby_create_context(xbt_main_func_t code,int argc,char** argv, + void_f_pvoid_t cleanup_func,void *cleanup_arg); + + +static int smx_ctx_ruby_factory_finalize(smx_context_factory_t *factory); + +static void smx_ctx_ruby_free(smx_context_t context); + +static void smx_ctx_ruby_start(smx_context_t context); + +static void smx_ctx_ruby_stop(smx_context_t context); + +static void smx_ctx_ruby_suspend(smx_context_t context); + +static void + smx_ctx_ruby_resume(smx_context_t old_context,smx_context_t new_context); + +static void smx_ctx_ruby_wrapper(void); //??!! + + + +void SIMIX_ctx_ruby_factory_init(smx_context_factory_t *factory) +{ + + *factory = xbt_new0(s_smx_context_factory_t,1); + + (*factory)->create_context = smx_ctx_ruby_create_context; + (*factory)->finalize = smx_ctx_ruby_factory_finalize; + (*factory)->free = smx_ctx_ruby_free; + (*factory)->start = smx_ctx_ruby_start; + (*factory)->stop = smx_ctx_ruby_stop; + (*factory)->suspend = smx_ctx_ruby_suspend; + (*factory)->resume = smx_ctx_ruby_resume; + (*factory)->name = "smx_ruby_context_factory"; + + ruby_init(); + ruby_init_loadpath(); + +} + +static int smx_ctx_ruby_factory_finalize(smx_context_factory_t *factory) +{ + + free(*factory); + *factory = NULL; + return 0; + +} + +static smx_context_t + smx_ctx_ruby_create_context(xbt_main_func_t code,int argc,char** argv, + void_f_pvoid_t cleanup_func,void* cleanup_arg) +{ + + smx_ctx_ruby_t context = xbt_new0(s_smx_ruby_t,1); + + /*if the user provided a function for the process , then use it + Otherwise it's the context for maestro */ + if( code ) + { + context->cleanup_func = cleanup_func; + context->cleanup_arg = cleanup_arg; + context->process = rb_funcall3(rb_const_get(rb_cObject, rb_intern("RbProcess")), rb_intern("new"), 0, 0); + //context->process = rb_thread_main(); // Or VALUE rb_thread_create ( VALUE(*(ANYARGS), void *) ) + + + } + return (smx_context_t) context; + +} + +static void smx_ctx_ruby_free(smx_context_t context) +{ + + if (context) + { + smx_ctx_ruby_t ctx_ruby = (smx_ctx_ruby_t) context; + + if (ctx_ruby->process) + VALUE process = ctx_ruby->process; + + ctx_ruby->process = Qnil; + + // if the Ruby Process is Alive , Join it + + if ( process_isAlive(process) ) + process_join(process); + + } + + free(context); + context = NULL; + + + } + + +} + + +static void smx_ctx_ruby_start(smx_context_t context) +{ + + + +} + + +static void smx_ctx_ruby_stop(smx_context_t context) +{ + + VALUE process = Qnil; + smx_ctx_ruby_t ctx_ruby; + + if ( context->cleanup_func) + (*(context->cleanup_func)) (context->cleanup_arg); + + ctx_ruby = (smx_ctx_ruby_t) context; + + // Well , Let's Do The Same as JNI Stoppin' Process + if ( simix_gloabl->current_process->iwannadie ) + { + if( ctx_ruby->process ) + { + //if the Ruby Process still Alive ,let's Schedule it + if ( process_isAlive( ctx_ruby->process ) ) + { + + current = (smx_ctx_ruby_t)simix_gloabl->current_process->context: + process_schedule(current->process); + + process = ctx_ruby->process; + + // interupt/kill The Ruby Process + process_kill(process); + + } + } + }else { + + process = ctx_ruby->process; + ctx_ruby->process = Qnil; + + } + + +} + +static void smx_ctx_ruby_suspend(smx_context_t context) +{ + +if ( context ) +{ +smx_ctx_ruby_t ctx_ruby = (smx_ctx_ruby_t) context; + if (ctx_ruby->process) + process_unschedule( ctx_ruby->process ) ; +} + + else + rb_raise(rb_eRuntimeError,"smx_ctx_ruby_suspend failed"); + +} + +static void smx_ctx_ruby_resume(smx_context_t old_context,smx_context_t new_context) +{ + + smx_ctx_ruby_t ctx_ruby = (smx_ctx_ruby_t) new_context; + + process_schedule( ctx_ruby->process ); + + +}