Created
April 21, 2011 01:56
-
-
Save pbosetti/933511 to your computer and use it in GitHub Desktop.
Recurring process triggered by SIGALARM via ualarm FFI mapping
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# untitled.rb | |
# Created by Paolo Bosetti on 2011-04-20. | |
# Copyright (c) 2011 University of Trento. All rights reserved. | |
require "rubygems" | |
require 'ffi' | |
class Array | |
def mean | |
self.inject {|sum,i| sum + i} / size | |
end | |
def sd | |
m = self.mean | |
v = self.inject(0.0) {|sum,i| sum + (i - m)**2} | |
Math::sqrt(v / (size - 1.0)) | |
end | |
end | |
# Importo le funzioni di sistema alarm e ualarm | |
module Alarm | |
extend FFI::Library | |
if RUBY_PLATFORM =~ /darwin/ | |
so_ext = 'dylib' | |
else | |
so_ext = 'so' | |
end | |
ffi_lib "libc.#{so_ext}" | |
attach_function :ualarm, [:uint, :uint], :uint | |
attach_function :alarm, [:uint], :uint | |
enum :which, [ | |
:prio_process, 0, | |
:prio_pgrp, | |
:prio_user, | |
:prio_darwin_thread, | |
:prio_darwin_process ] | |
attach_function :setpriority, [:which, :uint, :int], :int | |
end | |
result = Alarm.setpriority(:prio_process,0,-20) | |
puts "Setting max priority: #{result == 0 ? 'success' : 'failure (missing sudo?)'}" | |
# Esco quando si preme ^C | |
Signal.trap("SIGINT") do | |
exit | |
end | |
# Un po' di parametri | |
STEP = 0.02 | |
CYCLES = 100 | |
USECS = (STEP * 1E6).to_i | |
puts "Timer: #{USECS} usec" | |
times = [] | |
i = 0 | |
running = true | |
# La thread di analisi dei dati. Si mette subito in pausa, in attesa di | |
# ripartire quando la generazione di dati è terminata | |
analysis = Thread.start do | |
sleep | |
delta = [] | |
times.each_with_index do |t,i| | |
delta << (t - times[i-1]) if i > 0 | |
end | |
puts "mean #{delta.mean}, st.dev #{delta.sd}" | |
puts "min #{delta.min} max #{delta.max}" | |
exit | |
end | |
# Gestione dell'allarme generato dall'interrupt di sistema | |
Signal.trap("ALRM") do | |
# Sto generando dati | |
if running | |
times << Time.now | |
i += 1 | |
end | |
# Ho finito di generare i dati | |
if i >= CYCLES | |
running = false | |
analysis.wakeup if analysis.alive? # faccio ripartire l'analisi (adesso che ha tutti i dati) | |
end | |
end | |
# Imposto l'allarme dopo USECS, e poi ricorrente ogni USECS | |
Alarm.ualarm(USECS, USECS) | |
# Aspetto che l'analisi abbia terminato, poi esco. | |
analysis.join |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment