diff --git a/src/atomic.h b/src/atomic.h index 1c3efb73..8627e64a 100644 --- a/src/atomic.h +++ b/src/atomic.h @@ -29,3 +29,9 @@ atomic_exchange(volatile int *ptr, int new) { return __sync_lock_test_and_set(ptr, new); } + +static inline uint64_t +atomic_add_u64(volatile uint64_t *ptr, uint64_t incr) +{ + return __sync_fetch_and_add(ptr, incr); +} diff --git a/src/timeshift/timeshift_filemgr.c b/src/timeshift/timeshift_filemgr.c index 635f4769..64f724bc 100644 --- a/src/timeshift/timeshift_filemgr.c +++ b/src/timeshift/timeshift_filemgr.c @@ -31,6 +31,7 @@ #include "timeshift/private.h" #include "config2.h" #include "settings.h" +#include "atomic.h" static int timeshift_reaper_run; static timeshift_file_list_t timeshift_reaper_list; @@ -38,7 +39,6 @@ static pthread_t timeshift_reaper_thread; static pthread_mutex_t timeshift_reaper_lock; static pthread_cond_t timeshift_reaper_cond; -pthread_mutex_t timeshift_size_lock; size_t timeshift_total_size; /* ************************************************************************** @@ -75,10 +75,7 @@ static void* timeshift_reaper_callback ( void *p ) if (errno != ENOTEMPTY) tvhlog(LOG_ERR, "timeshift", "failed to remove %s [e=%s]", dpath, strerror(errno)); - pthread_mutex_lock(×hift_size_lock); - assert(tsf->size <= timeshift_total_size); - timeshift_total_size -= tsf->size; - pthread_mutex_unlock(×hift_size_lock); + atomic_add_u64(×hift_total_size, -tsf->size); /* Free memory */ while ((ti = TAILQ_FIRST(&tsf->iframes))) { @@ -151,9 +148,7 @@ void timeshift_filemgr_close ( timeshift_file_t *tsf ) if (r > 0) { tsf->size += r; - pthread_mutex_lock(×hift_size_lock); - timeshift_total_size += r; - pthread_mutex_unlock(×hift_size_lock); + atomic_add_u64(×hift_total_size, r); } close(tsf->fd); tsf->fd = -1; @@ -230,12 +225,11 @@ timeshift_file_t *timeshift_filemgr_get ( timeshift_t *ts, int create ) } /* Check size */ - pthread_mutex_lock(×hift_size_lock); - if (!timeshift_unlimited_size && timeshift_total_size >= timeshift_max_size) { + if (!timeshift_unlimited_size && + atomic_add_u64(×hift_total_size, 0) >= timeshift_max_size) { tvhlog(LOG_DEBUG, "timshift", "ts %d buffer full", ts->id); ts->full = 1; } - pthread_mutex_unlock(×hift_size_lock); /* Create new file */ tsf_tmp = NULL; @@ -332,7 +326,6 @@ void timeshift_filemgr_init ( void ) /* Size processing */ timeshift_total_size = 0; - pthread_mutex_init(×hift_size_lock, NULL); /* Start the reaper thread */ timeshift_reaper_run = 1; diff --git a/src/timeshift/timeshift_writer.c b/src/timeshift/timeshift_writer.c index bf944dbe..06810a86 100644 --- a/src/timeshift/timeshift_writer.c +++ b/src/timeshift/timeshift_writer.c @@ -20,6 +20,7 @@ #include "streaming.h" #include "timeshift.h" #include "timeshift/private.h" +#include "atomic.h" #include #include @@ -224,9 +225,7 @@ static inline ssize_t _process_msg0 if (err > 0) { tsf->last = sm->sm_time; tsf->size += err; - pthread_mutex_lock(×hift_size_lock); - timeshift_total_size += err; - pthread_mutex_unlock(×hift_size_lock); + atomic_add_u64(×hift_total_size, err); } return err; }