For a little app, I need to send stream over UDP at a fixed rate. I have done severals tests w/ some buffers and sleep(), but I can’t achieve the desired speed. Mainly because sleep() doesn’t provide a stable enought result.
I decided to look at this a little deeply, and decided to use /dev/rtc to do the trick. Here a little example of the stuff.
from fcntl import ioctl import os, time # some linux kernel header RTC_IRQP_SET = 1074032652 RTC_PIE_ON = 28677 RTC_PIE_OFF = 28678 # open the realtime clock f = open ("/dev/rtc", "r") fd = f.fileno() # 2048 freq ioctl(fd,RTC_IRQP_SET,2048) ioctl(fd,RTC_PIE_ON,0) t0 = time.time() interupt = 0 # the read will block until the next interrupt. while interupt < 1000 : os.read(fd,4) # 4 = size of double interupt = interupt + 1 delta = time.time() - t0 print interupt / delta # drop the scheduler ioctl(fd,RTC_PIE_OFF,0)
This is quite accurate enought, the only issue is that I’m unable to call the sched_setscheduler() from Python right now. So, if the host isn’t loaded I get the 2048 interrupts.. but it can be less :(
The sched_setscheduler can be done w/ a simple pyrex extension:
cdef extern from "sched.h": struct sched_param: int sched_priority int sched_setscheduler(int pid, int policy,sched_param *p) SCHED_FIFO = 1 def switchRTCPriority(nb): cdef sched_param sp sp.sched_priority = nb sched_setscheduler (0,SCHED_FIFO , &sp);
After this quick Pyrex hack, I now have a accurate realtime interrupt in Python ;)