The zynthian[1] project would like to upgrade to linuxsampler-2 but the
source currently requires patching to add ARM support.

The attached patch to RTPath.cpp and atomic.h is required. The patch will
also be maintained in this github repo[2] until it lands in trunk.

The Raspberry PI 3 is more than capable of running linuxsampler, so it
would be great if this patch could be applied to the main source tree.

[1] http://zynthian.org/
[2] https://github.com/steveb/rpi_linuxsampler_patch
diff --git a/src/common/RTMath.cpp b/src/common/RTMath.cpp
index f228c08..bc53f8f 100644
--- a/src/common/RTMath.cpp
+++ b/src/common/RTMath.cpp
@@ -22,6 +22,9 @@
  ***************************************************************************/
 
 #include "RTMath.h"
+#if defined(__arm__)
+#include <time.h>
+#endif
 
 // for unsafeMicroSeconds() implementation
 #if !defined(WIN32) && !defined(__APPLE__)
@@ -73,6 +76,10 @@ RTMathBase::time_stamp_t RTMathBase::CreateTimeStamp() {
     return t;
     #elif defined(__APPLE__)
     return (time_stamp_t) mach_absolute_time();
+    #elif defined(__arm__)
+    timespec tp;
+    clock_gettime(CLOCK_MONOTONIC, &tp);
+    return tp.tv_nsec;
     #else // we don't want to use a slow generic solution
     #  error "Sorry, LinuxSampler lacks time stamp code for your system."
     #  error "Please report this error and the CPU you are using to the LinuxSampler developers mailing list!"
diff --git a/src/common/atomic.h b/src/common/atomic.h
index b1f5c43..bd8ec38 100644
--- a/src/common/atomic.h
+++ b/src/common/atomic.h
@@ -1186,6 +1186,127 @@ static __inline__ int atomic_dec_and_test(volatile atomic_t *v)
 #endif /* __ARCH_M68K_ATOMIC __ */
 
 #else
+#ifdef __arm__
+
+/*
+ * That part of code for ARM11 was taken from ALSA's iatomic.h
+ */
+
+/*
+ * FIXME: bellow code is valid only for SA11xx
+ */
+
+/*
+ * Save the current interrupt enable state & disable IRQs
+ */
+#define local_irq_save(x)					\
+	({							\
+		unsigned long temp;				\
+	__asm__ __volatile__(					\
+	"mrs	%0, cpsr		@ local_irq_save\n"	\
+"	orr	%1, %0, #128\n"					\
+"	msr	cpsr_c, %1"					\
+	: "=r" (x), "=r" (temp)					\
+	:							\
+	: "memory");						\
+	})
+
+/*
+ * restore saved IRQ & FIQ state
+ */
+#define local_irq_restore(x)					\
+	__asm__ __volatile__(					\
+	"msr	cpsr_c, %0		@ local_irq_restore\n"	\
+	:							\
+	: "r" (x)						\
+	: "memory")
+
+#define __save_flags_cli(x) local_irq_save(x)
+#define __restore_flags(x) local_irq_restore(x)
+
+typedef struct { volatile int counter; } atomic_t;
+
+#define ATOMIC_INIT(i)	{ (i) }
+
+#define atomic_read(v)	((v)->counter)
+#define atomic_set(v,i)	(((v)->counter) = (i))
+
+static __inline__ void atomic_add(int i, volatile atomic_t *v)
+{
+	unsigned long flags;
+
+	__save_flags_cli(flags);
+	v->counter += i;
+	__restore_flags(flags);
+}
+
+static __inline__ void atomic_sub(int i, volatile atomic_t *v)
+{
+	unsigned long flags;
+
+	__save_flags_cli(flags);
+	v->counter -= i;
+	__restore_flags(flags);
+}
+
+static __inline__ void atomic_inc(volatile atomic_t *v)
+{
+	unsigned long flags;
+
+	__save_flags_cli(flags);
+	v->counter += 1;
+	__restore_flags(flags);
+}
+
+static __inline__ void atomic_dec(volatile atomic_t *v)
+{
+	unsigned long flags;
+
+	__save_flags_cli(flags);
+	v->counter -= 1;
+	__restore_flags(flags);
+}
+
+static __inline__ int atomic_dec_and_test(volatile atomic_t *v)
+{
+	unsigned long flags;
+	int result;
+
+	__save_flags_cli(flags);
+	v->counter -= 1;
+	result = (v->counter == 0);
+	__restore_flags(flags);
+
+	return result;
+}
+
+static inline int atomic_add_negative(int i, volatile atomic_t *v)
+{
+	unsigned long flags;
+	int result;
+
+	__save_flags_cli(flags);
+	v->counter += i;
+	result = (v->counter < 0);
+	__restore_flags(flags);
+
+	return result;
+}
+
+static __inline__ void atomic_clear_mask(unsigned long mask, unsigned long *addr)
+{
+	unsigned long flags;
+
+	__save_flags_cli(flags);
+	*addr &= ~mask;
+	__restore_flags(flags);
+}
+
+#define mb() __asm__ __volatile__ ("" : : : "memory")
+#define rmb() mb()
+#define wmb() mb()
+
+#else
 
 #warning libs/pbd has no implementation of strictly atomic operations for your hardware.
 
@@ -1231,6 +1352,7 @@ static __inline__ int atomic_inc_and_test(atomic_t *v)
 }
 
 #  endif /* __NO_STRICT_ATOMIC */
+#  endif /* arm */
 #  endif /* m68k */
 #  endif /* mips */
 #  endif /* s390 */
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Linuxsampler-devel mailing list
Linuxsampler-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxsampler-devel

Reply via email to