Add time and clock Mach functions; implement Mach::Semaphore#timedwait.
This commit is contained in:
		
							parent
							
								
									b76bf99947
								
							
						
					
					
						commit
						680527cbab
					
				|  | @ -0,0 +1,24 @@ | ||||||
|  | require 'mach/functions' | ||||||
|  | require 'mach/port' | ||||||
|  | require 'mach/time_spec' | ||||||
|  | 
 | ||||||
|  | module Mach | ||||||
|  |   class Clock | ||||||
|  |     include Functions | ||||||
|  | 
 | ||||||
|  |     def initialize(clock_id) | ||||||
|  |       @clock_id = clock_id | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     def to_s | ||||||
|  |       "#<#{self.class} #{@clock_id.to_i}>" | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     def get_time | ||||||
|  |       time = TimeSpec.new | ||||||
|  |       clock_get_time(@clock_id.to_i, time) | ||||||
|  |       time | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | @ -1,5 +1,7 @@ | ||||||
| require 'ffi' | require 'ffi' | ||||||
| 
 | 
 | ||||||
|  | require 'mach/time_spec' | ||||||
|  | 
 | ||||||
| module Mach | module Mach | ||||||
|   # FFI wrapper around a subset of the Mach API (likely Mac OS X |   # FFI wrapper around a subset of the Mach API (likely Mac OS X | ||||||
|   # specific). |   # specific). | ||||||
|  | @ -15,9 +17,12 @@ module Mach | ||||||
|     typedef :int, :kern_return_t # true for 64 bit?? |     typedef :int, :kern_return_t # true for 64 bit?? | ||||||
|     typedef :int, :mach_error_t |     typedef :int, :mach_error_t | ||||||
|     typedef :int, :sync_policy_t # SyncPolicy |     typedef :int, :sync_policy_t # SyncPolicy | ||||||
|  |     typedef :int, :clock_id_t | ||||||
|  |     typedef :int, :clock_res_t | ||||||
| 
 | 
 | ||||||
|     typedef :string, :name_t |     typedef :string, :name_t | ||||||
| 
 | 
 | ||||||
|  |     typedef :mach_port_t, :host_t | ||||||
|     typedef :mach_port_t, :task_t |     typedef :mach_port_t, :task_t | ||||||
|     typedef :mach_port_t, :ipc_space_t |     typedef :mach_port_t, :ipc_space_t | ||||||
|     typedef :mach_port_t, :semaphore_t |     typedef :mach_port_t, :semaphore_t | ||||||
|  | @ -128,11 +133,6 @@ module Mach | ||||||
|             :name, |             :name, | ||||||
|             :bootstrap ) |             :bootstrap ) | ||||||
| 
 | 
 | ||||||
|     class Timespec < FFI::ManagedStruct |  | ||||||
|       layout(:tv_sec, :uint, |  | ||||||
|              :tv_nsec, :int) |  | ||||||
|     end |  | ||||||
| 
 |  | ||||||
|     KERN_SUCCESS = 0 |     KERN_SUCCESS = 0 | ||||||
| 
 | 
 | ||||||
|     # Replace methods in +syms+ with error checking wrappers that |     # Replace methods in +syms+ with error checking wrappers that | ||||||
|  | @ -253,6 +253,18 @@ module Mach | ||||||
|                           MachMsgType], |                           MachMsgType], | ||||||
|                          :kern_return_t) |                          :kern_return_t) | ||||||
| 
 | 
 | ||||||
|  |     ################## | ||||||
|  |     # Host functions # | ||||||
|  |     ################## | ||||||
|  | 
 | ||||||
|  |     attach_function :mach_host_self, [], :mach_port_t | ||||||
|  | 
 | ||||||
|  |     attach_mach_function(:host_get_clock_service, | ||||||
|  |                          [:host_t, | ||||||
|  |                           :clock_id_t, | ||||||
|  |                           :pointer], | ||||||
|  |                          :kern_return_t) | ||||||
|  | 
 | ||||||
|     ################## |     ################## | ||||||
|     # Task functions # |     # Task functions # | ||||||
|     ################## |     ################## | ||||||
|  | @ -269,6 +281,15 @@ module Mach | ||||||
|                           :mach_port_t], |                           :mach_port_t], | ||||||
|                          :kern_return_t) |                          :kern_return_t) | ||||||
| 
 | 
 | ||||||
|  |     ################### | ||||||
|  |     # Clock functions # | ||||||
|  |     ################### | ||||||
|  | 
 | ||||||
|  |     attach_mach_function(:clock_get_time, | ||||||
|  |                          [:clock_id_t, | ||||||
|  |                           TimeSpec], | ||||||
|  |                          :kern_return_t) | ||||||
|  | 
 | ||||||
|     ##################### |     ##################### | ||||||
|     # Message functions # |     # Message functions # | ||||||
|     ##################### |     ##################### | ||||||
|  | @ -312,7 +333,7 @@ module Mach | ||||||
|                          [:semaphore_t], |                          [:semaphore_t], | ||||||
|                          :kern_return_t) |                          :kern_return_t) | ||||||
|     attach_mach_function(:semaphore_timedwait, |     attach_mach_function(:semaphore_timedwait, | ||||||
|                          [:semaphore_t, Timespec.val], |                          [:semaphore_t, TimeSpec.val], | ||||||
|                          :kern_return_t) |                          :kern_return_t) | ||||||
| 
 | 
 | ||||||
|   end |   end | ||||||
|  |  | ||||||
|  | @ -0,0 +1,28 @@ | ||||||
|  | require 'mach/functions' | ||||||
|  | require 'mach/port' | ||||||
|  | require 'mach/clock' | ||||||
|  | 
 | ||||||
|  | module Mach | ||||||
|  |   class Host < Port | ||||||
|  |     include Functions | ||||||
|  | 
 | ||||||
|  |     # @return [Task] | ||||||
|  |     def self.self | ||||||
|  |       new(Functions.mach_host_self) | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     def initialize(host) | ||||||
|  |       super(:port => host) | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     alias_method :host, :port | ||||||
|  | 
 | ||||||
|  |     def get_clock_service | ||||||
|  |       mem = new_memory_pointer(:clock_id_t) | ||||||
|  |       host_get_clock_service(host, 0, mem) | ||||||
|  |       clock_id = Port.new(:port => mem.read_int) | ||||||
|  |       Clock.new clock_id | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | @ -1,5 +1,7 @@ | ||||||
| require 'mach/functions' | require 'mach/functions' | ||||||
| require 'mach/port' | require 'mach/port' | ||||||
|  | require 'mach/host' | ||||||
|  | require 'mach/clock' | ||||||
| 
 | 
 | ||||||
| module Mach | module Mach | ||||||
|   class Semaphore < Port |   class Semaphore < Port | ||||||
|  | @ -61,8 +63,11 @@ module Mach | ||||||
|       semaphore_wait(port) |       semaphore_wait(port) | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     # TODO: implement |     # @see http://pkaudio.blogspot.com/2010/05/mac-os-x-no-timed-semaphore-waits.html | ||||||
|     def timedwait(secs) |     def timedwait(secs) | ||||||
|  |       timespec = TimeSpec.new | ||||||
|  |       timespec.add_seconds!(secs) | ||||||
|  | 
 | ||||||
|       semaphore_timedwait(port, timespec) |       semaphore_timedwait(port, timespec) | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
|  |  | ||||||
|  | @ -0,0 +1,16 @@ | ||||||
|  | require 'ffi' | ||||||
|  | 
 | ||||||
|  | module Mach | ||||||
|  |   class TimeSpec < FFI::Struct | ||||||
|  |     layout(:tv_sec, :uint, | ||||||
|  |            :tv_nsec, :int)      # clock_res_t | ||||||
|  | 
 | ||||||
|  |     def to_s | ||||||
|  |       "#<%s tv_sec=%d tv_nsec=%d>" % [self.class, | ||||||
|  |                                       self[:tv_sec], | ||||||
|  |                                       self[:tv_nsec]] | ||||||
|  |        | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | end | ||||||
|  | 
 | ||||||
		Loading…
	
		Reference in New Issue