module Ragweed; end module Ragweed::Wraposx::ThreadInfo # info interfaces BASIC_INFO = 3 #basic information # following are obsolete interfaces # according to the source @ fxr they still work except FIFO SCHED_TIMESHARE_INFO = 10 SCHED_RR_INFO = 11 # SCHED_FIFO_INFO = 12 module State #Thread run states RUNNING = 1 #/* thread is running normally */ STOPPED = 2 #/* thread is stopped */ WAITING = 3 #/* thread is waiting normally */ UNINTERRUPTIBLE = 4 #/* thread is in an uninterruptible wait */ HALTED = 5 #/* thread is halted at a clean point */ end # struct thread_basic_info # { # time_value_t user_time; # time_value_t system_time; # integer_t cpu_usage; # policy_t policy; # integer_t run_state; # integer_t flags; # integer_t suspend_count; # integer_t sleep_time; # }; class Basic < FFI::Struct include Ragweed::FFIStructInclude module Flags #Thread flags (flags field). SWAPPED = 0x1 #/* thread is swapped out */ IDLE = 0x2 #/* thread is an idle thread */ end FLAVOR = Ragweed::Wraposx::ThreadInfo::BASIC_INFO layout :user_time, Ragweed::Wraposx::TimeValue, :system_time, Ragweed::Wraposx::TimeValue, :cpu_usage, :int, :policy, Ragweed::Wraposx::Libc.find_type(:policy_t), :run_state, :int, :flags, :int, :suspend_count, :int, :sleep_time, :int def dump(&block) maybe_hex = lambda {|a| begin; "\n" + (" " * 9) + block.call(a, 16).hexdump(true)[10..-2]; rescue; ""; end } maybe_dis = lambda {|a| begin; "\n" + block.call(a, 16).distorm.map {|i| " " + i.mnem}.join("\n"); rescue; ""; end } string =< {:size => 30, :count => 10, :class => Basic}, # define POLICY_TIMESHARE_INFO_COUNT ((mach_msg_type_number_t)(sizeof(struct policy_timeshare_info)/sizeof(integer_t))) SCHED_TIMESHARE_INFO => {:size => 20, :count => 5, :class => SchedTimeshare}, # define POLICY_RR_INFO_COUNT ((mach_msg_type_number_t)(sizeof(struct policy_rr_info)/sizeof(integer_t))) SCHED_RR_INFO => {:size => 20,:count => 5, :class => SchedRr}, # define POLICY_FIFO_INFO_COUNT ((mach_msg_type_number_t)(sizeof(struct policy_fifo_info)/sizeof(integer_t))) # SCHED_FIFO_INFO => {:size => 16,:count => 4} # immediately returns KERNEL_INVALID_POLICY on osx } end module Ragweed::Wraposx class << self # Returns the packed string representation of the thread_info_t struct for later parsing. # # kern_return_t thread_info # (thread_act_t target_thread, # thread_flavor_t flavor, # thread_info_t thread_info, # mach_msg_type_number_t thread_info_count); def thread_info(thread, flavor) info = FFI::MemoryPointer.new(ThreadInfo::FLAVORS[flavor][:class], 1) count = FFI::MemoryPointer.new(:int, 1).write_int(ThreadInfo::FLAVORS[flavor][:count]) r = Libc.thread_info(thread, flavor, info, count) raise KernelCallError.new(r) if r != 0 ThreadInfo::FLAVORS[flavor][:class].new info end end end