Add time and clock Mach functions; implement Mach::Semaphore#timedwait.

This commit is contained in:
Patrick Mahoney 2012-02-01 21:34:51 -06:00
parent b76bf99947
commit 680527cbab
5 changed files with 101 additions and 7 deletions

24
lib/mach/clock.rb Normal file
View File

@ -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

View File

@ -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

28
lib/mach/host.rb Normal file
View File

@ -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

View File

@ -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

16
lib/mach/time_spec.rb Normal file
View File

@ -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