Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
DVR: use atomic operations for the running start/stop variables
  • Loading branch information
perexg committed Nov 15, 2015
1 parent 303b142 commit 2afa831
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 34 deletions.
6 changes: 6 additions & 0 deletions configure
Expand Up @@ -146,6 +146,12 @@ uint64_t test(uint64_t *ptr){
return __sync_fetch_and_add(ptr, 1);
}'

check_cc_snippet atomic_time_t '#include <stdint.h>
#include <time.h>
uint64_t test(time_t *ptr){
return __sync_fetch_and_add(ptr, 1);
}'

check_cc_snippet lockowner '
#include <sys/syscall.h>
#include <unistd.h>
Expand Down
86 changes: 62 additions & 24 deletions src/atomic.h
Expand Up @@ -19,33 +19,20 @@
#pragma once

#include <stdint.h>
#include <time.h>

extern pthread_mutex_t atomic_lock;

/*
* Atomic FETCH and ADD operation
*/

static inline int
atomic_add(volatile int *ptr, int incr)
{
return __sync_fetch_and_add(ptr, incr);
}

static inline int
atomic_dec(volatile int *ptr, int decr)
{
return __sync_fetch_and_sub(ptr, decr);
}

static inline int
atomic_exchange(volatile int *ptr, int new)
{
return __sync_lock_test_and_set(ptr, new);
}

static inline int
atomic_exchange_u64(volatile uint64_t *ptr, uint64_t new)
{
return __sync_lock_test_and_set(ptr, new);
}

static inline uint64_t
atomic_add_u64(volatile uint64_t *ptr, uint64_t incr)
{
Expand All @@ -61,21 +48,25 @@ atomic_add_u64(volatile uint64_t *ptr, uint64_t incr)
#endif
}

static inline uint64_t
atomic_dec_u64(volatile uint64_t *ptr, uint64_t decr)
static inline time_t
atomic_add_time_t(volatile time_t *ptr, time_t incr)
{
#if ENABLE_ATOMIC64
return __sync_fetch_and_sub(ptr, decr);
#if ENABLE_ATOMIC_TIME_T
return __sync_fetch_and_add(ptr, incr);
#else
uint64_t ret;
time_t ret;
pthread_mutex_lock(&atomic_lock);
ret = *ptr;
*ptr -= decr;
*ptr += incr;
pthread_mutex_unlock(&atomic_lock);
return ret;
#endif
}

/*
* Atomic ADD and FETCH operation
*/

static inline uint64_t
atomic_pre_add_u64(volatile uint64_t *ptr, uint64_t incr)
{
Expand All @@ -90,3 +81,50 @@ atomic_pre_add_u64(volatile uint64_t *ptr, uint64_t incr)
return ret;
#endif
}

/*
* Atomic DEC operation
*/

static inline int
atomic_dec(volatile int *ptr, int decr)
{
return __sync_fetch_and_sub(ptr, decr);
}

static inline uint64_t
atomic_dec_u64(volatile uint64_t *ptr, uint64_t decr)
{
#if ENABLE_ATOMIC64
return __sync_fetch_and_sub(ptr, decr);
#else
uint64_t ret;
pthread_mutex_lock(&atomic_lock);
ret = *ptr;
*ptr -= decr;
pthread_mutex_unlock(&atomic_lock);
return ret;
#endif
}

/*
* Atomic EXCHANGE operation
*/

static inline int
atomic_exchange(volatile int *ptr, int new)
{
return __sync_lock_test_and_set(ptr, new);
}

static inline int
atomic_exchange_u64(volatile uint64_t *ptr, uint64_t new)
{
return __sync_lock_test_and_set(ptr, new);
}

