padding patch for mutex problem; better x86_64 alignment patch from mike taht; fixes for ringbuffer types for x86_64 from mike taht

git-svn-id: svn://localhost/ardour2/trunk@1593 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis
2007-03-15 12:30:17 +00:00
parent 44502336c8
commit a1960ba3c0
6 changed files with 88 additions and 103 deletions

View File

@@ -33,7 +33,6 @@
#include <pbd/fastlog.h>
#include <pbd/ringbufferNPT.h>
#include <pbd/stateful.h>
#include <pbd/mutex.h>
#include <pbd/statefuldestructible.h>
#include <ardour/ardour.h>
@@ -237,8 +236,9 @@ class IO;
virtual void use_destructive_playlist () = 0;
static nframes_t disk_io_chunk_frames;
vector<CaptureInfo*> capture_info;
PBDMutex capture_info_lock;
std::vector<CaptureInfo*> capture_info;
char pad1[1024];
Glib::Mutex capture_info_lock;
uint32_t i_am_the_modifier;
@@ -293,7 +293,8 @@ class IO;
AlignStyle _persistent_alignment_style;
bool first_input_change;
PBDMutex state_lock;
char pad2[1024];
Glib::Mutex state_lock;
nframes_t scrub_start;
nframes_t scrub_buffer_size;

View File

@@ -127,8 +127,6 @@ AudioDiskstream::~AudioDiskstream ()
}
channels.clear();
}
state_lock.lock ();
}
void

View File

@@ -356,7 +356,6 @@ void
Diskstream::playlist_modified ()
{
if (!i_am_the_modifier && !overwrite_queued) {
cerr << _name << " request overwrite\n";
_session.request_overwrite_buffer (this);
overwrite_queued = true;
}

View File

@@ -78,6 +78,12 @@ using namespace ARDOUR;
using namespace PBD;
using boost::shared_ptr;
#ifdef __x86_64__
static const int CPU_CACHE_ALIGN = 64;
#else
static const int CPU_CACHE_ALIGN = 16; /* arguably 32 on most arches, but it matters less */
#endif
const char* Session::_template_suffix = X_(".template");
const char* Session::_statefile_suffix = X_(".ardour");
const char* Session::_pending_suffix = X_(".pending");
@@ -1396,7 +1402,7 @@ Session::set_block_size (nframes_t nframes)
uint32_t np;
current_block_size = nframes;
for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
free (*i);
}
@@ -1417,7 +1423,7 @@ Session::set_block_size (nframes_t nframes)
#ifdef NO_POSIX_MEMALIGN
buf = (Sample *) malloc(current_block_size * sizeof(Sample));
#else
posix_memalign((void **)&buf,16,current_block_size * 4);
posix_memalign((void **)&buf,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample));
#endif
*i = buf;
@@ -3563,7 +3569,7 @@ Session::ensure_passthru_buffers (uint32_t howmany)
#ifdef NO_POSIX_MEMALIGN
p = (Sample *) malloc(current_block_size * sizeof(Sample));
#else
posix_memalign((void **)&p,16,current_block_size * 4);
posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample));
#endif
_passthru_buffers.push_back (p);
@@ -3572,7 +3578,7 @@ Session::ensure_passthru_buffers (uint32_t howmany)
#ifdef NO_POSIX_MEMALIGN
p = (Sample *) malloc(current_block_size * sizeof(Sample));
#else
posix_memalign((void **)&p,16,current_block_size * 4);
posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * 4);
#endif
memset (p, 0, sizeof (Sample) * current_block_size);
_silent_buffers.push_back (p);
@@ -3582,7 +3588,7 @@ Session::ensure_passthru_buffers (uint32_t howmany)
#ifdef NO_POSIX_MEMALIGN
p = (Sample *) malloc(current_block_size * sizeof(Sample));
#else
posix_memalign((void **)&p,16,current_block_size * 4);
posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample));
#endif
memset (p, 0, sizeof (Sample) * current_block_size);
_send_buffers.push_back (p);
@@ -3862,7 +3868,7 @@ Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t le
#ifdef NO_POSIX_MEMALIGN
b = (Sample *) malloc(chunk_size * sizeof(Sample));
#else
posix_memalign((void **)&b,16,chunk_size * 4);
posix_memalign((void **)&b,4096,chunk_size * sizeof(Sample));
#endif
buffers.push_back (b);
}

View File

