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 'mach/time_spec'
 | 
			
		||||
 | 
			
		||||
module Mach
 | 
			
		||||
  # FFI wrapper around a subset of the Mach API (likely Mac OS X
 | 
			
		||||
  # specific).
 | 
			
		||||
| 
						 | 
				
			
			@ -15,9 +17,12 @@ module Mach
 | 
			
		|||
    typedef :int, :kern_return_t # true for 64 bit??
 | 
			
		||||
    typedef :int, :mach_error_t
 | 
			
		||||
    typedef :int, :sync_policy_t # SyncPolicy
 | 
			
		||||
    typedef :int, :clock_id_t
 | 
			
		||||
    typedef :int, :clock_res_t
 | 
			
		||||
 | 
			
		||||
    typedef :string, :name_t
 | 
			
		||||
 | 
			
		||||
    typedef :mach_port_t, :host_t
 | 
			
		||||
    typedef :mach_port_t, :task_t
 | 
			
		||||
    typedef :mach_port_t, :ipc_space_t
 | 
			
		||||
    typedef :mach_port_t, :semaphore_t
 | 
			
		||||
| 
						 | 
				
			
			@ -128,11 +133,6 @@ module Mach
 | 
			
		|||
            :name,
 | 
			
		||||
            :bootstrap )
 | 
			
		||||
 | 
			
		||||
    class Timespec < FFI::ManagedStruct
 | 
			
		||||
      layout(:tv_sec, :uint,
 | 
			
		||||
             :tv_nsec, :int)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    KERN_SUCCESS = 0
 | 
			
		||||
 | 
			
		||||
    # Replace methods in +syms+ with error checking wrappers that
 | 
			
		||||
| 
						 | 
				
			
			@ -253,6 +253,18 @@ module Mach
 | 
			
		|||
                          MachMsgType],
 | 
			
		||||
                         :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 #
 | 
			
		||||
    ##################
 | 
			
		||||
| 
						 | 
				
			
			@ -269,6 +281,15 @@ module Mach
 | 
			
		|||
                          :mach_port_t],
 | 
			
		||||
                         :kern_return_t)
 | 
			
		||||
 | 
			
		||||
    ###################
 | 
			
		||||
    # Clock functions #
 | 
			
		||||
    ###################
 | 
			
		||||
 | 
			
		||||
    attach_mach_function(:clock_get_time,
 | 
			
		||||
                         [:clock_id_t,
 | 
			
		||||
                          TimeSpec],
 | 
			
		||||
                         :kern_return_t)
 | 
			
		||||
 | 
			
		||||
    #####################
 | 
			
		||||
    # Message functions #
 | 
			
		||||
    #####################
 | 
			
		||||
| 
						 | 
				
			
			@ -312,7 +333,7 @@ module Mach
 | 
			
		|||
                         [:semaphore_t],
 | 
			
		||||
                         :kern_return_t)
 | 
			
		||||
    attach_mach_function(:semaphore_timedwait,
 | 
			
		||||
                         [:semaphore_t, Timespec.val],
 | 
			
		||||
                         [:semaphore_t, TimeSpec.val],
 | 
			
		||||
                         :kern_return_t)
 | 
			
		||||
 | 
			
		||||
  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/port'
 | 
			
		||||
require 'mach/host'
 | 
			
		||||
require 'mach/clock'
 | 
			
		||||
 | 
			
		||||
module Mach
 | 
			
		||||
  class Semaphore < Port
 | 
			
		||||
| 
						 | 
				
			
			@ -61,8 +63,11 @@ module Mach
 | 
			
		|||
      semaphore_wait(port)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # TODO: implement
 | 
			
		||||
    # @see http://pkaudio.blogspot.com/2010/05/mac-os-x-no-timed-semaphore-waits.html
 | 
			
		||||
    def timedwait(secs)
 | 
			
		||||
      timespec = TimeSpec.new
 | 
			
		||||
      timespec.add_seconds!(secs)
 | 
			
		||||
 | 
			
		||||
      semaphore_timedwait(port, timespec)
 | 
			
		||||
    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