Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
memoryinfo: initial work
  • Loading branch information
perexg committed Mar 12, 2016
1 parent 5a94400 commit 41b5def
Show file tree
Hide file tree
Showing 30 changed files with 734 additions and 73 deletions.
3 changes: 2 additions & 1 deletion Makefile
Expand Up @@ -213,7 +213,8 @@ SRCS-1 = \
src/profile.c \
src/bouquet.c \
src/lock.c \
src/wizard.c
src/wizard.c \
src/memoryinfo.c
SRCS = $(SRCS-1)
I18N-C = $(SRCS-1)

Expand Down
16 changes: 16 additions & 0 deletions src/api/api_config.c
Expand Up @@ -20,6 +20,7 @@
#include "tvheadend.h"
#include "channels.h"
#include "access.h"
#include "memoryinfo.h"
#include "api.h"
#include "config.h"

Expand All @@ -31,6 +32,19 @@ api_config_capabilities(access_t *perm, void *opaque, const char *op,
return 0;
}

static void
api_memoryinfo_grid
( access_t *perm, idnode_set_t *ins, api_idnode_grid_conf_t *conf, htsmsg_t *args )
{
memoryinfo_t *my;

LIST_FOREACH(my, &memoryinfo_entries, my_link) {
if (my->my_update)
my->my_update(my);
idnode_set_add(ins, (idnode_t*)my, &conf->filter, perm->aa_lang_ui);
}
}

void
api_config_init ( void )
{
Expand All @@ -40,6 +54,8 @@ api_config_init ( void )
{ "config/save", ACCESS_ADMIN, api_idnode_save_simple, &config },
{ "tvhlog/config/load", ACCESS_ADMIN, api_idnode_load_simple, &tvhlog_conf },
{ "tvhlog/config/save", ACCESS_ADMIN, api_idnode_save_simple, &tvhlog_conf },
{ "memoryinfo/class", ACCESS_ADMIN, api_idnode_class, (void *)&memoryinfo_class },
{ "memoryinfo/grid", ACCESS_ADMIN, api_idnode_grid, api_memoryinfo_grid },
{ NULL },
};

Expand Down
62 changes: 62 additions & 0 deletions src/atomic.h
Expand Up @@ -82,6 +82,21 @@ atomic_add_time_t(volatile time_t *ptr, time_t incr)
* Atomic ADD and FETCH operation
*/

static inline int64_t
atomic_pre_add_s64(volatile int64_t *ptr, int64_t incr)
{
#if ENABLE_ATOMIC64
return __sync_add_and_fetch(ptr, incr);
#else
int64_t ret;
pthread_mutex_lock(&atomic_lock);
*ptr += incr;
ret = *ptr;
pthread_mutex_unlock(&atomic_lock);
return ret;
#endif
}

static inline uint64_t
atomic_pre_add_u64(volatile uint64_t *ptr, uint64_t incr)
{
Expand All @@ -97,6 +112,31 @@ atomic_pre_add_u64(volatile uint64_t *ptr, uint64_t incr)
#endif
}

/*
* Atomic ADD and FETCH operation with PEAK (MAX)
*/

static inline int64_t
atomic_pre_add_s64_peak(volatile int64_t *ptr, int64_t incr,
volatile int64_t *peak)
{
#if ENABLE_ATOMIC64
int64_t ret = __sync_add_and_fetch(ptr, incr);
if (__sync_fetch_and_add(peak, 0) < ret)
__sync_lock_test_and_set(peak, ret);
return ret;
#else
int64_t ret;
pthread_mutex_lock(&atomic_lock);
*ptr += incr;
ret = *ptr;
if (*peak < ret)
*peak = ret;
pthread_mutex_unlock(&atomic_lock);
return ret;
#endif
}

/*
* Atomic DEC operation
*/
Expand Down Expand Up @@ -247,3 +287,25 @@ atomic_set_time_t(volatile time_t *ptr, time_t val)
{
return atomic_exchange_time_t(ptr, val);
}

/*
* Atomic set operation + peak (MAX)
*/

static inline int64_t
atomic_set_s64_peak(volatile int64_t *ptr, int64_t val, volatile int64_t *peak)
{
#if ENABLE_ATOMIC64
int64_t ret = atomic_exchange_s64(ptr, val);
if (val > atomic_get_s64(peak))
atomic_set_s64(peak, val);
return ret;
#else
pthread_mutex_lock(&atomic_lock);
*ptr = val;
if (val > *peak)
*peak = val;
pthread_mutex_unlock(&atomic_lock);
return ret;
#endif
}
52 changes: 52 additions & 0 deletions src/channels.c
Expand Up @@ -44,6 +44,7 @@
#include "htsbuf.h"
#include "bouquet.h"
#include "intlconv.h"
#include "memoryinfo.h"

#define CHANNEL_BLANK_NAME "{name-not-set}"

Expand Down Expand Up @@ -1064,7 +1065,30 @@ channel_delete ( channel_t *ch, int delconf )
free(ch);
}

/**
*
*/

static void channels_memoryinfo_update(memoryinfo_t *my)
{
channel_t *ch;
int64_t size = 0, count = 0;

lock_assert(&global_lock);
CHANNEL_FOREACH(ch) {
size += sizeof(*ch);
size += tvh_strlen(ch->ch_epg_parent);
size += tvh_strlen(ch->ch_name);
size += tvh_strlen(ch->ch_icon);
count++;
}
memoryinfo_update(my, size, count);
}

static memoryinfo_t channels_memoryinfo = {
.my_name = "Channels",
.my_update = channels_memoryinfo_update
};

/**
*
Expand All @@ -1078,6 +1102,7 @@ channel_init ( void )
char *s;

RB_INIT(&channels);
memoryinfo_register(&channels_memoryinfo);

/* Tags */
channel_tag_init();
Expand Down Expand Up @@ -1116,6 +1141,7 @@ channel_done ( void )
pthread_mutex_lock(&global_lock);
while ((ch = RB_FIRST(&channels)) != NULL)
channel_delete(ch, 0);
memoryinfo_unregister(&channels_memoryinfo);
pthread_mutex_unlock(&global_lock);
channel_tag_done();
}
Expand Down Expand Up @@ -1485,6 +1511,31 @@ channel_tag_find_by_identifier(uint32_t id) {
return NULL;
}

/**
*
*/

static void channel_tags_memoryinfo_update(memoryinfo_t *my)
{
channel_tag_t *ct;
int64_t size = 0, count = 0;

lock_assert(&global_lock);
TAILQ_FOREACH(ct, &channel_tags, ct_link) {
size += sizeof(*ct);
size += tvh_strlen(ct->ct_name);
size += tvh_strlen(ct->ct_comment);
size += tvh_strlen(ct->ct_icon);
count++;
}
memoryinfo_update(my, size, count);
}

static memoryinfo_t channel_tags_memoryinfo = {
.my_name = "Channel tags",
.my_update = channel_tags_memoryinfo_update
};

/**
* Init / Done
*/
Expand All @@ -1495,6 +1546,7 @@ channel_tag_init ( void )
htsmsg_t *c, *m;
htsmsg_field_t *f;

