Introduce rtstella, replace mutex with spinlock in AudioQueue.

This commit is contained in:
Christian Speckner 2023-09-14 21:54:04 +02:00
parent 542d0fd094
commit 61057126a7
6 changed files with 117 additions and 6 deletions

15
configure vendored
View File

@ -320,6 +320,9 @@ case $_host in
retron77)
_host_os=retron77
;;
rtstella)
_host_os=rtstella
;;
mingw32-cross)
_host_os=mingw32msvc
_host_cpu=i386
@ -543,6 +546,10 @@ if test -n "$_host"; then
_build_cheats=no
_build_httplib=no
;;
rtstella)
echo "Compiling rtstella"
DEFINES="$DEFINES -DRTSTELLA"
;;
mingw32-cross)
echo "Cross-compiling for Windows using MinGW."
DEFINES="$DEFINES -DWIN32"
@ -567,7 +574,7 @@ else
echo_n "Checking hosttype... "
echo $_host_os
case $_host_os in
linux* | openbsd* | freebsd* | kfreebsd* | netbsd* | bsd* | gnu0.* | sunos* | hpux* | beos*)
linux* | openbsd* | freebsd* | kfreebsd* | netbsd* | bsd* | gnu0.* | sunos* | hpux* | beos* )
DEFINES="$DEFINES -DUNIX"
_host_os=unix
;;
@ -834,6 +841,12 @@ case $_host_os in
MODULES="$MODULES $SRC_OS/unix"
INCLUDES="$INCLUDES -I$SRC_OS/unix"
;;
rtstella)
DEFINES="$DEFINES -DBSPF_UNIX"
MODULES="$MODULES $SRC_OS/unix $SRC_OS/rtstella"
INCLUDES="$INCLUDES -I$SRC_OS/unix -I$SRC_OS/rtstella"
LIBS="$LIBS -lpthread"
;;
darwin)
DEFINES="$DEFINES -DBSPF_UNIX -DMACOS_KEYS"
MODULES="$MODULES $SRC_OS/unix"

View File

@ -54,7 +54,7 @@ uInt32 AudioQueue::capacity() const
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 AudioQueue::size() const
{
const lock_guard<mutex> guard(myMutex);
const lock_guard<Lock> guard(myLock);
return mySize;
}
@ -74,7 +74,7 @@ uInt32 AudioQueue::fragmentSize() const
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Int16* AudioQueue::enqueue(Int16* fragment)
{
const lock_guard<mutex> guard(myMutex);
const lock_guard<Lock> guard(myLock);
Int16* newFragment = nullptr;
@ -105,7 +105,7 @@ Int16* AudioQueue::enqueue(Int16* fragment)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Int16* AudioQueue::dequeue(Int16* fragment)
{
const lock_guard<mutex> guard(myMutex);
const lock_guard<Lock> guard(myLock);
if (mySize == 0) return nullptr;
@ -128,7 +128,7 @@ Int16* AudioQueue::dequeue(Int16* fragment)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void AudioQueue::closeSink(Int16* fragment)
{
const lock_guard<mutex> guard(myMutex);
const lock_guard<Lock> guard(myLock);
if (myFirstFragmentForDequeue && fragment)
throw runtime_error("attempt to return unknown buffer on closeSink");

View File

@ -23,6 +23,10 @@
#include "bspf.hxx"
#include "StaggeredLogger.hxx"
#ifdef RTSTELLA
#include "Spinlock.hxx"
#endif
/**
This class implements an audio queue that acts both like a ring buffer
and a pool of audio fragments. The TIA emulation core fills a fragment
@ -36,6 +40,11 @@
*/
class AudioQueue
{
#ifdef RTSTELLA
using Lock = Spinlock;
#else
using Lock = std::Mutex;
#endif
public:
/**
@ -120,7 +129,8 @@ class AudioQueue
uInt32 myNextFragment{0};
// We need a mutex for thread safety.
mutable std::mutex myMutex;
mutable Lock myLock;
// The first (empty) enqueue call returns this fragment.
Int16* myFirstFragmentForEnqueue{nullptr};

View File

@ -0,0 +1,39 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2023 by Bradford W. Mott, Stephen Anthony
// and the Stella Team
//
// See the file "License.txt" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//============================================================================
#include "bspf.hxx"
#include "Spinlock.hxx"
Spinlock::Spinlock()
{
pthread_spin_init(&mySpinlock, PTHREAD_PROCESS_PRIVATE);
}
Spinlock::~Spinlock()
{
pthread_spin_destroy(&mySpinlock);
}
void Spinlock::lock()
{
pthread_spin_lock(&mySpinlock);
}
void Spinlock::unlock()
{
pthread_spin_unlock(&mySpinlock);
}

View File

@ -0,0 +1,39 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2023 by Bradford W. Mott, Stephen Anthony
// and the Stella Team
//
// See the file "License.txt" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//============================================================================
#include <pthread.h>
#ifndef SPINLOCK_HXX
#define SPINLOCK_HXX
class Spinlock
{
public:
Spinlock();
~Spinlock();
void lock();
void unlock();
private:
pthread_spinlock_t mySpinlock;
};
#endif // SPINLOCK_HXX

10
src/os/rtstella/module.mk Normal file
View File

@ -0,0 +1,10 @@
MODULE := src/os/rtstella
MODULE_OBJS := \
src/os/rtstella/Spinlock.o
MODULE_DIRS += \
src/os/rtstella
# Include common rules
include $(srcdir)/common.rules