Lightweight Teensy3.x Fibers Library (C++) Available

Status
Not open for further replies.
Per Warren's suggestion, I used the arm version of nm.exe to list all of the symbols in the core library, fibers, and the ino file, which are the only objects the go into the exapmple application. Neither fiber_getsp nor _sstack appears.

I then modified the statement defining the Fibers object as shown below:

Fibers<6> fibers(2000); // instrument = false (by default)
Fibers<6> fibers(2000,false); // instrument = false
Fibers<6> fibers(2000,true); // instrument = true

For Teensy 3.2, the build succeeds when instrument=false and fails when instrument=true (on symbols fiber_getsp and _sstack). For Teensy 3.5, the build fails in all 3 cases. So, the symbols fiber_getsp and _sstack are not available, and somehow, while building for 3.2 but not for 3.5, the linker detects that those symbol are not required when "instrument = false".

In any case, commenting out the statements within the "if (instrument)" clause avoids the problem for both 3.2 and 3.5.

Warren, is there any reason to be concerned about rounding stack space up, i.e. allocation more bytes of stack than the user requested? Would it be safer to truncate, i.e. allocate the largest number of uint32_t possible for the requested number of bytes?

Joe
 
Per Warren's suggestion, I used the arm version of nm.exe to list all of the symbols in the core library, fibers, and the ino file, which are the only objects the go into the exapmple application. Neither fiber_getsp nor _sstack appears.

I then modified the statement defining the Fibers object as shown below:

Fibers<6> fibers(2000); // instrument = false (by default)
Fibers<6> fibers(2000,false); // instrument = false
Fibers<6> fibers(2000,true); // instrument = true

For Teensy 3.2, the build succeeds when instrument=false and fails when instrument=true (on symbols fiber_getsp and _sstack). For Teensy 3.5, the build fails in all 3 cases. So, the symbols fiber_getsp and _sstack are not available, and somehow, while building for 3.2 but not for 3.5, the linker detects that those symbol are not required when "instrument = false".

The only thing I can figure is that the routine fiber_getsp() was provided originally and got lost along the way. Perhaps someone can check my git repo history to see if it was there at an earlier revision. But usually I develop offline before it makes it to github, so it may have been lost before that point. Anyway, the #if 0 trick will work around the issue for now.

Warren, is there any reason to be concerned about rounding stack space up, i.e. allocation more bytes of stack than the user requested? Would it be safer to truncate, i.e. allocate the largest number of uint32_t possible for the requested number of bytes?

This is really a "no win" game. If someone says they need 35 bytes, is it really safe to only assume 32? What if they really need that extra word but specified it incorrectly? Alternatively, if they required a huge odd number of bytes but after we round up, the size is too large to accommodate the stack. Without knowing the max stack size, we can't win on this score.

It's similar to allocating a char buffer in C/C++. You never want to allocate less than requested (bar maximum restrictions), so rounding up is the normal practice.

But at the end of the day, if the caller provides bad information, the best you can do is punt or go for it (apologies for the American football terms). If you punt (add more than requested) then any bug experienced is the caller's fault. If you "go for it" (allocate less), then they could fault your library when the stack gets overrun. Since the library should not be at fault, I would err on the side of a punt.
 
Even if the code compiles with instrumentation removed, it still doesn't work on a Teensy 3.6, while the Zilch implementation does. At first glance, the assembler parts between the two look very different. If this was AVR code then I could probably tell what's going on, but I've never written ARM assembler, let alone read someone else's.
 
Even if the code compiles with instrumentation removed, it still doesn't work on a Teensy 3.6, while the Zilch implementation does. At first glance, the assembler parts between the two look very different. If this was AVR code then I could probably tell what's going on, but I've never written ARM assembler, let alone read someone else's.

I understand that and I'd like to help. But I don't have a Teensy 3.6 currently, nor the time right now to investigate the changes needed. It appears that some architectural differences are involved requiring different registers to be saved/restored in a context change.
 
But I don't have a Teensy 3.6 currently, nor the time right now to investigate the changes needed.

Of course, you explained that and I absolutely understand it! I appreciate your help so far. Duff's library does the job for now.
 
I'm using Zilch with success on Teensy 3.2 and 3.5. Have you tried it on Teensy LC?

One small issue in Zilch::create(). The line below increments num_task when already at its maximum. This will cause yield() to access beyond the end of the context array.

if ( ++num_task >= MAX_TASKS ) return TaskInvalid;

It should be split into two statements:

if ( (num_task + 1) >= MAX_TASKS ) return TaskInvalid;
++num_task;
 
I'm using Zilch with success on Teensy 3.2 and 3.5. Have you tried it on Teensy LC?

One small issue in Zilch::create(). The line below increments num_task when already at its maximum. This will cause yield() to access beyond the end of the context array.

if ( ++num_task >= MAX_TASKS ) return TaskInvalid;

It should be split into two statements:

if ( (num_task + 1) >= MAX_TASKS ) return TaskInvalid;
++num_task;
Correct! Thanks i'll fix that now.
 
I see that you already updated your git repository. Thanks. This is less important, but yesterday we discussed another small issue in Fibers (and also Zilch).

In both create() and init_stack()

int s_size = ( stack_size + sizeof ( uint32_t ) ) / sizeof ( uint32_t ) * sizeof ( uint32_t );

should be

int s_size = ( stack_size + sizeof ( uint32_t ) - 1 ) / sizeof ( uint32_t ) * sizeof ( uint32_t );
 
Here are somethings I've been working on using a custom implementation of Zlich. The library I created is called Teensy Tracks and it is inspired from Apples Garage Band and can be used with the Audio Library. This video is of one of the example's in the library.
 
int s_size = ( stack_size + sizeof ( uint32_t ) ) / sizeof ( uint32_t ) * sizeof ( uint32_t );

should be

int s_size = ( stack_size + sizeof ( uint32_t ) - 1 ) / sizeof ( uint32_t ) * sizeof ( uint32_t );
ok, this work properly so done!

Probably should start a new thread for Zlich related stuff, I don't wanna hijack this thread anymore.
 
Status
Not open for further replies.
Back
Top