memoryinfo_register(&channel_tags_memoryinfo);
TAILQ_INIT(&channel_tags);
if ((c = hts_settings_load("channel/tag")) != NULL) {
HTSMSG_FOREACH(f, c) {
Expand Down
4 changes: 2 additions & 2 deletions src/clock.h
@@ -1,6 +1,6 @@
/*
* Tvheadend - structures
* Copyright (C) 2007 Andreas Öman
* Tvheadend - clock support
* Copyright (C) 2016 Jaroslav Kysela
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down
131 changes: 131 additions & 0 deletions src/epgdb.c
Expand Up @@ -32,6 +32,7 @@
#include "epg.h"
#include "epggrab.h"
#include "config.h"
#include "memoryinfo.h"

#define EPG_DB_VERSION 2
#define EPG_DB_ALLOC_STEP (1024*1024)
Expand Down Expand Up @@ -146,6 +147,125 @@ _epgdb_v2_process( char **sect, htsmsg_t *m, epggrab_stats_t *stats )
}
}

/*
* Memoryinfo
*/

static void epg_memoryinfo_brands_update(memoryinfo_t *my)
{
epg_object_t *eo;
epg_brand_t *eb;
int64_t size = 0, count = 0;

RB_FOREACH(eo, &epg_brands, uri_link) {
eb = (epg_brand_t *)eo;
size += sizeof(*eb);
size += tvh_strlen(eb->uri);
size += lang_str_size(eb->title);
size += lang_str_size(eb->summary);
size += tvh_strlen(eb->image);
count++;
}
memoryinfo_update(my, size, count);
}

static memoryinfo_t epg_memoryinfo_brands = {
.my_name = "EPG Brands",
.my_update = epg_memoryinfo_brands_update
};

static void epg_memoryinfo_seasons_update(memoryinfo_t *my)
{
epg_object_t *eo;
epg_season_t *es;
int64_t size = 0, count = 0;

RB_FOREACH(eo, &epg_seasons, uri_link) {
es = (epg_season_t *)eo;
size += sizeof(*es);
size += tvh_strlen(es->uri);
size += lang_str_size(es->summary);
size += tvh_strlen(es->image);
count++;
}
memoryinfo_update(my, size, count);
}

static memoryinfo_t epg_memoryinfo_seasons = {
.my_name = "EPG Seasons",
.my_update = epg_memoryinfo_seasons_update
};

static void epg_memoryinfo_episodes_update(memoryinfo_t *my)
{
epg_object_t *eo;
epg_episode_t *ee;
int64_t size = 0, count = 0;

RB_FOREACH(eo, &epg_episodes, uri_link) {
ee = (epg_episode_t *)eo;
size += sizeof(*ee);
size += tvh_strlen(ee->uri);
size += lang_str_size(ee->title);
size += lang_str_size(ee->subtitle);
size += lang_str_size(ee->summary);
size += lang_str_size(ee->description);
size += tvh_strlen(ee->image);
size += tvh_strlen(ee->epnum.text);
count++;
}
memoryinfo_update(my, size, count);
}

static memoryinfo_t epg_memoryinfo_episodes = {
.my_name = "EPG Episodes",
.my_update = epg_memoryinfo_episodes_update
};

static void epg_memoryinfo_serieslinks_update(memoryinfo_t *my)
{
epg_object_t *eo;
epg_serieslink_t *es;
int64_t size = 0, count = 0;

RB_FOREACH(eo, &epg_serieslinks, uri_link) {
es = (epg_serieslink_t *)eo;
size += sizeof(*es);
size += tvh_strlen(es->uri);
count++;
}
memoryinfo_update(my, size, count);
}

static memoryinfo_t epg_memoryinfo_serieslinks = {
.my_name = "EPG Series Links",
.my_update = epg_memoryinfo_serieslinks_update
};

static void epg_memoryinfo_broadcasts_update(memoryinfo_t *my)
{
channel_t *ch;
epg_broadcast_t *ebc;
int64_t size = 0, count = 0;

CHANNEL_FOREACH(ch) {
if (ch->ch_epg_parent) continue;
RB_FOREACH(ebc, &ch->ch_epg_schedule, sched_link) {
size += sizeof(*ebc);
size += tvh_strlen(ebc->uri);
size += lang_str_size(ebc->summary);
size += lang_str_size(ebc->description);
count++;
}
}
memoryinfo_update(my, size, count);
}

static memoryinfo_t epg_memoryinfo_broadcasts = {
.my_name = "EPG Broadcasts",
.my_update = epg_memoryinfo_broadcasts_update
};

/*
* Recovery
*/
Expand All @@ -170,6 +290,12 @@ void epg_init ( void )
struct sigaction act, oldact;
char *sect = NULL;

memoryinfo_register(&epg_memoryinfo_brands);
memoryinfo_register(&epg_memoryinfo_seasons);
memoryinfo_register(&epg_memoryinfo_episodes);
memoryinfo_register(&epg_memoryinfo_serieslinks);
memoryinfo_register(&epg_memoryinfo_broadcasts);

/* Find the right file (and version) */
while (fd < 0 && ver > 0) {
fd = hts_settings_open_file(0, "epgdb.v%d", ver);
Expand Down Expand Up @@ -298,6 +424,11 @@ void epg_done ( void )
CHANNEL_FOREACH(ch)
epg_channel_unlink(ch);
epg_skel_done();
memoryinfo_unregister(&epg_memoryinfo_brands);
memoryinfo_unregister(&epg_memoryinfo_seasons);
memoryinfo_unregister(&epg_memoryinfo_episodes);
memoryinfo_unregister(&epg_memoryinfo_serieslinks);
memoryinfo_unregister(&epg_memoryinfo_broadcasts);
pthread_mutex_unlock(&global_lock);
}

Expand Down

0 comments on commit 41b5def

Please sign in to comment.