@@ -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