@@ -1,16 +0,0 @@
#include <glibmm/thread.h>
#include <iostream>
class PBDMutex : public Glib::Mutex
{
public:
PBDMutex() : Glib::Mutex() {}
~PBDMutex() {
if (trylock()) {
unlock ();
} else {
std::cerr << "Mutex @ " << this << " locked during destructor\n";
unlock ();
}
}
};

View File

@@ -20,19 +20,16 @@
#ifndef ringbuffer_h
#define ringbuffer_h
//#include <sys/mman.h>
#include <glib.h>
template<class T>
class RingBuffer
{
public:
RingBuffer (size_t sz) {
size_t power_of_two;
for (power_of_two = 1; 1U<<power_of_two < sz; power_of_two++);
RingBuffer (guint sz) {
// size = ffs(sz); /* find first [bit] set is a single inlined assembly instruction. But it looks like the API rounds up so... */
guint power_of_two;
for (power_of_two = 1; 1U<<power_of_two < sz; power_of_two++);
size = 1<<power_of_two;
size_mask = size;
size_mask -= 1;
@@ -47,44 +44,44 @@ class RingBuffer
void reset () {
/* !!! NOT THREAD SAFE !!! */
g_atomic_int_set (&write_ptr, 0);
g_atomic_int_set (&read_ptr, 0);
g_atomic_int_set (&write_idx, 0);
g_atomic_int_set (&read_idx, 0);
}
void set (size_t r, size_t w) {
void set (guint r, guint w) {
/* !!! NOT THREAD SAFE !!! */
g_atomic_int_set (&write_ptr, w);
g_atomic_int_set (&read_ptr, r);
g_atomic_int_set (&write_idx, w);
g_atomic_int_set (&read_idx, r);
}
size_t read (T *dest, size_t cnt);
size_t write (T *src, size_t cnt);
guint read (T *dest, guint cnt);
guint write (T *src, guint cnt);
struct rw_vector {
T *buf[2];
size_t len[2];
guint len[2];
};
void get_read_vector (rw_vector *);
void get_write_vector (rw_vector *);
void decrement_read_ptr (size_t cnt) {
g_atomic_int_set (&read_ptr, (g_atomic_int_get(&read_ptr) - cnt) & size_mask);
void decrement_read_idx (guint cnt) {
g_atomic_int_set (&read_idx, (g_atomic_int_get(&read_idx) - cnt) & size_mask);
}
void increment_read_ptr (size_t cnt) {
g_atomic_int_set (&read_ptr, (g_atomic_int_get(&read_ptr) + cnt) & size_mask);
void increment_read_idx (guint cnt) {
g_atomic_int_set (&read_idx, (g_atomic_int_get(&read_idx) + cnt) & size_mask);
}
void increment_write_ptr (size_t cnt) {
g_atomic_int_set (&write_ptr, (g_atomic_int_get(&write_ptr) + cnt) & size_mask);
void increment_write_idx (guint cnt) {
g_atomic_int_set (&write_idx, (g_atomic_int_get(&write_idx) + cnt) & size_mask);
}
size_t write_space () {
size_t w, r;
guint write_space () {
guint w, r;
w = g_atomic_int_get (&write_ptr);
r = g_atomic_int_get (&read_ptr);
w = g_atomic_int_get (&write_idx);
r = g_atomic_int_get (&read_idx);
if (w > r) {
return ((r - w + size) & size_mask) - 1;
@@ -95,11 +92,11 @@ class RingBuffer
}
}
size_t read_space () {
size_t w, r;
guint read_space () {
guint w, r;
w = g_atomic_int_get (&write_ptr);
r = g_atomic_int_get (&read_ptr);
w = g_atomic_int_get (&write_idx);
r = g_atomic_int_get (&read_idx);
if (w > r) {
return w - r;
@@ -109,28 +106,28 @@ class RingBuffer
}
T *buffer () { return buf; }
size_t get_write_ptr () const { return g_atomic_int_get (&write_ptr); }
size_t get_read_ptr () const { return g_atomic_int_get (&read_ptr); }
size_t bufsize () const { return size; }
guint get_write_idx () const { return g_atomic_int_get (&write_idx); }
guint get_read_idx () const { return g_atomic_int_get (&read_idx); }
guint bufsize () const { return size; }
protected:
T *buf;
size_t size;
mutable gint write_ptr;
mutable gint read_ptr;
size_t size_mask;
guint size;
mutable guint write_idx;
mutable guint read_idx;
guint size_mask;
};
template<class T> size_t
RingBuffer<T>::read (T *dest, size_t cnt)
template<class T> guint
RingBuffer<T>::read (T *dest, guint cnt)
{
size_t free_cnt;
size_t cnt2;
size_t to_read;
size_t n1, n2;
size_t priv_read_ptr;
guint free_cnt;
guint cnt2;
guint to_read;
guint n1, n2;
guint priv_read_idx;
priv_read_ptr=g_atomic_int_get(&read_ptr);
priv_read_idx=g_atomic_int_get(&read_idx);
if ((free_cnt = read_space ()) == 0) {
return 0;
@@ -138,39 +135,39 @@ RingBuffer<T>::read (T *dest, size_t cnt)
to_read = cnt > free_cnt ? free_cnt : cnt;
cnt2 = priv_read_ptr + to_read;
cnt2 = priv_read_idx + to_read;
if (cnt2 > size) {
n1 = size - priv_read_ptr;
n1 = size - priv_read_idx;
n2 = cnt2 & size_mask;
} else {
n1 = to_read;
n2 = 0;
}
memcpy (dest, &buf[priv_read_ptr], n1 * sizeof (T));
priv_read_ptr = (priv_read_ptr + n1) & size_mask;
memcpy (dest, &buf[priv_read_idx], n1 * sizeof (T));
priv_read_idx = (priv_read_idx + n1) & size_mask;
if (n2) {
memcpy (dest+n1, buf, n2 * sizeof (T));
priv_read_ptr = n2;
priv_read_idx = n2;
}
g_atomic_int_set(&read_ptr, priv_read_ptr);
g_atomic_int_set(&read_idx, priv_read_idx);
return to_read;
}
template<class T> size_t
RingBuffer<T>::write (T *src, size_t cnt)
template<class T> guint
RingBuffer<T>::write (T *src, guint cnt)
{
size_t free_cnt;
size_t cnt2;
size_t to_write;
size_t n1, n2;
size_t priv_write_ptr;
guint free_cnt;
guint cnt2;
guint to_write;
guint n1, n2;
guint priv_write_idx;
priv_write_ptr=g_atomic_int_get(&write_ptr);
priv_write_idx=g_atomic_int_get(&write_idx);
if ((free_cnt = write_space ()) == 0) {
return 0;
@@ -178,25 +175,25 @@ RingBuffer<T>::write (T *src, size_t cnt)
to_write = cnt > free_cnt ? free_cnt : cnt;
cnt2 = priv_write_ptr + to_write;
cnt2 = priv_write_idx + to_write;
if (cnt2 > size) {
n1 = size - priv_write_ptr;
n1 = size - priv_write_idx;
n2 = cnt2 & size_mask;
} else {
n1 = to_write;
n2 = 0;
}
memcpy (&buf[priv_write_ptr], src, n1 * sizeof (T));
priv_write_ptr = (priv_write_ptr + n1) & size_mask;
memcpy (&buf[priv_write_idx], src, n1 * sizeof (T));
priv_write_idx = (priv_write_idx + n1) & size_mask;
if (n2) {
memcpy (buf, src+n1, n2 * sizeof (T));
priv_write_ptr = n2;
priv_write_idx = n2;
}
g_atomic_int_set(&write_ptr, priv_write_ptr);
g_atomic_int_set(&write_idx, priv_write_idx);
return to_write;
}
@@ -204,12 +201,12 @@ template<class T> void
RingBuffer<T>::get_read_vector (RingBuffer<T>::rw_vector *vec)
{
size_t free_cnt;
size_t cnt2;
size_t w, r;
guint free_cnt;
guint cnt2;
guint w, r;
w = g_atomic_int_get (&write_ptr);
r = g_atomic_int_get (&read_ptr);
w = g_atomic_int_get (&write_idx);
r = g_atomic_int_get (&read_idx);
if (w > r) {
free_cnt = w - r;
@@ -244,12 +241,12 @@ template<class T> void
RingBuffer<T>::get_write_vector (RingBuffer<T>::rw_vector *vec)
{
size_t free_cnt;
size_t cnt2;
size_t w, r;
guint free_cnt;
guint cnt2;
guint w, r;
w = g_atomic_int_get (&write_ptr);
r = g_atomic_int_get (&read_ptr);
w = g_atomic_int_get (&write_idx);
r = g_atomic_int_get (&read_idx);
if (w > r) {
free_cnt = ((r - w + size) & size_mask) - 1;