Skip to content

Commit

Permalink
threads: make thread local storage manadatory
Browse files Browse the repository at this point in the history
Support either the __thread GNUism or the C11 _Thread_local.

Use 'thread_local' to point to the one that is used. Convert existing
__thread user to 'thread_local'.

Remove non-thread-local code from the packet pool code.
  • Loading branch information
victorjulien committed Apr 16, 2020
1 parent 32cfd71 commit 3ba4afd
Show file tree
Hide file tree
Showing 13 changed files with 87 additions and 134 deletions.
32 changes: 20 additions & 12 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -320,18 +320,26 @@
esac
AC_MSG_RESULT(ok)

# disable TLS on user request
AC_ARG_ENABLE(threading-tls,
AS_HELP_STRING([--disable-threading-tls], [Disable TLS (thread local storage)]), [enable_tls="$enableval"],[enable_tls=yes])
AS_IF([test "x$enable_tls" = "xyes"], [
# check if our target supports thread local storage
AC_MSG_CHECKING(for thread local storage __thread support)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdlib.h>]],
[[ static __thread int i; i = 1; i++; ]])],
[AC_DEFINE([TLS], [1], [Thread local storage])
AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])])
])
# check if our target supports thread local storage
AC_MSG_CHECKING(for thread local storage c11 thread_local support)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdlib.h>]],
[[ static _Thread_local int i; i = 1; i++; ]])],
[AC_DEFINE([TLS_C11], [1], [Thread local storage])
AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])
have_c11_tls=no])
# check if our target supports thread local storage
AC_MSG_CHECKING(for thread local storage gnu __thread support)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdlib.h>]],
[[ static __thread int i; i = 1; i++; ]])],
[AC_DEFINE([TLS_GNU], [1], [Thread local storage])
AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])
have_gnu_tls=no])
if [ test "x$have_c11_tls" = "xno" ] && [ test "x$have_gnu_tls" = "xno" ]; then
AC_MSG_ERROR("no thread local support available.")
exit 1
fi

#Enable support for gcc compile time security options. There is no great way to do detection of valid cflags that I have found
#AX_CFLAGS_GCC_OPTION don't seem to do a better job than the code below and are a pain because of extra m4 files etc.
Expand Down
2 changes: 1 addition & 1 deletion src/output-filestore.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ typedef struct OutputFilestoreLogThread_ {

/* For WARN_ONCE, a record of warnings that have already been
* issued. */
static __thread bool once_errs[SC_ERR_MAX];
static thread_local bool once_errs[SC_ERR_MAX];

#define WARN_ONCE(err_code, ...) do { \
if (!once_errs[err_code]) { \
Expand Down
15 changes: 12 additions & 3 deletions src/suricata.c
Original file line number Diff line number Diff line change
Expand Up @@ -650,7 +650,7 @@ static void PrintBuildInfo(void)
const char *bits = "<unknown>-bits";
const char *endian = "<unknown>-endian";
char features[2048] = "";
const char *tls = "pthread key";
const char *tls;

printf("This is %s version %s\n", PROG_NAME, GetProgramVersion());

Expand Down Expand Up @@ -715,9 +715,14 @@ static void PrintBuildInfo(void)
#ifdef PROFILE_LOCKING
strlcat(features, "PROFILE_LOCKING ", sizeof(features));
#endif
#ifdef TLS
#if defined(TLS_C11) || defined(TLS_GNU)
strlcat(features, "TLS ", sizeof(features));
#endif
#if defined(TLS_C11)
strlcat(features, "TLS_C11 ", sizeof(features));
#elif defined(TLS_GNU)
strlcat(features, "TLS_GNU ", sizeof(features));
#endif
#ifdef HAVE_MAGIC
strlcat(features, "MAGIC ", sizeof(features));
#endif
Expand Down Expand Up @@ -810,8 +815,12 @@ static void PrintBuildInfo(void)
#ifdef CLS
printf("L1 cache line size (CLS)=%d\n", CLS);
#endif
#ifdef TLS
#if defined(TLS_C11)
tls = "_Thread_local";
#elif defined(TLS_GNU)
tls = "__thread";
#else
#error "Unsupported thread local"
#endif
printf("thread local storage method: %s\n", tls);

Expand Down
30 changes: 15 additions & 15 deletions src/threads-profile.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@ typedef struct ProfilingLock_ {
uint64_t ticks;
} ProfilingLock;

extern __thread ProfilingLock locks[PROFILING_MAX_LOCKS];
extern __thread int locks_idx;
extern __thread int record_locks;
extern thread_local ProfilingLock locks[PROFILING_MAX_LOCKS];
extern thread_local int locks_idx;
extern thread_local int record_locks;

extern __thread uint64_t mutex_lock_contention;
extern __thread uint64_t mutex_lock_wait_ticks;
extern __thread uint64_t mutex_lock_cnt;
extern thread_local uint64_t mutex_lock_contention;
extern thread_local uint64_t mutex_lock_wait_ticks;
extern thread_local uint64_t mutex_lock_cnt;

/* mutex */

Expand Down Expand Up @@ -92,9 +92,9 @@ extern __thread uint64_t mutex_lock_cnt;

/* spinlocks */

extern __thread uint64_t spin_lock_contention;
extern __thread uint64_t spin_lock_wait_ticks;
extern __thread uint64_t spin_lock_cnt;
extern thread_local uint64_t spin_lock_contention;
extern thread_local uint64_t spin_lock_wait_ticks;
extern thread_local uint64_t spin_lock_cnt;

//printf("%16s(%s:%d): (thread:%"PRIuMAX") locked mutex %p ret %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), mut, retl);
#define SCSpinLock_profile(spin) ({ \
Expand Down Expand Up @@ -131,9 +131,9 @@ extern __thread uint64_t spin_lock_cnt;

/* rwlocks */

extern __thread uint64_t rww_lock_contention;
extern __thread uint64_t rww_lock_wait_ticks;
extern __thread uint64_t rww_lock_cnt;
extern thread_local uint64_t rww_lock_contention;
extern thread_local uint64_t rww_lock_wait_ticks;
extern thread_local uint64_t rww_lock_cnt;

#define SCRWLockWRLock_profile(mut) ({ \
rww_lock_cnt++; \
Expand All @@ -160,9 +160,9 @@ extern __thread uint64_t rww_lock_cnt;
retl; \
})

