Defragster, I tried to run the code with the modifications you mentioned in your last post (#48) and could also reproduce the behavior you have shown. Very weird. I have no idea what caused this.
That's interesting. I modified my last code (post #46) to memset all allocated heap and also use our stack and was still able to successfully and reliably malloc() from any thread. I have also performed a simple check for heap and stack integrity, and it seems to work. I don't know if the test I made was enough to prove anything, but what do you think?
Does this code also works for you? I stopped using printf as it seems to cause many problems and in my full code I have already started to use the arduino-printf library, which is malloc free.
I tried a few more things, including having the thread stacks on the stack of the main thread, and I think the fundamental problem is the same. If you call malloc() with different stack pointers, you can overwrite memory you did not intend. I added call to memset() in thread_loop() to set all malloc'd bytes to 0xFF. When I do this, only the main thread continues to run.
That's interesting. I modified my last code (post #46) to memset all allocated heap and also use our stack and was still able to successfully and reliably malloc() from any thread. I have also performed a simple check for heap and stack integrity, and it seems to work. I don't know if the test I made was enough to prove anything, but what do you think?
Code:
#include <Arduino.h>
#include <TeensyThreads.h>
#define SIZE_ALLOC 2500 // JWP 500
#define STK_CHK_SIZE 800
uint32_t total_bytes_alloc = 0;
uint32_t thread_bytes_alloc[5] = {0,0,0,0,0};
bool threads_created = false;
void thread_loop( int threadID )
{
int numLoops = 0;
char stkSig[STK_CHK_SIZE];
for ( int ii = 0; ii < STK_CHK_SIZE; ii++ ) stkSig[ii] = (char)threadID; // Set markers on out thread stack
while(1) {
numLoops++;
char* pointer = (char*)malloc(SIZE_ALLOC);
if (pointer) {
thread_bytes_alloc[threadID] += SIZE_ALLOC;
total_bytes_alloc += SIZE_ALLOC;
memset(pointer, (char)threadID, SIZE_ALLOC); // Set markers on the heap we allocated
Serial.print("Thread ");
Serial.print(threadID);
Serial.print(" loop #");
Serial.print(numLoops);
Serial.print(" malloc ");
Serial.print(SIZE_ALLOC);
Serial.print(". Addr = 0x");
Serial.print((uint32_t)pointer, HEX);
Serial.print(". thread_total = ");
Serial.print(thread_bytes_alloc[threadID]);
Serial.print(". total = ");
Serial.println(total_bytes_alloc);
bool heap_corrupted = false;
for ( int ii = 0; ii < SIZE_ALLOC; ii++ )
{
if(pointer[ii] != (char)threadID) heap_corrupted = true; // Check for heap integrity
}
if(heap_corrupted) Serial.printf("Thread #%d heap corruped!\n", threadID);
}
else
{
Serial.print("Thread ");
Serial.print(threadID);
Serial.print(" loop #");
Serial.print(numLoops);
Serial.println(" malloc failed!");
}
bool stack_corrupted = false;
for ( int ii = 0; ii < STK_CHK_SIZE; ii++ )
{
if(stkSig[ii] != (char)threadID) stack_corrupted = true; // Check for stack integrity
}
if(stack_corrupted) Serial.printf("Thread #%d stack corruped!\n", threadID);
threads.delay(100);
}
}
void thread_func( void *param )
{
thread_loop( (int)param );
}
void setup()
{
Serial.begin(9600);
delay(3000);
}
void loop()
{
int threadStackSize = 1024;
int threadCount = 4;
char threadsStack[threadCount][threadStackSize]; // The stack of the threads are created on the stack of the loop()
if(!threads_created)
{
// Only runs once
for (int i=1; i<=threadCount; i++)
threads.addThread(thread_func, (void*)i, threadStackSize, threadsStack[i-1]); // threads stack are now on the main stack
Serial.println(threads.threadsInfo()); // Information for thread 0 (main) is incorrect, information for thread 1 is missing
threads_created = true;
}
thread_loop(0);
}
Does this code also works for you? I stopped using printf as it seems to cause many problems and in my full code I have already started to use the arduino-printf library, which is malloc free.