From 1f598fc2bb6975417751486405303d98246bb7bc Mon Sep 17 00:00:00 2001 From: antirez Date: Wed, 10 May 2017 10:01:06 +0200 Subject: Modules TSC: use atomic var for server.unixtime. 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. --- src/Makefile | 3 +++ src/server.c | 9 ++++++--- src/server.h | 8 ++++++-- 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 { -- cgit v1.2.1