[macruby-changes] [3336] MacRuby/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Mon Jan 25 16:39:08 PST 2010
Revision: 3336
http://trac.macosforge.org/projects/ruby/changeset/3336
Author: ernest.prabhakar at gmail.com
Date: 2010-01-25 16:39:08 -0800 (Mon, 25 Jan 2010)
Log Message:
-----------
Created Dispatch helper library for convenience methods
Added Paths:
-----------
MacRuby/trunk/lib/dispatch/enumerable.rb
MacRuby/trunk/lib/dispatch/queue.rb
MacRuby/trunk/lib/dispatch.rb
MacRuby/trunk/spec/macruby/library/
MacRuby/trunk/spec/macruby/library/dispatch/
MacRuby/trunk/spec/macruby/library/dispatch/queue_source_spec.rb
MacRuby/trunk/spec/macruby/library/dispatch/queue_spec.rb
MacRuby/trunk/spec/macruby/tags/macruby/library/
MacRuby/trunk/spec/macruby/tags/macruby/library/dispatch/
MacRuby/trunk/spec/macruby/tags/macruby/library/dispatch/queue_spec_tags.txt
MacRuby/trunk/spec/macruby/tags/macruby/library/dispatch/queue_tags.txt
Removed Paths:
-------------
MacRuby/trunk/spec/macruby/core/gcd/prelude_spec.rb
Added: MacRuby/trunk/lib/dispatch/enumerable.rb
===================================================================
--- MacRuby/trunk/lib/dispatch/enumerable.rb (rev 0)
+++ MacRuby/trunk/lib/dispatch/enumerable.rb 2010-01-26 00:39:08 UTC (rev 3336)
@@ -0,0 +1,18 @@
+module Dispatch
+ module Enumerable
+ def p_map(&block)
+ result = []
+ # We will access the `result` array from within this serial queue,
+ # as without a GIL we cannot assume array access to be thread-safe.
+ result_queue = Dispatch::Queue.new('access-queue.#{result.object_id}')
+ # Uses Dispatch::Queue#apply to submit many blocks at once
+ Dispatch::Queue.concurrent.apply(size) do |idx|
+ # run the block in the concurrent queue to maximize parallelism
+ temp = block(self[idx])
+ # do only the assignment on the serial queue
+ result_queue.async { result[idx] = temp }
+ end
+ result
+ end
+ end
+end
Added: MacRuby/trunk/lib/dispatch/queue.rb
===================================================================
--- MacRuby/trunk/lib/dispatch/queue.rb (rev 0)
+++ MacRuby/trunk/lib/dispatch/queue.rb 2010-01-26 00:39:08 UTC (rev 3336)
@@ -0,0 +1,16 @@
+module Dispatch
+ class Queue
+ # Combines +&block+ up to +stride+ times before passing to Queue::Apply
+ def stride(count, stride=1, &block)
+ sub_count = (count / stride).to_int
+ puts "\nsub_count: #{sub_count} (#{count} / #{stride})"
+ apply(sub_count) do |i|
+ i0 = i*stride
+ (i0..i0+stride).each { |j| "inner #{j}"; block.call(j) } #nested dispatch blocks fails
+ end
+ done = sub_count*stride;
+ puts "\ndone: #{done} (#{sub_count}*#{stride})"
+ (done..count).each { |j| p "inner #{j}"; block.call(j) }
+ end
+ end
+end
Added: MacRuby/trunk/lib/dispatch.rb
===================================================================
--- MacRuby/trunk/lib/dispatch.rb (rev 0)
+++ MacRuby/trunk/lib/dispatch.rb 2010-01-26 00:39:08 UTC (rev 3336)
@@ -0,0 +1,19 @@
+#
+# dispatch.rb - Grand Central Dispatch support library
+#
+# Copyright (C) 2010 Apple, Inc.
+#
+# == Overview
+#
+# Grand Central Dispatch (GCD) is a novel approach to multicore computing
+# first released in Mac OS X version 10.6 Snow Leopard.
+# The Dispatch module and associated classes (Queue, Group, Semaphore, Source)
+# in MacRuby core provides a simple wrapping on top of the libdispatch C API.
+# This library provides higher-level services and convenience methods
+# to make it easier for traditional Ruby programmers to add multicore support.
+
+raise "Dispatch will only work on Mac OS X 10.6 or later" if MACOSX_VERSION < 10.6
+
+require 'dispatch/queue'
+require 'dispatch/queue_source'
+require 'dispatch/enumerable'
Deleted: MacRuby/trunk/spec/macruby/core/gcd/prelude_spec.rb
===================================================================
--- MacRuby/trunk/spec/macruby/core/gcd/prelude_spec.rb 2010-01-26 00:39:06 UTC (rev 3335)
+++ MacRuby/trunk/spec/macruby/core/gcd/prelude_spec.rb 2010-01-26 00:39:08 UTC (rev 3336)
@@ -1,146 +0,0 @@
-require File.dirname(__FILE__) + "/../../spec_helper"
-require File.dirname(__FILE__) + "/../../../../gcd_prelude"
-
-if MACOSX_VERSION >= 10.6
-
- describe "Dispatch::Queue source from" do
- before :each do
- @q = Dispatch::Queue.new('org.macruby.gcd_spec.prelude')
- @src = nil
- end
-
- after :each do
- @src.cancel! if not @src.nil? and not @src.cancelled?
- @q.sync { }
- end
-
- describe "on_add" do
- it "fires with data on summed inputs" do
- @count = 0
- @src = @q.on_add {|s| @count += s.data}
- @src << 20
- @src << 22
- @q.sync {}
- @count.should == 42
- end
- end
-
- describe "on_or" do
- it "fires with data on ORed inputs" do
- @count = 0
- @src = @q.on_or {|s| @count += s.data}
- @src << 0b101_000
- @src << 0b000_010
- @q.sync {}
- @count.should == 42
- end
- end
-
- describe "on_process_event" do
- it "fires with data indicating which process event(s)" do
- @signal = Signal.list["USR1"]
- @event = nil
- @src = @q.on_process_event($$, :exit, :fork, :exec, :signal) do
- |s| @event = s.data
- end
- Signal.trap(@signal, "IGNORE")
- Process.kill(@signal, $$)
- Signal.trap(@signal, "DEFAULT")
- @q.sync {}
- @event.should == Dispatch::Source.proc_event(:signal)
- end
- end
-
- describe "on_signal" do
- it "fires with data on how often the process was signaled" do
- @signal = Signal.list["USR1"]
- @count = 0
- @src = @q.on_signal(@signal) {|s| @count += s.data}
- Signal.trap(@signal, "IGNORE")
- Process.kill(@signal, $$)
- Process.kill(@signal, $$)
- Signal.trap(@signal, "DEFAULT")
- @q.sync {}
- @count.should == 2
- @src.cancel!
- end
- end
-
- describe "file" do
- before :each do
- @msg = "#{$$}-#{Time.now}"
- @filename = "/var/tmp/gcd_spec_source-#{@msg}"
- @file = nil
- @src = nil
- end
-
- after :each do
- @src.cancel! if not @src.nil? and not @src.cancelled?
- @q.sync { }
- @file.close if not @file.closed?
- File.delete(@filename)
- end
-
- describe "on_read" do
- it "fires with data on how many bytes can be read" do
- File.open(@filename, "w") {|f| f.print @msg}
- @file = File.open(@filename, "r")
- @result = ""
- @src = @q.on_read(@file) {|s| @result<<@file.read(s.data)}
- while (@result.size < @msg.size) do; end
- @q.sync { }
- @result.should == @msg
- end
- end
-
- describe "on_write" do
- it "fires with data on how many bytes can be written" do
- @file = File.open(@filename, "w")
- @pos = 0
- @message = @msg
- @src = @q.on_read(@file) do |s|
- pos = s.data
- if not @message.nil? then
- next_msg = @message[0..pos-1]
- @file.write(next_msg)
- @message = @message[pos..-1]
- end
- end
- while (@result.size < @msg.size) do; end
- @q.sync { }
- @result.should == @msg
- end
- end
-
- describe "on_file_event" do
- it "fires with data on how many bytes can be written" do
- @file = File.open(@filename, "w")
- @fired = false
- @src = @q.on_file_event(@file, :delete, :write, :extend, :attrib, :link, :rename, :revoke) do |s|
- @flag = s.data
- @fired = true
- end
- @file.write(@msg)
- @file.flush
- @q.sync { }
- #while (@fired == false) do; end
- @fired.should == true
- @flag.should == Dispatch::Source.vnode_event(:write)
- end
- end
- end
-
- describe "on_interval" do
- it "fires with data on how often the timer has fired" do
- @count = -1
- repeats = 2
- @interval = 0.02
- @src = @q.on_interval(@interval) {|s| @count += s.data}
- sleep repeats*@interval
- @q.sync { }
- @count.should == repeats
- end
- end
- end
-
-end
Copied: MacRuby/trunk/spec/macruby/library/dispatch/queue_source_spec.rb (from rev 3335, MacRuby/trunk/spec/macruby/core/gcd/prelude_spec.rb)
===================================================================
--- MacRuby/trunk/spec/macruby/library/dispatch/queue_source_spec.rb (rev 0)
+++ MacRuby/trunk/spec/macruby/library/dispatch/queue_source_spec.rb 2010-01-26 00:39:08 UTC (rev 3336)
@@ -0,0 +1,146 @@
+require File.dirname(__FILE__) + "/../../spec_helper"
+require 'dispatch'
+
+if MACOSX_VERSION >= 10.6
+
+ describe "Dispatch::Queue source from" do
+ before :each do
+ @q = Dispatch::Queue.new('org.macruby.gcd_spec.prelude')
+ @src = nil
+ end
+
+ after :each do
+ @src.cancel! if not @src.nil? and not @src.cancelled?
+ @q.sync { }
+ end
+
+ describe "on_add" do
+ it "fires with data on summed inputs" do
+ @count = 0
+ @src = @q.on_add {|s| @count += s.data}
+ @src << 20
+ @src << 22
+ @q.sync {}
+ @count.should == 42
+ end
+ end
+
+ describe "on_or" do
+ it "fires with data on ORed inputs" do
+ @count = 0
+ @src = @q.on_or {|s| @count += s.data}
+ @src << 0b101_000
+ @src << 0b000_010
+ @q.sync {}
+ @count.should == 42
+ end
+ end
+
+ describe "on_process_event" do
+ it "fires with data indicating which process event(s)" do
+ @signal = Signal.list["USR1"]
+ @event = nil
+ @src = @q.on_process_event($$, :exit, :fork, :exec, :signal) do
+ |s| @event = s.data
+ end
+ Signal.trap(@signal, "IGNORE")
+ Process.kill(@signal, $$)
+ Signal.trap(@signal, "DEFAULT")
+ @q.sync {}
+ @event.should == Dispatch::Source.proc_event(:signal)
+ end
+ end
+
+ describe "on_signal" do
+ it "fires with data on how often the process was signaled" do
+ @signal = Signal.list["USR1"]
+ @count = 0
+ @src = @q.on_signal(@signal) {|s| @count += s.data}
+ Signal.trap(@signal, "IGNORE")
+ Process.kill(@signal, $$)
+ Process.kill(@signal, $$)
+ Signal.trap(@signal, "DEFAULT")
+ @q.sync {}
+ @count.should == 2
+ @src.cancel!
+ end
+ end
+
+ describe "file" do
+ before :each do
+ @msg = "#{$$}-#{Time.now}"
+ @filename = "/var/tmp/gcd_spec_source-#{@msg}"
+ @file = nil
+ @src = nil
+ end
+
+ after :each do
+ @src.cancel! if not @src.nil? and not @src.cancelled?
+ @q.sync { }
+ @file.close if not @file.closed?
+ File.delete(@filename)
+ end
+
+ describe "on_read" do
+ it "fires with data on how many bytes can be read" do
+ File.open(@filename, "w") {|f| f.print @msg}
+ @file = File.open(@filename, "r")
+ @result = ""
+ @src = @q.on_read(@file) {|s| @result<<@file.read(s.data)}
+ while (@result.size < @msg.size) do; end
+ @q.sync { }
+ @result.should == @msg
+ end
+ end
+
+ describe "on_write" do
+ it "fires with data on how many bytes can be written" do
+ @file = File.open(@filename, "w")
+ @pos = 0
+ @message = @msg
+ @src = @q.on_read(@file) do |s|
+ pos = s.data
+ if not @message.nil? then
+ next_msg = @message[0..pos-1]
+ @file.write(next_msg)
+ @message = @message[pos..-1]
+ end
+ end
+ while (@result.size < @msg.size) do; end
+ @q.sync { }
+ @result.should == @msg
+ end
+ end
+
+ describe "on_file_event" do
+ it "fires with data on how many bytes can be written" do
+ @file = File.open(@filename, "w")
+ @fired = false
+ @src = @q.on_file_event(@file, :delete, :write, :extend, :attrib, :link, :rename, :revoke) do |s|
+ @flag = s.data
+ @fired = true
+ end
+ @file.write(@msg)
+ @file.flush
+ @q.sync { }
+ #while (@fired == false) do; end
+ @fired.should == true
+ @flag.should == Dispatch::Source.vnode_event(:write)
+ end
+ end
+ end
+
+ describe "on_interval" do
+ it "fires with data on how often the timer has fired" do
+ @count = -1
+ repeats = 2
+ @interval = 0.02
+ @src = @q.on_interval(@interval) {|s| @count += s.data}
+ sleep repeats*@interval
+ @q.sync { }
+ @count.should == repeats
+ end
+ end
+ end
+
+end
Added: MacRuby/trunk/spec/macruby/library/dispatch/queue_spec.rb
===================================================================
--- MacRuby/trunk/spec/macruby/library/dispatch/queue_spec.rb (rev 0)
+++ MacRuby/trunk/spec/macruby/library/dispatch/queue_spec.rb 2010-01-26 00:39:08 UTC (rev 3336)
@@ -0,0 +1,27 @@
+require File.dirname(__FILE__) + "/../../spec_helper"
+require 'dispatch'
+
+if MACOSX_VERSION >= 10.6
+ describe "Dispatch::Queue" do
+ before :each do
+ @q = Dispatch::Queue.new('org.macruby.gcd_spec.prelude')
+ end
+
+ describe "stride" do
+ it "accepts a count, stride and block and yields it that many times, with an index" do
+ @i = 0
+ @q.stride(10) { |j| @i += j; p "outer #{j}" }
+ @i.should == 45
+ @i = 0
+ @q.stride(10, 3) { |j| @i += j }
+ @i.should == 45
+ @i = 0
+ @q.stride(12, 3) { |j| @i += j }
+ @i.should == 66
+ @i = 42
+ @q.stride(0, 1) { |j| @i += 1 }
+ @i.should == 42
+ end
+ end
+ end
+end
\ No newline at end of file
Added: MacRuby/trunk/spec/macruby/tags/macruby/library/dispatch/queue_tags.txt
===================================================================
--- MacRuby/trunk/spec/macruby/tags/macruby/library/dispatch/queue_tags.txt (rev 0)
+++ MacRuby/trunk/spec/macruby/tags/macruby/library/dispatch/queue_tags.txt 2010-01-26 00:39:08 UTC (rev 3336)
@@ -0,0 +1 @@
+fails:Dispatch::Queue stride accepts a count, stride and block and yields it that many times, with an index
\ No newline at end of file
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20100125/fa15f5de/attachment-0001.html>
More information about the macruby-changes
mailing list