Here is a crude little try of mine: have not programmed this type of
base logic for efficient multi-threading in a while. So, try to not to
flame me too hard wrt the following code:
____________________________
#include <cstdio>
#include <cstdint>
#include <cstdlib>
#if ! defined (CT_CLSIZE_DEFAULT)
# define CT_CLSIZE_DEFAULT 64
#endif
#if ! defined (CT_CLSIZE)
# define CT_CLSIZE CT_CLSIZE_DEFAULT
#endif
// Change this to:
template<typename T, std::size_t T_clsize = CT_CLSIZE>
struct ct_cache_line_pad
{
alignas(T_clsize) T data;
// alignas can pad at will!
// Uncomment the following line for a forced padding error...
// unsigned char pad[T_clsize];
static_assert(sizeof(T) <= T_clsize, "T greater than cache line!");
};
// a random user defined foo...
struct foo
{
unsigned char id;
unsigned int seq;
};
int main()
{
typedef ct_cache_line_pad<foo> foo_clpad;
foo_clpad f = { { 42, 103 } };
// uncomment the (// + 1;) for forced alignment error
uintptr_t p = ((uintptr_t)&f.data); // + 1;
if (sizeof(f) > CT_CLSIZE)
{
std::printf("f over padded! %lu\n", (unsigned long)sizeof(f));
std::printf("hit <ENTER> to continue...\n");
std::fflush(stdout);
std::getchar();
}
if ((p) % (CT_CLSIZE)) // hack assertion!
{
std::printf("&f not aligned! %llu\n", p);
std::printf("hit <ENTER> to continue...\n");
std::fflush(stdout);
std::getchar();
}
std::printf("sizeof(f) = %lu\n", (unsigned long)sizeof(f));
std::printf("&f = %p\n", (void*)&f);
std::printf("&f.data = %p\n", (void*)&f.data);
std::printf("\n\n");
std::printf("f.data.id:%u\n",
f.data.id);
std::printf("f.data.seq:%u\n", f.data.seq);
return 0;
}
____________________________
f needs to be padded up to a cache line size and aligned on its
boundary. Afaict, my code should check for that. Please point out any
problems you see. For instance GCC alignas pads and aligns, no need for
extra padding in the struct?