NOTE: To understand my question, you might need to know about my project and the problem. If not, skip right to the "QUESTION" section at the bottom.
class BlockingThread
: public BlockingThreadBase // all the Asm magic happens in BlockingThreadBase
{
void StartStopHere(void) // called upon the first Resume() call (pure virtual in base)
{
printf("1"); Pause();
printf("3"); Pause();
printf("5"); Pause();
}
};
int main(void)
{
BlockingThread obj;
obj.Resume(); printf("2");
obj.Resume(); printf("4");
obj.Resume(); printf("6");
return 0;
}
// OUTPUT: 123456
I've tried true threading and several novel ideas but they ended up too slow to transfer between code locations 21 million times per second.
My latest idea is use chunks of the stack (stack buffers) to create the illusion of multiple stacks. When obj1.Resume() is called, it would return to location of its personal stack, New #1 Stack, execute until Pause() and then return to the previous stack location it was at.
How the stack would look without anyBlockingThread objects in main().
_________________
| Normal | Stack |
| Stack | Buffer |
|________|________|
How aBlockingThread object in main() would look like on the stack.
___________________________________
| Normal | Stack | New #1 | Stack |
| Stack | Buffer | Stack | Buffer |
|________|________|________|________|
How twoBlockingThread objects in main() would look like on the stack.
_____________________________________________________
| Normal | Stack | New #1 | Stack | New #2 | Stack |
| Stack | Buffer | Stack | Buffer | Stack | Buffer |
|________|________|________|________|________|________|
When moving to a "new" stack, and then calling obj.Resume() (from main) which in turn call StartStopHere() causes a segfault at the point of calling StartStopHere(). GDB says can't find linker symbol for virtual table for 'BlockingThreadBase' value when I try to get the value of a member variable from BlockingThreadBase. This is why I suspect it has the same problem when trying to find the location of StartStopHere() when it's called.
(ignore the italics words if you didn't read the other sections)
How can I find [and move or copy] the vtable (or its location if that's what's stored) of the class in the [normal] stack [to a new stack]?
I think what you're looking for is cooperative threading. For a fast and simple implementation of it, check out libco. http://byuu.org/files/libco_v16.tar.bz2. The coswitching is implemented in raw assembly and works for x86, x86_64, PPC32 and PPC64. It also has implementation (ab)using setjmp/longjmp and posix ucontext (very slow). The overhead with this kind of stack swizzling is about 5x. 20 million swaps / sec should work fine. There are some test programs included to test speed.
Example:
#include "libco.h"
#include <stdio.h>
static cothread_t t1;
static cothread_t t2;
static void foo(void)
{
for (int i = 1; i < 10; i+=2)
{
printf("%d\n", i);
co_switch(t1); // Swap back to main cothread
}
}
int main(void)
{
// Get a handle to the current coinstance.
t1 = co_active();
t2 = co_create(10000, foo); // New cothread with stacksize 10000.
for (int i = 0; i < 10; i+=2)
{
printf("%d\n", i);
co_switch(t2); // Swap to cothread t2.
}
co_delete(t2);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With