extern __thread uint64_t rwr_lock_contention;
extern __thread uint64_t rwr_lock_wait_ticks;
extern __thread uint64_t rwr_lock_cnt;
extern thread_local uint64_t rwr_lock_contention;
extern thread_local uint64_t rwr_lock_wait_ticks;
extern thread_local uint64_t rwr_lock_cnt;

#define SCRWLockRDLock_profile(mut) ({ \
rwr_lock_cnt++; \
Expand Down
8 changes: 8 additions & 0 deletions src/threads.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@
#include <config.h>
#endif

#if defined(TLS_C11)
#define thread_local _Thread_local
#elif defined(TLS_GNU)
#define thread_local __thread
#else
#error "No supported thread local type found"
#endif

/* need this for the _POSIX_SPIN_LOCKS define */
#if HAVE_UNISTD_H
#include <unistd.h>
Expand Down
24 changes: 12 additions & 12 deletions src/tm-threads.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,21 +44,21 @@
#include "queue.h"

#ifdef PROFILE_LOCKING
__thread uint64_t mutex_lock_contention;
__thread uint64_t mutex_lock_wait_ticks;
__thread uint64_t mutex_lock_cnt;
thread_local uint64_t mutex_lock_contention;
thread_local uint64_t mutex_lock_wait_ticks;
thread_local uint64_t mutex_lock_cnt;

__thread uint64_t spin_lock_contention;
__thread uint64_t spin_lock_wait_ticks;
__thread uint64_t spin_lock_cnt;
thread_local uint64_t spin_lock_contention;
thread_local uint64_t spin_lock_wait_ticks;
thread_local uint64_t spin_lock_cnt;

__thread uint64_t rww_lock_contention;
__thread uint64_t rww_lock_wait_ticks;
__thread uint64_t rww_lock_cnt;
thread_local uint64_t rww_lock_contention;
thread_local uint64_t rww_lock_wait_ticks;
thread_local uint64_t rww_lock_cnt;

__thread uint64_t rwr_lock_contention;
__thread uint64_t rwr_lock_wait_ticks;
__thread uint64_t rwr_lock_cnt;
thread_local uint64_t rwr_lock_contention;
thread_local uint64_t rwr_lock_wait_ticks;
thread_local uint64_t rwr_lock_cnt;
#endif

#ifdef OS_FREEBSD
Expand Down
74 changes: 1 addition & 73 deletions src/tmqh-packetpool.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,76 +54,12 @@
#define MAX_PENDING_RETURN_PACKETS 32
static uint32_t max_pending_return_packets = MAX_PENDING_RETURN_PACKETS;

#ifdef TLS
__thread PktPool thread_pkt_pool;
thread_local PktPool thread_pkt_pool;

static inline PktPool *GetThreadPacketPool(void)
{
return &thread_pkt_pool;
}
#else
/* __thread not supported. */
static pthread_key_t pkt_pool_thread_key;
static SCMutex pkt_pool_thread_key_mutex = SCMUTEX_INITIALIZER;
static int pkt_pool_thread_key_initialized = 0;

static void PktPoolThreadDestroy(void * buf)
{
SCFreeAligned(buf);
}

static void TmqhPacketPoolInit(void)
{
SCMutexLock(&pkt_pool_thread_key_mutex);
if (pkt_pool_thread_key_initialized) {
/* Key has already been created. */
SCMutexUnlock(&pkt_pool_thread_key_mutex);
return;
}

/* Create the pthread Key that is used to look up thread specific
* data buffer. Needs to be created only once.
*/
int r = pthread_key_create(&pkt_pool_thread_key, PktPoolThreadDestroy);
if (r != 0) {
SCLogError(SC_ERR_MEM_ALLOC, "pthread_key_create failed with %d", r);
exit(EXIT_FAILURE);
}

pkt_pool_thread_key_initialized = 1;
SCMutexUnlock(&pkt_pool_thread_key_mutex);
}

