Here is a patch to do some basic cheap refmem counting/byte allocation counting,
does it look correct?
It produces output like this (after *ONLY* entering watch recordings):
before cmyth_proglist_create: Total Refs: 9 Total Bytes: 207
after cmyth_proglist_create: Total Refs: 10 Total Bytes: 227
before cmyth_proglist_get_all_recorded: Total Refs: 10 Total Bytes:
227
event thread started (pid 159)
after cmyth_proglist_get_all_recorded: Total Refs: 21790 Total Bytes:
763174
The refcounter takes 12 bytes per reference, so of the total usage of 763174
bytes, 261000 is the refcounter (or roughly 1/3 of the total memory used for
programs info).
Doing some testing it does appear to leak (it takes 21000 to load my recordings
but I have seem up to 5x that number-more testing to follow).
Also a "timestamp" takes 7-4 byte ints, and there are 6 timestamps per program
info so in my case 6 x 7 x 4 x 725 = 121,000 bytes for just the timestamps, so
if one were able to use "unsigned char" and if the structure will pack in that
case (I don't know what sort of alignment issues there are on a PPC, on i386
there would not be an issue, on IA64 slow kernel interrupts have to take care of
that), but if it would work that would reduced the timestamps to 1/4 of that.
Roger
Simon Hyde wrote:
On Fri, 30 May 2008, Roger Heflin wrote:
Hi,
Sorry for replying so late, kinda forgot about this thread... :)
Anyway, I just got a H3 wireless MVP and am seing the same problems
(not just when deleting). I'm up to 1900 movies/episodes on my MythTV
backend and moving around in the mvpmc menus is an excersice in
patience... selecting MythTV->Watch Recordings takes a long time to
end up in a usable state.
I am up to 720 and so far it is not that bad.
I have noticed that it takes 3-5 seconds to load the shows, I am
wondering if it
would be faster to read in from a binary file located on NFS that
contained
the show data, or put a binary file on NFS that at least contains the
more
troublesome data and retrieve it as necessary (when one selects show
info).
This sounds like a bit of a cludge, we'd be better off accessing the
data directly over SQL than requiring some extra server-side
functionality/files. If we had to resort to SQL for normal recordings
then we might want to make it optional. It's nice that at the moment SQL
access is only required for LiveTV.
From some looking around with the current method that mvpmc uses it is
not
possible to grab a single recording's information. It may be
possible if we
were using the xml method that is in the 0.21 and newer myth, and then
it would
be possible to not load/ignore the information that is not often used and
retrieve as necessary.
Here is the current proginfo structure:
[snip large proginfo structure]
So about 200 bytes per program before anything is allocated to any of
the char
*. If something is allocated to the char *'s then there are a
number of bytes
for the reference counters for overhead for each allocation, plus the
bytes
allocated.
I suspect that a number of the entries aren't used anywhere except
show_info and
a number of the entries even if they are used in show_info aren't of
any use to
a person so could probably be ignored.
It's worth noting that a (re-encoded) version of the data in this
structure is passed back to MythTV to request playback of a recording,
so you also need to determin what data in this structure MythTV
uses/needs for file i/o.
I need to figure out a way to gauge how much memory is being used so I
can get
an idea of how much is being saved.
Also, watching recordings through the MythTV interface simply doesn't
work when I use the wireless network - if I start to watch something
it takes a few minutes until anything appears, and then only in short
bursts. I can see on the router lights and statistics that only a few
packets every few seconds are actually transmitted...
However, if I watch the same recording by selecting the .mpg file
through the file browser it plays just fine, and I can see that the
wireless traffic flows perfectly. Could this be because there is much
more free (and less fragmented) memory when playing that way?
My guess would be that this is related to the different block sizes in
use for the MythTV protocol connection compared to the NFS connection,
and them travelling better over NFS. Luckily for you you should be able
to tell mvpmc to use NFS to play the file whilst still browsing through
the MythTV interface. Simply add the -r /path/to/mythtv/mpegs to the
command line options for mvpmc in your dongle.bin.config
Finally, I wanted to ask if anything came from this discussion. Did
anyone manage to test the proposed changes? If not, how long does it
take to get to the point where I can play around with the code myself?
I make my living as a codemonkey but haven't done much private coding
in years except for a few private hacks in mythfilldatabase...
/ Niklas (op)
It should be very easy. The normal build environment automatically
downloads (into ~/downloads) everything required, and then automatically
builds all the toolchains required (into ~/toolchains).
The 2 major pre-requisits are the git version control system, and the
scons "makefile replacement". On a debian system you can get both of
these by doing an:
apt-get install git-core git-gui scons
Whilst the version of git in debian etch does work, it's a little old
and lacks some of the functionality you may want, so if you're a debian
user then I'd recommend getting the version from http://www.backports.org.
Once you have git and scons installed you should be able to simply do:
git clone git://git.mvpmc.org/repos/mvpmc.git
and then:
make
And everything necessary should be downloaded/compiled. I think part of
the toolchain build process still errors when it has succeeded, so you
may find you have to run make a couple of times to get all the way through.
Cheers,
Simon
diff --git a/include/mvp_refmem.h b/include/mvp_refmem.h
index 3bc1d10..fe1a25a 100644
--- a/include/mvp_refmem.h
+++ b/include/mvp_refmem.h
@@ -32,6 +32,9 @@
* -----------------------------------------------------------------
*/
+/* Return current number of references outstanding for everything */
+extern int ref_get_refcount();
+
/**
* Release a reference to allocated memory.
* \param p allocated memory
diff --git a/libs/libcmyth/proglist.c b/libs/libcmyth/proglist.c
index 40d7458..165b444 100644
--- a/libs/libcmyth/proglist.c
+++ b/libs/libcmyth/proglist.c
@@ -52,11 +52,13 @@ static void
cmyth_proglist_destroy(cmyth_proglist_t pl)
{
int i;
-
+ ref_get_refcount("Before cmyth_proglist_destroy");
cmyth_dbg(CMYTH_DBG_DEBUG, "%s\n", __FUNCTION__);
if (!pl) {
return;
}
+
+ printf("Destroying proglist %p with count %ld\n",pl,pl->proglist_count);
for (i = 0; i < pl->proglist_count; ++i) {
if (pl->proglist_list[i]) {
ref_release(pl->proglist_list[i]);
@@ -66,6 +68,7 @@ cmyth_proglist_destroy(cmyth_proglist_t pl)
if (pl->proglist_list) {
free(pl->proglist_list);
}
+ ref_get_refcount("After cmyth_proglist_destroy");
}
/*
@@ -89,6 +92,7 @@ cmyth_proglist_create(void)
cmyth_proglist_t ret;
cmyth_dbg(CMYTH_DBG_DEBUG, "%s\n", __FUNCTION__);
+ ref_get_refcount("before cmyth_proglist_create:");
ret = ref_alloc(sizeof(*ret));
if (!ret) {
return(NULL);
@@ -97,6 +101,8 @@ cmyth_proglist_create(void)
ret->proglist_list = NULL;
ret->proglist_count = 0;
+ ref_get_refcount("after cmyth_proglist_create:");
+
return ret;
}
@@ -317,6 +323,7 @@ cmyth_proglist_get_all_recorded(cmyth_conn_t control)
{
cmyth_proglist_t proglist = cmyth_proglist_create();
+ ref_get_refcount("before cmyth_proglist_get_all_recorded:");
if (proglist == NULL) {
cmyth_dbg(CMYTH_DBG_ERROR,
"%s: cmyth_proglist_create() failed\n",
@@ -333,6 +340,7 @@ cmyth_proglist_get_all_recorded(cmyth_conn_t control)
ref_release(proglist);
return NULL;
}
+ ref_get_refcount("after cmyth_proglist_get_all_recorded:");
return proglist;
}
@@ -359,7 +367,7 @@ cmyth_proglist_t
cmyth_proglist_get_all_pending(cmyth_conn_t control)
{
cmyth_proglist_t proglist = cmyth_proglist_create();
-
+ ref_get_refcount("before cmyth_get_all_pending:");
if (proglist == NULL) {
cmyth_dbg(CMYTH_DBG_ERROR,
"%s: cmyth_proglist_create() failed\n",
@@ -376,6 +384,7 @@ cmyth_proglist_get_all_pending(cmyth_conn_t control)
ref_release(proglist);
return NULL;
}
+ ref_get_refcount("before cmyth_get_all_pending:");
return proglist;
}
diff --git a/libs/librefmem/alloc.c b/libs/librefmem/alloc.c
index ae34d8d..574ec85 100644
--- a/libs/librefmem/alloc.c
+++ b/libs/librefmem/alloc.c
@@ -55,6 +55,8 @@
#define GUARD_MAGIC 0xe3
#endif /* DEBUG */
+static int total_refcount=0;
+static int total_bytecount=0;
/*
* struct refcounter
*
@@ -102,6 +104,12 @@ typedef struct {
static refcounter_t *ref_list[REF_ALLOC_BINS];
#endif /* DEBUG */
+int ref_get_refcount(char *loc)
+ {
+ printf("%s Total Refs: %7d Total Bytes:
%8d\n",loc,total_refcount,total_bytecount);
+ return(total_refcount);
+ }
+
#if defined(DEBUG)
static inline void
ref_remove(refcounter_t *ref)
@@ -228,6 +236,9 @@ __ref_alloc(size_t len, const char *file, const char *func,
int line)
if (block) {
memset(block, 0, sizeof(refcounter_t) + len);
mvp_atomic_set(&ref->refcount, 1);
+ total_refcount ++;
+ total_bytecount += sizeof(refcounter_t) + len;
+
#ifdef DEBUG
ref->magic = ALLOC_MAGIC;
ref->file = file;
@@ -403,6 +414,7 @@ ref_hold(void *p)
assert(guard->magic == GUARD_MAGIC);
#endif /* DEBUG */
mvp_atomic_inc(&ref->refcount);
+ total_refcount ++;
}
refmem_dbg(REF_DBG_DEBUG, "%s(%p) }\n", __FUNCTION__, p);
return p;
@@ -445,6 +457,10 @@ ref_release(void *p)
sizeof(refcounter_t) + ref->length);
assert(guard->magic == GUARD_MAGIC);
#endif /* DEBUG */
+
+/* Remove a refcount */
+ total_refcount --;
+
if (mvp_atomic_dec_and_test(&ref->refcount)) {
/*
* Last reference, destroy the structure (if
@@ -463,6 +479,8 @@ ref_release(void *p)
refmem_ref_remove(ref);
ref->next = NULL;
#endif /* DEBUG */
+/* Remove its bytes */
+ total_bytecount -= ( sizeof(refcounter_t) +
ref->length);
free(block);
}
if (ref->refcount < 0)
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Mvpmc-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mvpmc-users
mvpmc wiki: http://mvpmc.wikispaces.com/