Passing a variable to a job

89 views
Skip to first unread message

David Silcott

unread,
Jul 9, 2011, 3:49:10 PM7/9/11
to bareme...@googlegroups.com
Hi,

I am trying to pass parameters to queued jobs and have the jobs print out the parameter which was passed to them at the bottom of this email is one of my attempts at it. 
Every other parameter is printed out as 2097334. I seem to be doing something wrong but cannot figure out what it is. 

The output I am getting is as follows:

3
2097334
2
2097334
8
Jobs completed. Terminating


Also, shouldn't  b_smp_run() accept a var parameter?

What I am eventually aiming to have is a shared array of buffers and a job which does some work on a buffer. Whenever something comes in over the nic interface a free buffer is populated with the b_ethernet_rx() call 
and the index of the buffer is queued with the job to be picked up later by a processor.



Thanks
David

======================================================================================================================================



int main(void)
{
   unsigned long j, local = 0;
   unsigned long numArr[5] = {3, 4, 2, 5, 8};

   for(j = 0; j <5; j++)
   {
      b_smp_enqueue(&sample_process, numArr[j]);
   }

   while (b_smp_queuelen() != 0) // Check the length of the queue. If greater than 0 then try to run a queued job.
   {
      unsigned long tvar;
      local = b_smp_dequeue( &tvar ); // Grab a job from the queue. b_smp_dequeue returns the memory address of the code
      if (local != 0) // If it was set to 0 then the queue was empty
         b_smp_run(local); // Run the code
   }

   b_smp_wait();

   b_print_string("Jobs completed. Terminating\n");

   return 0;
}


void sample_process(unsigned long incrVal)
{
   unsigned char NumAsStr[10];

   b_int_to_string(incrVal, NumAsStr);
   b_print_string(NumAsStr);
   b_print_newline();

   // wait 1 second
   b_delay(8);
}

Ian Seyler

unread,
Jul 10, 2011, 10:13:33 PM7/10/11
to BareMetal OS
I'll take a look into this one as well. I think the issue is int
b_smp_run().

-Ian


On Jul 9, 3:49 pm, David Silcott <d.silc...@gmail.com> wrote:
> Hi,
>
> I am trying to pass parameters to queued jobs and have the jobs print out
> the parameter which was passed to them at the bottom of this email is one of
> my attempts at it.
> Every other parameter is printed out as 2097334. I seem to be doing
> something wrong but cannot figure out what it is.
>
> The output I am getting is as follows:
>
> 3
> 2097334
> 2
> 2097334
> 8
> Jobs completed. Terminating
>
> Also, shouldn't * b_smp_run()* accept a var parameter?
>
> What I am eventually aiming to have is a shared array of buffers and a job
> which does some work on a buffer. Whenever something comes in over the nic
> interface a free buffer is populated with the* b_ethernet_rx()* call

Ian Seyler

unread,
Jul 14, 2011, 11:45:01 AM7/14/11
to BareMetal OS
This is a confirmed bug again. I have duplicated the results on a VM.

b_smp_run should accept two parameters. The code address as well as
the variable.

I get better (though inconsistent) results with this in
libBareMetal.c:

void b_smp_run(unsigned long ptr, unsigned long var)
{
asm volatile ("call *0x00100358" : : "a"(ptr), "D"(var));
}

I'm still working on it.

-Ian

Ian Seyler

unread,
Jul 14, 2011, 1:30:24 PM7/14/11
to BareMetal OS
It looks like the issue may be in os_smp_dequeue (or rather the C
implementation) as seen in the following line:

local = b_smp_dequeue( &tvar ); // Grab a job from the queue.

tvar does not have the correct value after it is run. Stepping through
the code with a debugger it looks ok but ends up pulling some other
value from the stack.

This seems to be related to the b_mem_free issue as well since
b_mem_allocate passes a variable by reference as well (which is
getting clobbered)

The issue must be in the C<->Assembly glue of libBareMetal.c

-Ian

lavapatch

unread,
Jul 14, 2011, 5:55:15 PM7/14/11
to bareme...@googlegroups.com
Thanks again

David

Ian Seyler

unread,
Jul 15, 2011, 10:18:16 AM7/15/11
to BareMetal OS
unsigned long b_smp_dequeue(unsigned long *var)
{
unsigned long tlong, tvar = 0;
unsigned char numstr[30];
asm volatile ("call *0x00100228" : "=a"(tlong), "=D"(tvar));
b_print_string("tvar - ");
b_int_to_string(tvar, numstr);
b_print_string(numstr);
return tlong;
}

"tvar" has the correct value. I'm just stuck on getting that data back
into "var". Still working on it.

-Ian

Ian Seyler

unread,
Jul 15, 2011, 10:37:46 AM7/15/11
to BareMetal OS
Embarrassing... NGG provided a fix for this back in September!

http://code.google.com/p/baremetal/issues/detail?id=8

This is the correct b_smp_dequeue:

unsigned long b_smp_dequeue(unsigned long *var)
{
unsigned long tlong;
asm volatile ("call *0x00100228" : "=a"(tlong), "=D"(*(var)));
return tlong;
}

The program runs correctly now.

int main(void)
{
unsigned long j, local = 0;
unsigned long numArr[8] = {1, 2, 3, 4, 5, 6, 7, 8};

for(j = 0; j <8; j++)
{
b_smp_enqueue(&sample_process, numArr[j]);
}

while (b_smp_queuelen() != 0) // Check the length of the queue. If
greater than 0 then try to run a queued job.
{
unsigned long tvar;
local = b_smp_dequeue( &tvar ); // Grab a job from the queue.
b_smp_dequeue returns the memory address of the code
if (local != 0) // If it was set to 0 then the queue was empty
{
b_smp_run(local, tvar); // Run the code
}
}

b_smp_wait();
b_print_string("Jobs completed. Terminating\n");
return 0;
}

-Ian


On Jul 15, 10:18 am, Ian Seyler <isey...@gmail.com> wrote:

lavapatch

unread,
Jul 15, 2011, 12:45:33 PM7/15/11
to bareme...@googlegroups.com
Thanks,

I will make the corrections on my end.

David

lavapatch

unread,
Apr 26, 2012, 5:48:43 PM4/26/12
to bareme...@googlegroups.com
Hi Ian,

Sorry to resurrect this thread but apparently the problem seems to be still lingering.

The solution you posted above only works when the CPU which runs the main method is explicitly asked to execute a job on the queue. All of the other CPUs print an incorrect value when they take a job from the queue.

Eg. 

When the condition for the while block is  while (b_smp_queuelen() != 0) , the correct value is only printed when the CPU running the main method takes a job so the output looks like

1
4
1
5
1

If I change the while block to while (b_smp_queuelen() > 10)  the following output is printed

1
1
1
1
1


It seems as if there may be a bug with the code which is responsible for taking jobs off the queue for other CPUs. Why guess is that it does not know when parameters are passed in.

I am currently testing on BareMetal OS  0.5.3 

Thoughts?


David

Ian Seyler

unread,
Apr 26, 2012, 10:06:33 PM4/26/12
to bareme...@googlegroups.com
This is with the same source code you posted earlier?

-Ian

lavapatch

unread,
Apr 27, 2012, 12:54:37 AM4/27/12
to bareme...@googlegroups.com
Yes, only difference is the main method has been updated as per your previous response.

Ian Seyler

unread,
May 16, 2012, 11:41:21 AM5/16/12
to bareme...@googlegroups.com
Ok. I will take another look into this.
Reply all
Reply to author
Forward
0 new messages