Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

[libcmyth/refmem] Pull across upstream changes to support other architec... #1471

Closed
wants to merge 1 commit into from

6 participants

@dteirney
Collaborator

...tures.

RFC: This PR contains a number of updates from upstream for the refmem bits within the cmyth library. I'm not familiar with this area much so this is really an exercise to try and get XBMC and upstream in sync. I've reviewed the diffs and made the changes to both sides that seem sensible but I don't know enough about what this code is supposed to do for the new architectures that it supports, e.g. ANDROID, ARM, APPLE. I'd really appreciate it if the devs who know more about those platforms could have a look.

The associated upstream cmyth diff to get XBMC and upstream to finally match can be found at dteirney/cmyth@5991469

@MartijnKaijser

ping anyone..

@Memphiz
Owner

I don't even know what libcmyth does in xbmc?

@fetzerch

Libcmyth is used to access a MythTV backend via the old myth:// protocol, that was used before PVR was implemented in XBMC: http://wiki.xbmc.org/?title=MythTV#Old-style_myth:.2F.2F_protocol_access
Starting with XBMC Frodo, the PVR addon for MythTV can be used for this.
The PVR addon supports everything that was possible with the myth:// protocol. (With EDL support being added to the Gotham PVR API)

I don't know what the team plans to do with such legacy sources, but I guess that it makes more sense to improve the PVR addons and to remove those legacy sources.

@elupus
Collaborator

I'm perfectly fine with this as long as it still seem to work. As long as it exists in our source, we should stay close to upstream.

jenkins test this please

@elupus
Collaborator

jenkins build this please

@Memphiz
Owner

Jenkins failed because this seems to be based on some Old master branch without jenkins Support - rebase please

@elupus
Collaborator

@dteirney think you could rebase it and build test it again?

@dteirney
Collaborator

Is any other part of XBMC using librefmem other than libcmyth? If not then we probably need to start considering how / when that functionality can be moved out to the PVR addon. The libcmyth library used by the PVR addon has also diverged further from upstream (and internal XBMC) and I've not had time to move that work upstream. There are still some gaps in PVR support compared to the existing myth:// protocol that would be good to close out somehow, e.g. Movies from the PVR recording list included in the XBMC Movie database. Would be great to get recorded TV Shows into the XBMC TV database as well.

@MartijnKaijser

jenkins build this please

@elupus elupus was assigned
@MartijnKaijser

@dteirney care to update?

@dteirney
Collaborator

I've just updated to the MythTV PVR Addon for our use at home after upgrading to Myth 0.27, which the version of libcmyth in XBMC doesn't support.

There are a few things that the PVR Addon doesn't support that the standard File / Directory handling in XBMC does, which hasn't completely passed the WAF test, e.g. sorting by title does not appear to be possible in the PVR directories.

Anyway, overall I think we should look to deprecate and ultimately remove the current MythTV support within XBMC in favour of making the current PVR support better. What is the general protocol for removing parts of XBMC?

@jmarshallnz
Owner

Basically just throw up a PR to do the removal. I don't suspect there'll be much in the way of complaints if the PVR add-on is just about there anyway.

My understanding is that with the PVR window rewrite you'll get the sorting stuff (or at least it'll make it easier to do so).

@jmarshallnz
Owner

Oh, and if it's mostly the filesystem stuff that's being removed, then it may be that it can be moved to a binary add-on instead in the near future (i.e. next couple months).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Sep 24, 2012
  1. [libcmyth/refmem] Pull across upstream changes to support other archi…

    David Teirney authored
    …tectures.