static inline int
atomic_exchange_time_t(volatile time_t *ptr, int new)
{
return __sync_lock_test_and_set(ptr, new);
}
9 changes: 5 additions & 4 deletions src/dvr/dvr_db.c
Expand Up @@ -1622,7 +1622,8 @@ void dvr_event_running(epg_broadcast_t *e, epg_source_t esrc, int running)
return;
LIST_FOREACH(de, &e->channel->ch_dvrs, de_channel_link) {
if (de->de_dvb_eid == 0 || !dvr_entry_get_epg_running(de)) {
de->de_running_start = de->de_running_stop = 0;
atomic_exchange_time_t(&de->de_running_start, 0);
atomic_exchange_time_t(&de->de_running_stop, 0);
continue;
}
if (running && de->de_dvb_eid == e->dvb_eid) {
Expand All @@ -1631,10 +1632,10 @@ void dvr_event_running(epg_broadcast_t *e, epg_source_t esrc, int running)
idnode_uuid_as_sstr(&de->de_id),
epg_broadcast_get_title(e, NULL),
channel_get_name(e->channel));
de->de_running_start = dispatch_clock;
atomic_exchange_time_t(&de->de_running_start, dispatch_clock);
}
if (dvr_entry_get_start_time(de) > dispatch_clock) {
de->de_start = dispatch_clock;
atomic_exchange_time_t(&de->de_start, dispatch_clock);
dvr_entry_set_timer(de);
tvhdebug("dvr", "dvr entry %s event %s on %s - EPG start",
idnode_uuid_as_sstr(&de->de_id),
Expand All @@ -1658,7 +1659,7 @@ void dvr_event_running(epg_broadcast_t *e, epg_source_t esrc, int running)
epg_broadcast_get_title(e, NULL),
channel_get_name(de->de_channel));
}
de->de_running_stop = dispatch_clock;
atomic_exchange_time_t(&de->de_running_stop, dispatch_clock);
if (de->de_sched_state == DVR_RECORDING && de->de_running_start) {
de->de_dont_reschedule = 1;
dvr_stop_recording(de, SM_CODE_OK, 0, 0);
Expand Down
14 changes: 8 additions & 6 deletions src/dvr/dvr_rec.c
Expand Up @@ -1199,7 +1199,7 @@ dvr_thread(void *aux)
int commercial = COMMERCIAL_UNKNOWN;
int running_disabled;
int64_t packets = 0, dts_offset = PTS_UNSET;
time_t start_time = 0;
time_t start_time = 0, running_start = 0, running_stop = 0;
char *postproc;

if (!dvr_thread_global_lock(de, &run))
Expand All @@ -1223,9 +1223,11 @@ dvr_thread(void *aux)
if (running_disabled) {
epg_running = 1;
} else if (sm->sm_type == SMT_PACKET || sm->sm_type == SMT_MPEGTS) {
if (de->de_running_start > 0) {
epg_running = de->de_running_start >= de->de_running_stop;
} else if (de->de_running_stop == 0) {
running_start = atomic_add_time_t(&de->de_running_start, 0);
running_stop = atomic_add_time_t(&de->de_running_stop, 0);
if (running_start > 0) {
epg_running = running_start >= running_stop;
} else if (running_stop == 0) {
if (start_time + 2 >= dispatch_clock) {
TAILQ_INSERT_TAIL(&backlog, sm, sm_link);
continue;
Expand Down Expand Up @@ -1254,7 +1256,7 @@ dvr_thread(void *aux)
dvr_rec_set_state(de, rs, 0);

if ((rs == DVR_RS_COMMERCIAL && comm_skip) || !epg_running) {
if (ss && packets && de->de_running_start == 0) {
if (ss && packets && running_start == 0) {
dvr_streaming_restart(de, &run);
packets = 0;
started = 0;
Expand Down Expand Up @@ -1319,7 +1321,7 @@ dvr_thread(void *aux)
break;

if (!epg_running) {
if (packets && de->de_running_start == 0) {
if (packets && running_start == 0) {
dvr_streaming_restart(de, &run);
packets = 0;
started = 0;
Expand Down

0 comments on commit 2afa831

Please sign in to comment.