threads: make thread local storage manadatory

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.
pull/4832/head
Victor Julien 5 years ago
parent 32cfd71f1a
commit 3ba4afd40b

@ -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_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], [1], [Thread local storage])
[AC_DEFINE([TLS_GNU], [1], [Thread local storage])
AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])])
])
[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.

@ -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]) { \

@ -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());
@ -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
@ -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);

@ -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 */
@ -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) ({ \
@ -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++; \
@ -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++; \

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

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

@ -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
@ -350,10 +286,6 @@ void PacketPoolReturnPacket(Packet *p)
void PacketPoolInitEmpty(void)
{
#ifndef TLS
TmqhPacketPoolInit();
#endif
PktPool *my_pool = GetThreadPacketPool();
#ifdef DEBUG_VALIDATION
@ -371,10 +303,6 @@ void PacketPoolInit(void)
{
extern intmax_t max_pending_packets;
#ifndef TLS
TmqhPacketPoolInit();
#endif
PktPool *my_pool = GetThreadPacketPool();
#ifdef DEBUG_VALIDATION

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

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

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

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

@ -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 *);
@ -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); \
@ -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; \

@ -242,7 +242,7 @@ struct tm *SCUtcTime(time_t timep, struct tm *result)
*/
#ifndef TLS
/* OpenBSD does not support __thread, so don't use time caching on BSD
/* OpenBSD does not support thread_local, so don't use time caching on BSD
*/
struct tm *SCLocalTime(time_t timep, struct tm *result)
{
@ -266,7 +266,7 @@ void CreateTimeString (const struct timeval *ts, char *str, size_t size)
#else
/* On systems supporting __thread, use Per-thread values for caching
/* On systems supporting thread_local, use Per-thread values for caching
* in CreateTimeString */
/* The maximum possible length of the time string.
@ -274,16 +274,16 @@ void CreateTimeString (const struct timeval *ts, char *str, size_t size)
* Or "01/01/2013-15:42:21.123456", which is 26, so round up to 32. */
#define MAX_LOCAL_TIME_STRING 32
static __thread int mru_time_slot; /* Most recently used cached value */
static __thread time_t last_local_time[2];
static __thread short int cached_local_time_len[2];
static __thread char cached_local_time[2][MAX_LOCAL_TIME_STRING];
static thread_local int mru_time_slot; /* Most recently used cached value */
static thread_local time_t last_local_time[2];
static thread_local short int cached_local_time_len[2];
static thread_local char cached_local_time[2][MAX_LOCAL_TIME_STRING];
/* Per-thread values for caching SCLocalTime() These cached values are
* independent from the CreateTimeString cached values. */
static __thread int mru_tm_slot; /* Most recently used local tm */
static __thread time_t cached_minute_start[2];
static __thread struct tm cached_local_tm[2];
static thread_local int mru_tm_slot; /* Most recently used local tm */
static thread_local time_t cached_minute_start[2];
static thread_local struct tm cached_local_tm[2];
/** \brief Convert time_t into Year, month, day, hour and minutes.
* \param timep Time in seconds since defined date.

Loading…
Cancel
Save