From f3c2c12fa2f42d5e401da954db06364f55671e28 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 8 Aug 2023 16:06:56 +0200 Subject: [PATCH] Fix alignment of Tpool user data to 32 bytes The thread pool provides user data to be stored by (pre-)allocating the necessary memory. A previous attempt was made to have this user data aligned on a 32 byte boundary (e.g., to prevent segfault with SIMD instructions, or avoid inefficient data access); the current implementation, however, leads to unaligned memory access. This patch attempts again to implement user data to be 32 byte aligned. First, use memalign() to allocate the actual job on a 32 byte boundary. Second, use alignas(32) to align the pointer to the user data to be aligned to 32 bytes. Since it is the last member of the struct, this ensures that user data, which is allocated right behind it, will be aligned to 32 bytes as well. --- common/utils/threadPool/thread-pool.h | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/common/utils/threadPool/thread-pool.h b/common/utils/threadPool/thread-pool.h index 66e1152f48..1a78e20134 100644 --- a/common/utils/threadPool/thread-pool.h +++ b/common/utils/threadPool/thread-pool.h @@ -26,6 +26,8 @@ #define THREAD_POOL_H #include #include +#include +#include #include #include #include @@ -64,7 +66,10 @@ typedef struct notifiedFIFO_elt_s { oai_cputime_t startProcessingTime; oai_cputime_t endProcessingTime; oai_cputime_t returnTime; - void *msgData; + // use alignas(32) to align msgData to 32b + // user data behind it will be aligned to 32b as well + // important! this needs to be the last member in the struct + alignas(32) void *msgData; } notifiedFIFO_elt_t; typedef struct notifiedFIFO_s { @@ -80,14 +85,15 @@ static inline notifiedFIFO_elt_t *newNotifiedFIFO_elt(int size, uint64_t key, notifiedFIFO_t *reponseFifo, void (*processingFunc)(void *)) { - notifiedFIFO_elt_t *ret; - AssertFatal( NULL != (ret=(notifiedFIFO_elt_t *) calloc(1, sizeof(notifiedFIFO_elt_t)+size+32)), ""); + notifiedFIFO_elt_t *ret = (notifiedFIFO_elt_t *)memalign(32, sizeof(notifiedFIFO_elt_t) + size); + AssertFatal(NULL != ret, "out of memory\n"); ret->next=NULL; ret->key=key; ret->reponseFifo=reponseFifo; ret->processingFunc=processingFunc; // We set user data piece aligend 32 bytes to be able to process it with SIMD - ret->msgData=(void *)((uint8_t*)ret+(sizeof(notifiedFIFO_elt_t)/32+1)*32); + // msgData is aligned to 32bytes, so everything after will be as well + ret->msgData = ((uint8_t *)ret) + sizeof(notifiedFIFO_elt_t); ret->malloced=true; return ret; }