Fix alignment of fields for atomic accesses (#761)
* Assert alignment is suitable for atomic accesses * Move fields and pad to meet alignment constraints * Add padding to JackEngineControl to account for inherited data * Parenthesise padding length for clarity * Revert "Parenthesise padding length for clarity" This reverts commit 1f757b9ece5e3b032743c6c5ac49e83c3928e3de. * Revert "Add padding to JackEngineControl to account for inherited data" This reverts commit 3d8c7d83ad9483280f623171af7e40ccc76cef38. * Revert "Move fields and pad to meet alignment constraints" This reverts commit ff631bbbdc2279df05f3a18dd44e8fd68be2e04d. * Assure alignment by using 'alignas' on fields
This commit is contained in:
parent
0fe68adecc
commit
dff7fa4fa8
|
@ -39,13 +39,16 @@ class JackActivationCount
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
SInt32 fValue;
|
alignas(SInt32) SInt32 fValue;
|
||||||
SInt32 fCount;
|
SInt32 fCount;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
JackActivationCount(): fValue(0), fCount(0)
|
JackActivationCount(): fValue(0), fCount(0)
|
||||||
{}
|
{
|
||||||
|
static_assert(offsetof(JackActivationCount, fValue) % sizeof(fValue) == 0,
|
||||||
|
"fValue must be aligned within JackActivationCount");
|
||||||
|
}
|
||||||
|
|
||||||
bool Signal(JackSynchro* synchro, JackClientControl* control);
|
bool Signal(JackSynchro* synchro, JackClientControl* control);
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "JackAtomic.h"
|
#include "JackAtomic.h"
|
||||||
#include "JackCompilerDeps.h"
|
#include "JackCompilerDeps.h"
|
||||||
#include <string.h> // for memcpy
|
#include <string.h> // for memcpy
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
namespace Jack
|
namespace Jack
|
||||||
{
|
{
|
||||||
|
@ -121,7 +122,7 @@ class JackAtomicArrayState
|
||||||
// fState[2] ==> request
|
// fState[2] ==> request
|
||||||
|
|
||||||
T fState[3];
|
T fState[3];
|
||||||
volatile AtomicArrayCounter fCounter;
|
alignas(UInt32) volatile AtomicArrayCounter fCounter;
|
||||||
|
|
||||||
UInt32 WriteNextStateStartAux(int state, bool* result)
|
UInt32 WriteNextStateStartAux(int state, bool* result)
|
||||||
{
|
{
|
||||||
|
@ -159,6 +160,8 @@ class JackAtomicArrayState
|
||||||
|
|
||||||
JackAtomicArrayState()
|
JackAtomicArrayState()
|
||||||
{
|
{
|
||||||
|
static_assert(offsetof(JackAtomicArrayState, fCounter) % sizeof(fCounter) == 0,
|
||||||
|
"fCounter must be aligned within JackAtomicArrayState");
|
||||||
Counter1(fCounter) = 0;
|
Counter1(fCounter) = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#include "JackAtomic.h"
|
#include "JackAtomic.h"
|
||||||
#include "JackCompilerDeps.h"
|
#include "JackCompilerDeps.h"
|
||||||
#include <string.h> // for memcpy
|
#include <string.h> // for memcpy
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
namespace Jack
|
namespace Jack
|
||||||
{
|
{
|
||||||
|
@ -93,7 +94,7 @@ class JackAtomicState
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
T fState[2];
|
T fState[2];
|
||||||
volatile AtomicCounter fCounter;
|
alignas(UInt32) volatile AtomicCounter fCounter;
|
||||||
SInt32 fCallWriteCounter;
|
SInt32 fCallWriteCounter;
|
||||||
|
|
||||||
UInt32 WriteNextStateStartAux()
|
UInt32 WriteNextStateStartAux()
|
||||||
|
@ -131,6 +132,8 @@ class JackAtomicState
|
||||||
|
|
||||||
JackAtomicState()
|
JackAtomicState()
|
||||||
{
|
{
|
||||||
|
static_assert(offsetof(JackAtomicState, fCounter) % sizeof(fCounter) == 0,
|
||||||
|
"fCounter must be aligned within JackAtomicState");
|
||||||
Counter(fCounter) = 0;
|
Counter(fCounter) = 0;
|
||||||
fCallWriteCounter = 0;
|
fCallWriteCounter = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,9 @@ namespace Jack
|
||||||
JackConnectionManager::JackConnectionManager()
|
JackConnectionManager::JackConnectionManager()
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
static_assert(offsetof(JackConnectionManager, fInputCounter) % sizeof(UInt32) == 0,
|
||||||
|
"fInputCounter must be aligned within JackConnectionManager");
|
||||||
|
|
||||||
jack_log("JackConnectionManager::InitConnections size = %ld ", sizeof(JackConnectionManager));
|
jack_log("JackConnectionManager::InitConnections size = %ld ", sizeof(JackConnectionManager));
|
||||||
|
|
||||||
for (i = 0; i < PORT_NUM_MAX; i++) {
|
for (i = 0; i < PORT_NUM_MAX; i++) {
|
||||||
|
|
|
@ -417,7 +417,7 @@ class SERVER_EXPORT JackConnectionManager
|
||||||
JackFixedArray1<PORT_NUM_FOR_CLIENT> fInputPort[CLIENT_NUM]; /*! Table of input port per refnum : to find a refnum for a given port */
|
JackFixedArray1<PORT_NUM_FOR_CLIENT> fInputPort[CLIENT_NUM]; /*! Table of input port per refnum : to find a refnum for a given port */
|
||||||
JackFixedArray<PORT_NUM_FOR_CLIENT> fOutputPort[CLIENT_NUM]; /*! Table of output port per refnum : to find a refnum for a given port */
|
JackFixedArray<PORT_NUM_FOR_CLIENT> fOutputPort[CLIENT_NUM]; /*! Table of output port per refnum : to find a refnum for a given port */
|
||||||
JackFixedMatrix<CLIENT_NUM> fConnectionRef; /*! Table of port connections by (refnum , refnum) */
|
JackFixedMatrix<CLIENT_NUM> fConnectionRef; /*! Table of port connections by (refnum , refnum) */
|
||||||
JackActivationCount fInputCounter[CLIENT_NUM]; /*! Activation counter per refnum */
|
alignas(UInt32) JackActivationCount fInputCounter[CLIENT_NUM]; /*! Activation counter per refnum */
|
||||||
JackLoopFeedback<CONNECTION_NUM_FOR_PORT> fLoopFeedback; /*! Loop feedback connections */
|
JackLoopFeedback<CONNECTION_NUM_FOR_PORT> fLoopFeedback; /*! Loop feedback connections */
|
||||||
|
|
||||||
bool IsLoopPathAux(int ref1, int ref2) const;
|
bool IsLoopPathAux(int ref1, int ref2) const;
|
||||||
|
|
|
@ -64,7 +64,7 @@ struct SERVER_EXPORT JackEngineControl : public JackShmMem
|
||||||
int fClientPriority;
|
int fClientPriority;
|
||||||
int fMaxClientPriority;
|
int fMaxClientPriority;
|
||||||
char fServerName[JACK_SERVER_NAME_SIZE+1];
|
char fServerName[JACK_SERVER_NAME_SIZE+1];
|
||||||
JackTransportEngine fTransport;
|
alignas(UInt32) JackTransportEngine fTransport;
|
||||||
jack_timer_type_t fClockSource;
|
jack_timer_type_t fClockSource;
|
||||||
int fDriverNum;
|
int fDriverNum;
|
||||||
bool fVerbose;
|
bool fVerbose;
|
||||||
|
@ -86,14 +86,18 @@ struct SERVER_EXPORT JackEngineControl : public JackShmMem
|
||||||
UInt64 fConstraint;
|
UInt64 fConstraint;
|
||||||
|
|
||||||
// Timer
|
// Timer
|
||||||
JackFrameTimer fFrameTimer;
|
alignas(UInt32) JackFrameTimer fFrameTimer;
|
||||||
|
|
||||||
#ifdef JACK_MONITOR
|
#ifdef JACK_MONITOR
|
||||||
JackEngineProfiling fProfiler;
|
JackEngineProfiling fProfiler;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
JackEngineControl(bool sync, bool temporary, long timeout, bool rt, long priority, bool verbose, jack_timer_type_t clock, const char* server_name)
|
JackEngineControl(bool sync, bool temporary, long timeout, bool rt, long priority, bool verbose, jack_timer_type_t clock, const char* server_name)
|
||||||
{
|
{
|
||||||
|
static_assert(offsetof(JackEngineControl, fTransport) % sizeof(UInt32) == 0,
|
||||||
|
"fTransport must be aligned within JackEngineControl");
|
||||||
|
static_assert(offsetof(JackEngineControl, fFrameTimer) % sizeof(UInt32) == 0,
|
||||||
|
"fFrameTimer must be aligned within JackEngineControl");
|
||||||
fBufferSize = 512;
|
fBufferSize = 512;
|
||||||
fSampleRate = 48000;
|
fSampleRate = 48000;
|
||||||
fPeriodUsecs = jack_time_t(1000000.f / fSampleRate * fBufferSize);
|
fPeriodUsecs = jack_time_t(1000000.f / fSampleRate * fBufferSize);
|
||||||
|
|
|
@ -38,7 +38,10 @@ JackMessageBuffer::JackMessageBuffer()
|
||||||
fOutBuffer(0),
|
fOutBuffer(0),
|
||||||
fOverruns(0),
|
fOverruns(0),
|
||||||
fRunning(false)
|
fRunning(false)
|
||||||
{}
|
{
|
||||||
|
static_assert(offsetof(JackMessageBuffer, fOverruns) % sizeof(fOverruns) == 0,
|
||||||
|
"fOverruns must be aligned within JackMessageBuffer");
|
||||||
|
}
|
||||||
|
|
||||||
JackMessageBuffer::~JackMessageBuffer()
|
JackMessageBuffer::~JackMessageBuffer()
|
||||||
{}
|
{}
|
||||||
|
|
|
@ -64,7 +64,7 @@ class JackMessageBuffer : public JackRunnableInterface
|
||||||
JackProcessSync fGuard;
|
JackProcessSync fGuard;
|
||||||
volatile unsigned int fInBuffer;
|
volatile unsigned int fInBuffer;
|
||||||
volatile unsigned int fOutBuffer;
|
volatile unsigned int fOutBuffer;
|
||||||
SInt32 fOverruns;
|
alignas(SInt32) SInt32 fOverruns;
|
||||||
bool fRunning;
|
bool fRunning;
|
||||||
|
|
||||||
void Flush();
|
void Flush();
|
||||||
|
|
|
@ -36,6 +36,8 @@ namespace Jack
|
||||||
|
|
||||||
JackTransportEngine::JackTransportEngine(): JackAtomicArrayState<jack_position_t>()
|
JackTransportEngine::JackTransportEngine(): JackAtomicArrayState<jack_position_t>()
|
||||||
{
|
{
|
||||||
|
static_assert(offsetof(JackTransportEngine, fWriteCounter) % sizeof(fWriteCounter) == 0,
|
||||||
|
"fWriteCounter must be first member of JackTransportEngine to ensure its alignment");
|
||||||
fTransportState = JackTransportStopped;
|
fTransportState = JackTransportStopped;
|
||||||
fTransportCmd = fPreviousCmd = TransportCommandStop;
|
fTransportCmd = fPreviousCmd = TransportCommandStop;
|
||||||
fSyncTimeout = 10000000; /* 10 seconds default...
|
fSyncTimeout = 10000000; /* 10 seconds default...
|
||||||
|
|
|
@ -104,7 +104,7 @@ class SERVER_EXPORT JackTransportEngine : public JackAtomicArrayState<jack_posit
|
||||||
bool fPendingPos;
|
bool fPendingPos;
|
||||||
bool fNetworkSync;
|
bool fNetworkSync;
|
||||||
bool fConditionnal;
|
bool fConditionnal;
|
||||||
SInt32 fWriteCounter;
|
alignas(SInt32) SInt32 fWriteCounter;
|
||||||
|
|
||||||
bool CheckAllRolling(JackClientInterface** table);
|
bool CheckAllRolling(JackClientInterface** table);
|
||||||
void MakeAllStartingLocating(JackClientInterface** table);
|
void MakeAllStartingLocating(JackClientInterface** table);
|
||||||
|
|
|
@ -21,6 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#define __JackAtomic_APPLE__
|
#define __JackAtomic_APPLE__
|
||||||
|
|
||||||
#include "JackTypes.h"
|
#include "JackTypes.h"
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
#if defined(__ppc__) || defined(__ppc64__)
|
#if defined(__ppc__) || defined(__ppc64__)
|
||||||
|
|
||||||
|
@ -67,8 +68,11 @@ static inline char CAS(volatile UInt32 value, UInt32 newvalue, volatile void* ad
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
static inline char CAS(volatile UInt32 value, UInt32 newvalue, volatile void* addr)
|
static inline char CAS(volatile UInt32 value, UInt32 newvalue, volatile void* addr)
|
||||||
{
|
{
|
||||||
|
// Assert pointer is 32-bit aligned
|
||||||
|
assert(((long)addr & (sizeof(int)-1)) == 0);
|
||||||
return __sync_bool_compare_and_swap ((UInt32*)addr, value, newvalue);
|
return __sync_bool_compare_and_swap ((UInt32*)addr, value, newvalue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue