Skip to content

Instantly share code, notes, and snippets.

@pbosetti
Created April 21, 2011 01:56
Show Gist options
  • Save pbosetti/933511 to your computer and use it in GitHub Desktop.
Save pbosetti/933511 to your computer and use it in GitHub Desktop.
Recurring process triggered by SIGALARM via ualarm FFI mapping
#!/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