Browse Source

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 1f757b9ece.

* Revert "Add padding to JackEngineControl to account for inherited data"

This reverts commit 3d8c7d83ad.

* Revert "Move fields and pad to meet alignment constraints"

This reverts commit ff631bbbdc.

* Assure alignment by using 'alignas' on fields
tags/v1.9.19
Colin McEwan GitHub 3 years ago
parent
commit
dff7fa4fa8
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 36 additions and 11 deletions
  1. +5
    -2
      common/JackActivationCount.h
  2. +4
    -1
      common/JackAtomicArrayState.h
  3. +4
    -1
      common/JackAtomicState.h
  4. +3
    -0
      common/JackConnectionManager.cpp
  5. +1
    -1
      common/JackConnectionManager.h
  6. +7
    -3
      common/JackEngineControl.h
  7. +4
    -1
      common/JackMessageBuffer.cpp
  8. +1
    -1
      common/JackMessageBuffer.h
  9. +2
    -0
      common/JackTransportEngine.cpp
  10. +1
    -1
      common/JackTransportEngine.h
  11. +4
    -0
      macosx/JackAtomic_os.h

+ 5
- 2
common/JackActivationCount.h View File

@@ -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);




+ 4
- 1
common/JackAtomicArrayState.h View File

@@ -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;
} }




+ 4
- 1
common/JackAtomicState.h View File

@@ -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;
} }


+ 3
- 0
common/JackConnectionManager.cpp View File

@@ -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++) {


+ 1
- 1
common/JackConnectionManager.h View File

@@ -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;


+ 7
- 3
common/JackEngineControl.h View File

@@ -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);


+ 4
- 1
common/JackMessageBuffer.cpp View File

@@ -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()
{} {}


+ 1
- 1
common/JackMessageBuffer.h View File

@@ -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();


+ 2
- 0
common/JackTransportEngine.cpp View File

@@ -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...


+ 1
- 1
common/JackTransportEngine.h View File

@@ -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);


+ 4
- 0
macosx/JackAtomic_os.h View File

@@ -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…
Cancel
Save