This page is out of date. Refresh to see the latest.
View
96 lib/cmyth/include/refmem/atomic.h
@@ -24,15 +24,30 @@
#pragma GCC optimization_level 0
#endif
-#ifdef _MSC_VER
+#if defined(_MSC_VER)
#include <windows.h>
+#define inline __inline
#endif
+
+#if defined __mips__
+#include <atomic.h>
+#endif
+
+#if defined(__APPLE__)
+#include <libkern/OSAtomic.h>
+
+typedef volatile int32_t mvp_atomic_t;
+
+#define __mvp_atomic_increment(x) OSAtomicIncrement32(x)
+#define __mvp_atomic_decrement(x) OSAtomicDecrement32(x)
+#else
+typedef volatile unsigned int mvp_atomic_t;
+
/**
* Atomically incremente a reference count variable.
* \param valp address of atomic variable
* \return incremented reference count
*/
-typedef unsigned mvp_atomic_t;
static inline unsigned
__mvp_atomic_increment(mvp_atomic_t *valp)
{
@@ -45,8 +60,8 @@ __mvp_atomic_increment(mvp_atomic_t *valp)
: "r" (valp), "0" (0x1)
: "cc", "memory"
);
-#elif defined __i386__
- asm volatile (".byte 0xf0, 0x0f, 0xc1, 0x02" /*lock; xaddl %eax, (%edx) */
+#elif defined __i386__ || defined __x86_64__
+ __asm__ volatile (".byte 0xf0, 0x0f, 0xc1, 0x02" /*lock; xaddl %eax, (%edx) */
: "=a" (__val)
: "0" (1), "m" (*valp), "d" (valp)
: "memory");
@@ -63,16 +78,35 @@ __mvp_atomic_increment(mvp_atomic_t *valp)
: "r" (valp)
: "cc", "memory");
#elif defined _MSC_VER
- __val = InterlockedIncrement(valp);
-#else
+ __val = InterlockedIncrement(valp);
+#elif defined ANDROID
+ __val = __atomic_inc(valp) + 1;
+#elif defined __arm__ && !defined __thumb__
+ int tmp1, tmp2;
+ int inc = 1;
+ __asm__ __volatile__ (
+ "\n"
+ "0:"
+ "ldr %0, [%3]\n"
+ "add %1, %0, %4\n"
+ "swp %2, %1, [%3]\n"
+ "cmp %0, %2\n"
+ "swpne %0, %2, [%3]\n"
+ "bne 0b\n"
+ : "=&r"(tmp1), "=&r"(__val), "=&r"(tmp2)
+ : "r" (valp), "r"(inc)
+ : "cc", "memory");
+#elif defined __mips__
+ __val = atomic_increment_val(valp);
+#elif defined __GNUC__
/*
* Don't know how to atomic increment for a generic architecture
- * so punt and just increment the value.
+ * so try to use GCC builtin
*/
-#ifdef _WIN32
- #pragma message("unknown architecture, atomic increment is not...");
+ __val = __sync_add_and_fetch(valp,1);
#else
- #warning unknown architecture, atomic increment is not...
+#if !defined(_MSC_VER)
+#warning unknown architecture, atomic increment is not...
#endif
__val = ++(*valp);
#endif
@@ -96,8 +130,8 @@ __mvp_atomic_decrement(mvp_atomic_t *valp)
: "r" (valp), "0" (0x1)
: "cc", "memory"
);
-#elif defined __i386__
- asm volatile (".byte 0xf0, 0x0f, 0xc1, 0x02" /*lock; xaddl %eax, (%edx) */
+#elif defined __i386__ || defined __x86_64__
+ __asm__ volatile (".byte 0xf0, 0x0f, 0xc1, 0x02" /*lock; xaddl %eax, (%edx) */
: "=a" (__val)
: "0" (-1), "m" (*valp), "d" (valp)
: "memory");
@@ -113,6 +147,25 @@ __mvp_atomic_decrement(mvp_atomic_t *valp)
: "=&r" (__val)
: "r" (valp)
: "cc", "memory");
+#elif defined ANDROID
+ __val = __atomic_dec(valp) - 1;
+#elif defined __arm__ && !defined __thumb__
+ int tmp1, tmp2;
+ int inc = -1;
+ __asm__ __volatile__ (
+ "\n"
+ "0:"
+ "ldr %0, [%3]\n"
+ "add %1, %0, %4\n"
+ "swp %2, %1, [%3]\n"
+ "cmp %0, %2\n"
+ "swpne %0, %2, [%3]\n"
+ "bne 0b\n"
+ : "=&r"(tmp1), "=&r"(__val), "=&r"(tmp2)
+ : "r" (valp), "r"(inc)
+ : "cc", "memory");
+#elif defined __mips__
+ __val = atomic_decrement_val(valp);
#elif defined __sparcv9__
mvp_atomic_t __newval, __oldval = (*valp);
do
@@ -126,17 +179,23 @@ __mvp_atomic_decrement(mvp_atomic_t *valp)
/* The value for __val is in '__oldval' */
__val = __oldval;
#elif defined _MSC_VER
- __val = InterlockedDecrement(valp);
-#else
+ __val = InterlockedDecrement(valp);
+#elif defined __GNUC__
/*
* Don't know how to atomic decrement for a generic architecture
- * so punt and just decrement the value.
+ * so use GCC builtin
*/
-//#warning unknown architecture, atomic decrement is not...
+ __val = __sync_sub_and_fetch(valp,1);
+#else
+#if !defined(_MSC_VER)
+#warning unknown architecture, atomic deccrement is not...
+#endif
__val = --(*valp);
#endif
return __val;
}
+#endif
+
#define mvp_atomic_inc __mvp_atomic_inc
static inline int mvp_atomic_inc(mvp_atomic_t *a) {
return __mvp_atomic_increment(a);
@@ -157,6 +216,11 @@ static inline void mvp_atomic_set(mvp_atomic_t *a, unsigned val) {
*a = val;
};
+#define mvp_atomic_val __mvp_atomic_val
+static inline int mvp_atomic_val(mvp_atomic_t *a) {
+ return *a;
+};
+
#ifdef __APPLE__
#pragma GCC optimization_level reset
#endif
View
32 lib/cmyth/include/refmem/refmem.h
@@ -24,12 +24,17 @@
#ifndef __REFMEM_H
#define __REFMEM_H
+#include "atomic.h"
+
/*
* -----------------------------------------------------------------
* Types
* -----------------------------------------------------------------
*/
+/* Return current number of references outstanding for everything */
+extern int ref_get_refcount();
+
/**
* Release a reference to allocated memory.
* \param p allocated memory
@@ -95,4 +100,31 @@ extern void ref_set_destroy(void *block, ref_destroy_t func);
*/
extern void ref_alloc_show(void);
+/*
+ * Debug level constants used to determine the level of debug tracing
+ * to be done and the debug level of any given message.
+ */
+
+#define REF_DBG_NONE -1
+#define REF_DBG_ERRORS 0
+#define REF_DBG_COUNTERS 1
+#define REF_DBG_DEBUG 2
+#define REF_DBG_ALL 3
+
+/**
+ * Set librefmem debug level.
+ * \param l debugging level (-1 for none, 3 for all)
+ */
+void refmem_dbg_level(int l);
+
+/**
+ * Enable all librefmem debugging.
+ */
+void refmem_dbg_all();
+
+/**
+ * Disable all librefmem debugging.
+ */
+void refmem_dbg_none();
+
#endif /* __REFMEM_H */
View
84 lib/cmyth/librefmem/alloc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2006, Eric Lund, Jon Gettler
+ * Copyright (C) 2005-2010, Eric Lund, Jon Gettler
* http://www.mvpmc.org/
*
* This library is free software; you can redistribute it and/or
@@ -40,9 +40,6 @@
*/
#include <sys/types.h>
#include <stdlib.h>
-#ifndef _MSC_VER
-#include <unistd.h>
-#endif
#include <errno.h>
#include <refmem/refmem.h>
#include <refmem/atomic.h>
@@ -52,9 +49,14 @@
#include <stdio.h>
#ifdef DEBUG
+#include <inttypes.h>
#include <assert.h>
#define ALLOC_MAGIC 0xef37a45d
#define GUARD_MAGIC 0xe3
+#define GUARD_BYTES 1
+#if defined(ANDROID)
+#include <android/log.h>
+#endif
#endif /* DEBUG */
/* Disable optimization on OSX ppc
@@ -63,6 +65,8 @@
#pragma GCC optimization_level 0
#endif
+static mvp_atomic_t total_refcount = 0;
+static mvp_atomic_t total_bytecount = 0;
/*
* struct refcounter
*
@@ -98,7 +102,7 @@ typedef struct refcounter {
#ifdef DEBUG
typedef struct {
- unsigned char magic;
+ unsigned char magic[GUARD_BYTES];
} guard_t;
#endif /* DEBUG */
@@ -110,6 +114,32 @@ typedef struct {
static refcounter_t *ref_list[REF_ALLOC_BINS];
#endif /* DEBUG */
+#ifdef DEBUG
+static inline void
+guard_set(guard_t *guard, unsigned char val)
+{
+ memset(&(guard->magic[0]), val, GUARD_BYTES);
+}
+
+static inline void
+guard_check(guard_t *guard)
+{
+ int i;
+
+ for (i=0; i<GUARD_BYTES; i++) {
+ assert(guard->magic[i] == GUARD_MAGIC);
+ }
+}
+#endif /* DEBUG */
+
+int ref_get_refcount(char *loc)
+{
+ refmem_dbg(REF_DBG_COUNTERS,
+ "%40.40s Refs: %7d Bytes: %8d\n",
+ loc,total_refcount,total_bytecount);
+ return(total_refcount);
+}
+
#if defined(DEBUG)
static inline void
ref_remove(refcounter_t *ref)
@@ -186,6 +216,21 @@ ref_alloc_show(void)
}
}
+#if defined(ANDROID)
+ {
+ char buf[512];
+
+ snprintf(buf, sizeof(buf),
+ "refmem allocation count: %d\n", count);
+ __android_log_print(ANDROID_LOG_DEBUG, "refmem", buf);
+ snprintf(buf, sizeof(buf),
+ "refmem allocation bytes: %d\n", bytes);
+ __android_log_print(ANDROID_LOG_DEBUG, "refmem", buf);
+ snprintf(buf, sizeof(buf),
+ "refmem unique allocation types: %d\n", types);
+ __android_log_print(ANDROID_LOG_DEBUG, "refmem", buf);
+ }
+#else
printf("refmem allocation count: %d\n", count);
printf("refmem allocation bytes: %d\n", bytes);
printf("refmem unique allocation types: %d\n", types);
@@ -194,6 +239,7 @@ ref_alloc_show(void)
alloc_list[i].file, alloc_list[i].func,
alloc_list[i].line, alloc_list[i].count);
}
+#endif
}
#else
void
@@ -236,6 +282,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);
+ mvp_atomic_inc(&total_refcount);
+ total_bytecount += sizeof(refcounter_t) + len;
+
#ifdef DEBUG
ref->magic = ALLOC_MAGIC;
ref->file = file;
@@ -243,7 +292,7 @@ __ref_alloc(size_t len, const char *file, const char *func, int line)
ref->line = line;
guard = (guard_t*)((uintptr_t)block +
sizeof(refcounter_t) + len);
- guard->magic = GUARD_MAGIC;
+ guard_set(guard, GUARD_MAGIC);
ref_add(ref);
#endif /* DEBUG */
ref->destroy = NULL;
@@ -409,9 +458,10 @@ ref_hold(void *p)
assert(ref->magic == ALLOC_MAGIC);
guard = (guard_t*)((uintptr_t)block +
sizeof(refcounter_t) + ref->length);
- assert(guard->magic == GUARD_MAGIC);
+ guard_check(guard);
#endif /* DEBUG */
mvp_atomic_inc(&ref->refcount);
+ mvp_atomic_inc(&total_refcount);
}
refmem_dbg(REF_DBG_DEBUG, "%s(%p) }\n", __FUNCTION__, p);
return p;
@@ -441,6 +491,7 @@ ref_release(void *p)
#ifdef DEBUG
guard_t *guard;
#endif /* DEBUG */
+ int refcount;
refmem_dbg(REF_DBG_DEBUG, "%s(%p) {\n", __FUNCTION__, p);
if (p) {
@@ -452,8 +503,14 @@ ref_release(void *p)
assert(ref->magic == ALLOC_MAGIC);
guard = (guard_t*)((uintptr_t)block +
sizeof(refcounter_t) + ref->length);
- assert(guard->magic == GUARD_MAGIC);
+ guard_check(guard);
#endif /* DEBUG */
+
+ /* Remove a refcount */
+ mvp_atomic_dec(&total_refcount);
+
+ refcount = ((int)ref->refcount) - 1;
+
if (mvp_atomic_dec_and_test(&ref->refcount)) {
/*
* Last reference, destroy the structure (if
@@ -468,14 +525,17 @@ ref_release(void *p)
__FILE__, __LINE__, __FUNCTION__);
#ifdef DEBUG
ref->magic = 0;
- guard->magic = 0;
-#ifndef _WIN32
- refmem_ref_remove(ref);
-#endif
+ guard_set(guard, 0);
+ ref_remove(ref);
ref->next = NULL;
#endif /* DEBUG */
+ /* Remove its bytes */
+ total_bytecount -= ( sizeof(refcounter_t) + ref->length);
free(block);
}
+ if (refcount < 0)
+ fprintf(stderr, "*** %s(): %p refcount %d ***\n",
+ __FUNCTION__, p, ref->refcount);
}
refmem_dbg(REF_DBG_DEBUG, "%s(%p) }\n", __FUNCTION__, p);
}
View
33 lib/cmyth/librefmem/refmem_local.h
@@ -1,20 +1,25 @@
-#ifndef __REFMEM_LOCAL_H
-#define __REFMEM_LOCAL_H
-
/*
- * Debug level constants used to determine the level of debug tracing
- * to be done and the debug level of any given message.
+ * Copyright (C) 2004-2012, Eric Lund, Jon Gettler
+ * http://www.mvpmc.org/
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#define REF_DBG_NONE -1
-#define REF_DBG_DEBUG 0
-#define REF_DBG_ALL 0
-
-void refmem_dbg_level(int l);
-
-void refmem_dbg_all();
-
-void refmem_dbg_none();
+#ifndef __REFMEM_LOCAL_H
+#define __REFMEM_LOCAL_H
void refmem_dbg(int level, char *fmt, ...);
+
#endif /* __REFMEM_LOCAL_H */
Something went wrong with that request. Please try again.