more on InterruptAttachEvent on SMP

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;
}

“Dennis” <dmoses@z-kat.com> wrote in message
news:a8anjt$7al$1@inn.qnx.com

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 ?

I was able to reproduce your problem. I’m not sure I understand exactly
what is happening. Under SMP priority aren’t as “meaningfull” as on a
single CPU machine, can easy play trick on the mind :wink: While your
priority 63 thread runs on CPU 1, other thread of lower priority
are running CPU 2 affecting what is happening on the CPU 1.

There is a solution though, don’t use affinity mask.


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;
}

Thanks for your suggestion. I hate to say this, but I am kinda glad you
could reproduce the behaviour. Hopefully that means it is not hardware
related.

I was able to reproduce your problem. I’m not sure I understand exactly
what is happening. Under SMP priority aren’t as “meaningfull” as on a
single CPU machine, can easy play trick on the mind > :wink: > While your
priority 63 thread runs on CPU 1, other thread of lower priority
are running CPU 2 affecting what is happening on the CPU 1.

There is a solution though, don’t use affinity mask.

If I donot assign affinity does ClockCycles hold any meaning ? How do I
check the timing without ClockCycles ?

Anyways, I believe it is some thing wierd in the way the interrupts are
handled. When I assigned the affinity to processor 2 the fluctuations were
less significant (not as nice as the single processor…still better).
More importantly if I set up a InterruptMask to mask all the other
interrupts, I get very nice results. Ofcource this is not an option cause
this disables even the mouse and keyboard :slight_smile:

Any more suggestions / comments are greatly appreciated.

Thanks
Dennis







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;
}
\

“Dennis” <dmoses@z-kat.com> wrote in message
news:a8cfhi$f2f$1@inn.qnx.com

Thanks for your suggestion. I hate to say this, but I am kinda glad you
could reproduce the behaviour. Hopefully that means it is not hardware
related.

I was able to reproduce your problem. I’m not sure I understand exactly
what is happening. Under SMP priority aren’t as “meaningfull” as on a
single CPU machine, can easy play trick on the mind > :wink: > While your
priority 63 thread runs on CPU 1, other thread of lower priority
are running CPU 2 affecting what is happening on the CPU 1.

There is a solution though, don’t use affinity mask.

If I donot assign affinity does ClockCycles hold any meaning ?

Not really, however my experience is that it’s not too bad.
My understanding is that the counter is reseted at boot time, hence
it’s usually reset by the same signal and the chip are normal
feed the same clock source (some MB allow chip to be
on different frequency though). It’s definitively not a good idea
to use ClockCylces on SMP though ;l

How do I check the timing without ClockCycles ?

You can meaure using standard timer routine (such as clock() ),
but it’s only precise down to the tick size.

Anyways, I believe it is some thing wierd in the way the interrupts are
handled. When I assigned the affinity to processor 2 the fluctuations
were
less significant (not as nice as the single processor…still better).
More importantly if I set up a InterruptMask to mask all the other
interrupts, I get very nice results. Ofcource this is not an option cause
this disables even the mouse and keyboard > :slight_smile:

Any more suggestions / comments are greatly appreciated.

Thanks
Dennis


\

clock doesnt seem to measure small times (<1ms ). I might be doing
something wrong. I will check it out.

Assuming clockcycles does a good job. I tried to run the same code without
the processor affinity mask and still got rather unacceptable results.
max_time ~= 2540 and min_time ~= 300 (us) !!

I ruled out the possibility of some ISR taking long amount of time because
if that were the case it should happen in the single processor system as
well. Intution inclines me to believe it has to do with the way the
Interrupts (the IPI type ) are used to schedule pulses or probably the
threads. I hope i am very wrong in saying that !

By the way I did another test. I used InterruptAttach to write a small ISR
that does the work instead of a thread doing the interrupt serviceing. I
got lesser fluctuations (max_time 1220 , min_time 860 (us)…still not as
nice as the single processor). Futher leading me to believe it has to do
with the scheduling of pulses.



“Mario Charest” <goto@nothingness.com> wrote in message
news:a8ciaa$h10$1@inn.qnx.com

“Dennis” <> dmoses@z-kat.com> > wrote in message
news:a8cfhi$f2f$> 1@inn.qnx.com> …
Thanks for your suggestion. I hate to say this, but I am kinda glad you
could reproduce the behaviour. Hopefully that means it is not hardware
related.

I was able to reproduce your problem. I’m not sure I understand
exactly
what is happening. Under SMP priority aren’t as “meaningfull” as on a
single CPU machine, can easy play trick on the mind > :wink: > While your
priority 63 thread runs on CPU 1, other thread of lower priority
are running CPU 2 affecting what is happening on the CPU 1.

There is a solution though, don’t use affinity mask.

If I donot assign affinity does ClockCycles hold any meaning ?

Not really, however my experience is that it’s not too bad.
My understanding is that the counter is reseted at boot time, hence
it’s usually reset by the same signal and the chip are normal
feed the same clock source (some MB allow chip to be
on different frequency though). It’s definitively not a good idea
to use ClockCylces on SMP though ;l

How do I check the timing without ClockCycles ?

You can meaure using standard timer routine (such as clock() ),
but it’s only precise down to the tick size.


