Skip to content

Commit c479429

Browse files
authored
Merge pull request #229 from ehein6/alignment-check
Enforce alignment of stinger sub-structures.
2 parents 92348d4 + dddddb0 commit c479429

3 files changed

Lines changed: 41 additions & 0 deletions

File tree

CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,11 @@ set(STINGER_DEFAULT_NEB_FACTOR "4" CACHE STRING "Default number of edge blocks p
139139
set(STINGER_EDGEBLOCKSIZE "14" CACHE STRING "Number of edges per edge block")
140140
set(STINGER_NAME_STR_MAX "255" CACHE STRING "Max string length in physmap")
141141

142+
MATH(EXPR STINGER_NAME_STR_MAX_ALIGN "(${STINGER_NAME_STR_MAX}+1) % 8")
143+
if (NOT STINGER_NAME_STR_MAX_ALIGN EQUAL 0)
144+
MESSAGE(SEND_ERROR "STINGER_NAME_STR_MAX must be a multiple of 8 (minus one for null terminator).")
145+
endif()
146+
142147
configure_file(${CMAKE_SOURCE_DIR}/lib/stinger_core/inc/stinger_defs.h.in ${CMAKE_BINARY_DIR}/include/stinger_core/stinger_defs.h @ONLY)
143148
configure_file(${CMAKE_SOURCE_DIR}/lib/stinger_core/inc/stinger_names.h.in ${CMAKE_BINARY_DIR}/include/stinger_core/stinger_names.h @ONLY)
144149

lib/stinger_core/inc/stinger_names.h.in

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ extern "C" {
88

99
#define NAME_STR_MAX @STINGER_NAME_STR_MAX@
1010

11+
// STINGER names storage must be 8-byte aligned
12+
#if (NAME_STR_MAX+1) % 8 != 0
13+
#error STINGER_NAME_STR_MAX must be a multiple of 8 (minus one for null terminator)
14+
#endif
15+
1116
#ifdef NAME_USE_SQLITE
1217
#include "sqlite/sqlite3.h"
1318

lib/stinger_core/src/stinger.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,31 @@ stinger_graph_size (const struct stinger *S)
467467
return result;
468468
}
469469

470+
/**
471+
* Checks the size of a stinger sub-structure, to make sure we aren't
472+
* violating any alignment rules. malloc() will return a pointer that
473+
* is properly aligned for any struct or array of structs. But when we
474+
* pack multiple structures into the same allocation, we run the risk of
475+
* a struct being misaligned. As long as each sub-structure ends on an
476+
* 8-byte boundary, the next one will start on an 8-byte boundary.
477+
* @param sz Size of sub-structure, in bytes
478+
* @param substructure_name Name of sub-structure, used when printing an error
479+
*/
480+
static void
481+
check_alignment(int64_t sz, const char* substructure_name)
482+
{
483+
if (sz % sizeof(int64_t) != 0) {
484+
LOG_F_A(
485+
"The sub-structure %s is %lli bytes long.\n"
486+
"The following struct will not be aligned to an 8-byte boundary.\n"
487+
"This can cause deadlocks when x86 64-bit atomics cross a cache line. \n"
488+
"See section 8.1.1 of the Intel® 64 and IA-32 Architectures Developer's Manual: Vol. 3A. \n"
489+
,substructure_name, (long long int)sz
490+
);
491+
abort();
492+
}
493+
}
494+
470495
/**
471496
* @brief Calculates the required memory to allocate a STINGER given a set of parameters
472497
*
@@ -484,21 +509,27 @@ struct stinger_size_t calculate_stinger_size(int64_t nv, int64_t nebs, int64_t n
484509

485510
ret.vertices_start = 0;
486511
sz += stinger_vertices_size(nv);
512+
check_alignment(sz - ret.vertices_start, "stinger_vertices");
487513

488514
ret.physmap_start = sz;
489515
sz += stinger_physmap_size(nv);
516+
check_alignment(sz - ret.physmap_start, "stinger_physmap");
490517

491518
ret.ebpool_start = sz;
492519
sz += netypes * stinger_ebpool_size(nebs);
520+
check_alignment(sz - ret.ebpool_start, "stinger_ebpool");
493521

494522
ret.etype_names_start = sz;
495523
sz += stinger_names_size(netypes);
524+
check_alignment(sz - ret.etype_names_start, "stinger_etype_names");
496525

497526
ret.vtype_names_start = sz;
498527
sz += stinger_names_size(nvtypes);
528+
check_alignment(sz - ret.vtype_names_start, "stinger_vtype_names");
499529

500530
ret.ETA_start = sz;
501531
sz += netypes * stinger_etype_array_size(nebs);
532+
check_alignment(sz - ret.ETA_start, "stinger_etype_array");
502533

503534
ret.size = sz;
504535

0 commit comments

Comments
 (0)