summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2017-05-10 10:01:06 +0200
committerantirez <antirez@gmail.com>2017-05-10 10:04:16 +0200
commit1f598fc2bb6975417751486405303d98246bb7bc (patch)
treea440ed56dfbd15ed1eb2375298ab1ae40c3cc0c6
parentde786186a5a0cd15aa86a2127647fb9c758bc405 (diff)
downloadredis-thread-safe-context.tar.gz
Modules TSC: use atomic var for server.unixtime.thread-safe-context
This avoids Helgrind complaining, but we are actually not using atomicGet() to get the unixtime value for now: too many places where it is used and given tha time_t is word-sized it should be safe in all the archs we support as it is. On the other hand, Helgrind, when Redis is compiled with "make helgrind" in order to force the __sync macros, will detect the write in updateCachedTime() as a read (because atomic functions are used) and will not complain about races. This commit also includes minor refactoring of mutex initializations and a "helgrind" target in the Makefile.
-rw-r--r--src/Makefile3
-rw-r--r--src/server.c9
-rw-r--r--src/server.h8
3 files changed, 15 insertions, 5 deletions
diff --git a/src/Makefile b/src/Makefile
index 8f429431b..691b5aaea 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -272,6 +272,9 @@ noopt:
valgrind:
$(MAKE) OPTIMIZATION="-O0" MALLOC="libc"
+helgrind:
+ $(MAKE) OPTIMIZATION="-O0" MALLOC="libc" CFLAGS="-D__ATOMIC_VAR_FORCE_SYNC_MACROS"
+
src/help.h:
@../utils/generate-command-help.rb > help.h
diff --git a/src/server.c b/src/server.c
index 75268b8a4..e50ec6359 100644
--- a/src/server.c
+++ b/src/server.c
@@ -923,7 +923,8 @@ void databasesCron(void) {
* every object access, and accuracy is not needed. To access a global var is
* a lot faster than calling time(NULL) */
void updateCachedTime(void) {
- server.unixtime = time(NULL);
+ time_t unixtime = time(NULL);
+ atomicSet(server.unixtime,unixtime);
server.mstime = mstime();
}
@@ -1331,6 +1332,10 @@ void createSharedObjects(void) {
void initServerConfig(void) {
int j;
+ pthread_mutex_init(&server.next_client_id_mutex,NULL);
+ pthread_mutex_init(&server.lruclock_mutex,NULL);
+ pthread_mutex_init(&server.unixtime_mutex,NULL);
+
getRandomHexChars(server.runid,CONFIG_RUN_ID_SIZE);
server.runid[CONFIG_RUN_ID_SIZE] = '\0';
changeReplicationId();
@@ -1423,7 +1428,6 @@ void initServerConfig(void) {
server.cluster_announce_bus_port = CONFIG_DEFAULT_CLUSTER_ANNOUNCE_BUS_PORT;
server.migrate_cached_sockets = dictCreate(&migrateCacheDictType,NULL);
server.next_client_id = 1; /* Client IDs, start from 1 .*/
- pthread_mutex_init(&server.next_client_id_mutex,NULL);
server.loading_process_events_interval_bytes = (1024*1024*2);
server.lazyfree_lazy_eviction = CONFIG_DEFAULT_LAZYFREE_LAZY_EVICTION;
server.lazyfree_lazy_expire = CONFIG_DEFAULT_LAZYFREE_LAZY_EXPIRE;
@@ -1432,7 +1436,6 @@ void initServerConfig(void) {
server.lua_time_limit = LUA_SCRIPT_TIME_LIMIT;
unsigned int lruclock = getLRUClock();
- pthread_mutex_init(&server.lruclock_mutex,NULL);
atomicSet(server.lruclock,lruclock);
resetServerSaveParams();
diff --git a/src/server.h b/src/server.h
index 12ccd8c0b..8403ed5ba 100644
--- a/src/server.h
+++ b/src/server.h
@@ -861,7 +861,6 @@ struct redisServer {
dict *orig_commands; /* Command table before command renaming. */
aeEventLoop *el;
unsigned int lruclock; /* Clock for LRU eviction */
- pthread_mutex_t lruclock_mutex;
int shutdown_asap; /* SHUTDOWN needed ASAP */
int activerehashing; /* Incremental rehash in serverCron() */
int active_defrag_running; /* Active defragmentation running (holds current scan aggressiveness) */
@@ -901,7 +900,6 @@ struct redisServer {
char neterr[ANET_ERR_LEN]; /* Error buffer for anet.c */
dict *migrate_cached_sockets;/* MIGRATE cached sockets */
uint64_t next_client_id; /* Next client unique ID. Incremental. */
- pthread_mutex_t next_client_id_mutex;
int protected_mode; /* Don't accept external connections. */
/* RDB / AOF loading information */
int loading; /* We are loading data from disk if true */
@@ -1173,6 +1171,12 @@ struct redisServer {
int watchdog_period; /* Software watchdog period in ms. 0 = off */
/* System hardware info */
size_t system_memory_size; /* Total memory in system as reported by OS */
+
+ /* Mutexes used to protect atomic variables when atomic builtins are
+ * not available. */
+ pthread_mutex_t lruclock_mutex;
+ pthread_mutex_t next_client_id_mutex;
+ pthread_mutex_t unixtime_mutex;
};
typedef struct pubsubPattern {