Anyways, I believe it is some thing wierd in the way the interrupts are
handled. When I assigned the affinity to processor 2 the fluctuations
were
less significant (not as nice as the single processor…still better).
More importantly if I set up a InterruptMask to mask all the other
interrupts, I get very nice results. Ofcource this is not an option
cause
this disables even the mouse and keyboard > :slight_smile:

Any more suggestions / comments are greatly appreciated.

Thanks
Dennis




\

“Dennis” <dmoses@z-kat.com> wrote in message
news:a8copp$ldv$1@inn.qnx.com

clock doesnt seem to measure small times (<1ms ). I might be doing
something wrong. I will check it out.

Normal, that what I meant by ticksize.

One quick thought, have you tried not setting you affinity to be the
first processor (ie. don’t set the affinity). Is there a reason why you
need to have your handler running on CPU 0?


Cheers,
Adam

QNX Software Systems Ltd.
[ amallory@qnx.com ]

With a PC, I always felt limited by the software available.
On Unix, I am limited only by my knowledge.
–Peter J. Schoenster <pschon@baste.magibox.net>



“Dennis” <dmoses@z-kat.com> wrote in news:a8anjt$7al$1@inn.qnx.com:

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;
}

One quick thought, have you tried not setting you affinity to be the
first processor (ie. don’t set the affinity).

I did try that approach, ie. not setting the processor affinity. I still
dont get acceptable results. (max_time ~= 2540 and min_time ~= 300 (us) !!
expected is ~ 1000(us)). Though I must say it is not as bad as assingning
processor affinity to 0x1. Also as a note, if I assign processor affinity
to 0x2 then it is a lot better (± 350 (us)). But this is still not as
consistant as the single processor (± 50 (us)).

Is there a reason why you
need to have your handler running on CPU 0?

It really doesnt have to be processor 0, but being able to control which
processor to run a thread will be very useful for our application. It may
end up needing to run two different threads ( each doing lot of work) to run
at the same time, that was the primary reason for the switch to SMP.

If I may ask why should it matter if it is on processor 0 or 1. I know the
interrupts are handled by processor 0, but will this add such significant
delays ?? if so why doesnt this happen on a single processor machine ?

Dennis


Cheers,
Adam

QNX Software Systems Ltd.
[ > amallory@qnx.com > ]

With a PC, I always felt limited by the software available.
On Unix, I am limited only by my knowledge.
–Peter J. Schoenster <> pschon@baste.magibox.net



“Dennis” <> dmoses@z-kat.com> > wrote in news:a8anjt$7al$> 1@inn.qnx.com> :

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;
}

It really doesnt have to be processor 0, but being able to control which
processor to run a thread will be very useful for our application. It may
end up needing to run two different threads ( each doing lot of work) to
run
at the same time, that was the primary reason for the switch to SMP.

You are MUCH better letting the kernel assign threads to the CPUs and
not play with affinity mask. kernel seems to be very smart at this stuff
and makes best usage of available CPU cycles!


If I may ask why should it matter if it is on processor 0 or 1. I know
the
interrupts are handled by processor 0, but will this add such significant
delays ?? if so why doesnt this happen on a single processor machine ?

Dennis

\

Cheers,
Adam

QNX Software Systems Ltd.
[ > amallory@qnx.com > ]

With a PC, I always felt limited by the software available.
On Unix, I am limited only by my knowledge.
–Peter J. Schoenster <> pschon@baste.magibox.net



“Dennis” <> dmoses@z-kat.com> > wrote in news:a8anjt$7al$> 1@inn.qnx.com> :

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;
}
\

I guess the kernel is much smarter as far as scheduling goes. And that is
how I had all my code setup to begin with. But then I keep running into the
same ol problem of large delays between interrupt events. (we use
interrupts for timing, so delays are not acceptable). I was hoping to avoid
time used by the kernel in deciding which processor to run the code on.
(but I guess this shouldnt take too long anyways). Simplistically thinking
I thought that would be a big difference in scheduling…I know it is not
right to think that way…but I was running out of ideas !

Thanks for the help. I will switch back to “no processor affinity” and
start working on the problem again with a different approach…

Dennis

“Mario Charest” <goto@nothingness.com> wrote in message
news:a8cuha$p6g$1@inn.qnx.com

It really doesnt have to be processor 0, but being able to control which
processor to run a thread will be very useful for our application. It
may
end up needing to run two different threads ( each doing lot of work) to
run
at the same time, that was the primary reason for the switch to SMP.

You are MUCH better letting the kernel assign threads to the CPUs and
not play with affinity mask. kernel seems to be very smart at this stuff
and makes best usage of available CPU cycles!



If I may ask why should it matter if it is on processor 0 or 1. I know
the
interrupts are handled by processor 0, but will this add such
significant
delays ?? if so why doesnt this happen on a single processor machine ?

Dennis

\

Cheers,
Adam

QNX Software Systems Ltd.
[ > amallory@qnx.com > ]

With a PC, I always felt limited by the software available.
On Unix, I am limited only by my knowledge.
–Peter J. Schoenster <> pschon@baste.magibox.net



“Dennis” <> dmoses@z-kat.com> > wrote in news:a8anjt$7al$> 1@inn.qnx.com> :

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;
}


\