This more of an addendum to my previous post regarding problems we are
having with regard to interrupts on an SMP machine. I realize my last post
had code that required specific hardware and libraries to run, sorry about
that.
So here is a simpler version of the code that shows the problem I am facing.
This code basically attaches an event (pulse) to the SYSPAGE(qtime)->intr
interrupt. And calculates the time taken between interrupts using
ClockCycles. It is running at max priority (63).
Running this code on a single processor machine, no matter what I do, I get
max_time ~= 1070 and min_time ~= 967 (us) very consistantly.
On an SMP machine without moving the mouse or doing anything I get similar
results. But if I do stuff like move the mouse arround and open/close a
voyager and open/close a helpviewer, the max_time jumps to 6000+ us (worst
case) and min_time goes to 500 us. (i.e. highly inconsistant !!). What
should I do to avoid this ?
Please help me in this regard.
Thanks
Dennis
code
#include <stdio.h>
#include <sys/neutrino.h>
#include <sys/syspage.h>
static uint64_t processor_cycles_per_sec;
struct sigevent event;
volatile unsigned counter;
static uint64_t cycles_per_period;
int channel_id;
double ticks_to_ms(uint64_t tme)
{
return (((double)(tme))/processor_cycles_per_sec);
}
int main()
{
int i,id,t,t_last;
double time_taken;
double max_time=0;
double min_time=1;
int intr;
struct _pulse pulse;
int coid;
// Set priority and set processor affinity
ThreadCtl (_NTO_TCTL_IO,0);
ThreadCtl (_NTO_TCTL_RUNMASK,(void *)0x01);
setprio(0,63);
// Create a channel
channel_id = ChannelCreate(0);
coid = ConnectAttach(0,0,channel_id,0,0);
// Initialize pulse
SIGEV_PULSE_INIT(&event,coid,63,0,0);
// data for calculating time taken
processor_cycles_per_sec = (SYSPAGE_ENTRY(qtime)->cycles_per_sec);
// Attach event to interrupt
id = InterruptAttachEvent(SYSPAGE_ENTRY(qtime)->intr, &event, 0);
// start the loop
t_last = ClockCycles();
for (i=0;i<10000+11;i++)
{
// block for interrupt and unmask when pulse is received
MsgReceive(channel_id,&pulse,sizeof(pulse),NULL);
InterruptUnmask(SYSPAGE_ENTRY(qtime)->intr,id);
// cal
t = ClockCycles();
time_taken = ticks_to_ms(t-t_last);
t_last = t;
// ignore the first 10 readings (might be doing some init stuff)
// not requred after ignoring the first event
if (i>10)
{
max_time = (time_taken>max_time)?time_taken:max_time;
min_time = (time_taken<min_time)?time_taken:min_time;
}
}
InterruptDetach(id);
printf(“max time = %f (us)\nmin time =
%f(us)\n”,max_time1e6,min_time1e6);
return 0;
}