static PktPool *ThreadPacketPoolCreate(void)
{
TmqhPacketPoolInit();

/* Create a new pool for this thread. */
PktPool* pool = (PktPool*)SCMallocAligned(sizeof(PktPool), CLS);
if (pool == NULL) {
SCLogError(SC_ERR_MEM_ALLOC, "malloc failed");
exit(EXIT_FAILURE);
}
memset(pool,0x0,sizeof(*pool));

int r = pthread_setspecific(pkt_pool_thread_key, pool);
if (r != 0) {
SCLogError(SC_ERR_MEM_ALLOC, "pthread_setspecific failed with %d", r);
exit(EXIT_FAILURE);
}

return pool;
}

static inline PktPool *GetThreadPacketPool(void)
{
PktPool* pool = (PktPool*)pthread_getspecific(pkt_pool_thread_key);
if (pool == NULL)
pool = ThreadPacketPoolCreate();

return pool;
}
#endif

/**
* \brief TmqhPacketpoolRegister
Expand Down Expand Up @@ -350,10 +286,6 @@ void PacketPoolReturnPacket(Packet *p)

void PacketPoolInitEmpty(void)
{
#ifndef TLS
TmqhPacketPoolInit();
#endif

PktPool *my_pool = GetThreadPacketPool();

#ifdef DEBUG_VALIDATION
Expand All @@ -371,10 +303,6 @@ void PacketPoolInit(void)
{
extern intmax_t max_pending_packets;

#ifndef TLS
TmqhPacketPoolInit();
#endif

PktPool *my_pool = GetThreadPacketPool();

#ifdef DEBUG_VALIDATION
Expand Down
2 changes: 1 addition & 1 deletion src/util-profiling-keywords.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ typedef struct SCProfileKeywordDetectCtx_ {

static int profiling_keywords_output_to_file = 0;
int profiling_keyword_enabled = 0;
__thread int profiling_keyword_entered = 0;
thread_local int profiling_keyword_entered = 0;
static char profiling_file_name[PATH_MAX];
static const char *profiling_file_mode = "a";

Expand Down
6 changes: 3 additions & 3 deletions src/util-profiling-locks.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@
#ifdef PROFILING
#ifdef PROFILE_LOCKING

__thread ProfilingLock locks[PROFILING_MAX_LOCKS];
__thread int locks_idx = 0;
__thread int record_locks = 0;
thread_local ProfilingLock locks[PROFILING_MAX_LOCKS];
thread_local int locks_idx = 0;
thread_local int record_locks = 0;

int profiling_locks_enabled = 0;
int profiling_locks_output_to_file = 0;
Expand Down
2 changes: 1 addition & 1 deletion src/util-profiling-prefilter.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ typedef struct SCProfilePrefilterDetectCtx_ {

static int profiling_prefilter_output_to_file = 0;
int profiling_prefilter_enabled = 0;
__thread int profiling_prefilter_entered = 0;
thread_local int profiling_prefilter_entered = 0;
static char profiling_file_name[PATH_MAX];
static const char *profiling_file_mode = "a";

Expand Down
2 changes: 1 addition & 1 deletion src/util-profiling.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ static SC_ATOMIC_DECLARE(uint64_t, samples);
/**
* Used as a check so we don't double enter a profiling run.
*/
__thread int profiling_rules_entered = 0;
thread_local int profiling_rules_entered = 0;

void SCProfilingDumpPacketStats(void);
const char * PacketProfileDetectIdToString(PacketProfileDetectId id);
Expand Down
6 changes: 3 additions & 3 deletions src/util-profiling.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
extern int profiling_rules_enabled;
extern int profiling_packets_enabled;
extern int profiling_sghs_enabled;
extern __thread int profiling_rules_entered;
extern thread_local int profiling_rules_entered;

void SCProfilingPrintPacketProfile(Packet *);
void SCProfilingAddPacket(Packet *);
Expand All @@ -60,7 +60,7 @@ int SCProfileRuleStart(Packet *p);
}

extern int profiling_keyword_enabled;
extern __thread int profiling_keyword_entered;
extern thread_local int profiling_keyword_entered;

#define KEYWORD_PROFILING_SET_LIST(ctx, list) { \
(ctx)->keyword_perf_list = (list); \
Expand Down Expand Up @@ -275,7 +275,7 @@ PktProfiling *SCProfilePacketStart(void);
}

extern int profiling_prefilter_enabled;
extern __thread int profiling_prefilter_entered;
extern thread_local int profiling_prefilter_entered;

#define PREFILTER_PROFILING_START \
uint64_t profile_prefilter_start_ = 0; \
Expand Down
Loading

0 comments on commit 3ba4afd

Please sign in to comment.