From 83f31253eb21c5ecd8a5907835e57720daae0b8b Mon Sep 17 00:00:00 2001 From: Nisanth M P Date: Mon, 16 Oct 2017 21:07:50 +0530 Subject: [PATCH] Thread safety: Make the global induced method status array local to thread BLIS retains a global status array for induced methods, and provides APIs to modify this state during runtime. So, one application thread can modify the state, before another starts the corresponding BLIS operation. This patch solves this issue by making the induced method status array local to threads. Change-Id: Iff59b6f473771344054c010b4eda51b7aa4317fe --- frame/include/bli_macro_defs.h | 14 ++++++++++++++ frame/ind/bli_l3_ind.c | 6 +++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/frame/include/bli_macro_defs.h b/frame/include/bli_macro_defs.h index d99be2345..a332554cc 100644 --- a/frame/include/bli_macro_defs.h +++ b/frame/include/bli_macro_defs.h @@ -64,6 +64,20 @@ #endif +// -- BLIS Thread Local Storage Keyword -- + +// __thread for TLS is supported by GCC, CLANG, ICC, and IBMC. +// There is a small risk here as __GNUC__ can also be defined by some other +// compiler (other than ICC and CLANG which we know define it) that +// doesn't support __thread, as __GNUC__ is not quite unique to GCC. +// But the possibility of someone using such non-main-stream compiler +// for building BLIS is low. +#if defined(__GNUC__) || defined(__clang__) || defined(__ICC) || defined(__IBMC__) + #define BLIS_THREAD_LOCAL __thread +#else + #define BLIS_THREAD_LOCAL +#endif + // -- Boolean values -- #ifndef TRUE diff --git a/frame/ind/bli_l3_ind.c b/frame/ind/bli_l3_ind.c index 0bf624a1e..7347ec796 100644 --- a/frame/ind/bli_l3_ind.c +++ b/frame/ind/bli_l3_ind.c @@ -60,7 +60,11 @@ static void* bli_l3_ind_oper_fp[BLIS_NUM_IND_METHODS][BLIS_NUM_LEVEL3_OPS] = // // NOTE: "2" is used instead of BLIS_NUM_FP_TYPES/2. // -static bool_t bli_l3_ind_oper_st[BLIS_NUM_IND_METHODS][BLIS_NUM_LEVEL3_OPS][2] = +// BLIS provides APIs to modify this state during runtime. So, one application thread +// can modify the state, before another starts the corresponding BLIS operation. +// This is solved by making the induced method status array local to threads. + +static BLIS_THREAD_LOCAL bool_t bli_l3_ind_oper_st[BLIS_NUM_IND_METHODS][BLIS_NUM_LEVEL3_OPS][2] = { /* gemm hemm herk her2k symm syrk, syr2k trmm3 trmm trsm */ /* c z */