I'm programming for embedded, resource constrained devices in C.
I have a structure, like this:
typedef struct UjThread{
struct{
UInt32 runInstr;
UInt8* mailbox;
}appBucket;
struct{
UInt32 appId;
UInt32 numInstr;
UInt32 allocMem;
UInt32 eepromStartAddr;
}appContract;
UInt16 spBase; //we use an empty ascending stack
UInt16 spLimit; //also used for "isPtr"
UInt16 localsBase;
UInt32 stack[];
}UjThread;
I start a thread per object and allocate the needed memory (92 bytes for this structure, but I haven't shown all fields). However, some objects won't use the internal appContract and appBucket structures but memory for those structures will still be allocated.
Is there a way to avoid this? To designate internal structures as optional or perhaps extract the size of those internal structures and subtract it from the memory allocation?
I could make two separate structures, one per type of object, but I'd prefer not to since I'd have to adjust my code everywhere to work with the two types of threads.
Consider this implementation of single inheritance that works in C.
Define a base struct that contains all the elements common to both objects. Notice that I've changed the type of the stack
member to a pointer because that's going to have to be a separate allocation in this design.
typedef struct ThreadBase{
UInt16 spBase; //we use an empty ascending stack
UInt16 spLimit; //also used for "isPtr"
UInt16 localsBase;
UInt32 *stack;
}ThreadBase;
Then declare another struct that contains the base object as the first member and appends the extra stuff.
typedef struct ThreadExtra{
ThreadBase base;
struct{
UInt32 runInstr;
UInt8* mailbox;
}appBucket;
struct{
UInt32 appId;
UInt32 numInstr;
UInt32 allocMem;
UInt32 eepromStartAddr;
}appContract;
}ThreadExtra;
Now you can define a ThreadBase object for threads that only need the base stuff. And you can define a ThreadExtra object for the threads that need more. But you can cast the ThreadExtra object to ThreadBase because ThreadBase is the first member of ThreadExtra. So in general purpose code that doesn't deal with the ThreadExtra elements you can treat all the Thread objects as if they are ThreadBase objects.