From bfa29336474e9b6db6886d7ded20d9bbd3568f21 Mon Sep 17 00:00:00 2001 From: Basil Nutmeg Date: Sat, 21 Jul 2012 17:30:08 -0700 Subject: [PATCH 1/3] Add new typedefs to support 32/64 mixed mode. The types int64_t, uint64_t, and double have different alignments between common 32-bit and 64-bit platforms, and this can cause trouble when they are used in structs which are shared between address spaces. Introduce new typedefs for these types with special alignment attributes to request consistent alignment. ABI implications: In the current tree, with packed attributes on the relevant structs, the only impact of this change is that the alignments of jack_unique_t and jack_time_t are increased from 4 to 8 on 32-bit platforms, so the layouts of structs which include them as members may be affected. The ABI impact relative to the tree before the packed attributes were introduced is that the alignment of jack_position_t is increased from 4 to 8 on 32-bit platforms. The layout of the struct itself is unmodified, though the layouts of structs which include it as a member may be affected. --- common/jack/systemdeps.h | 14 ++++++++++++++ common/jack/types.h | 22 +++++++++++++++------- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/common/jack/systemdeps.h b/common/jack/systemdeps.h index b4a14720c..b9d378775 100644 --- a/common/jack/systemdeps.h +++ b/common/jack/systemdeps.h @@ -34,6 +34,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #define PRE_PACKED_STRUCTURE #define POST_PACKED_STRUCTURE __attribute__((__packed__)) + #define JACK_ALIGN(N) __attribute__((__aligned__(N))) + + /* A utility for declaring a type which is aligned to its size. */ + #define JACK_ALIGNED_TYPE(T) JACK_ALIGN(sizeof(T)) T + #else #ifdef _MSC_VER @@ -49,9 +54,18 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #define POST_PACKED_STRUCTURE ;__pragma(pack(pop)) /* and POST_PACKED_STRUCTURE needs to be a macro which restores the packing to its previous setting */ + + #define JACK_ALIGN(N) __declspec(align(N)) + + /* A utility for declaring a type which is aligned to its size. */ + #define JACK_ALIGNED_TYPE(T) JACK_ALIGN(sizeof(T)) T + #else #define PRE_PACKED_STRUCTURE #define POST_PACKED_STRUCTURE + + #define JACK_ALIGN(N) + #define JACK_ALIGNED_TYPE(T) T #endif /* _MSC_VER */ #endif /* __GNUC__ */ diff --git a/common/jack/types.h b/common/jack/types.h index fa059159f..53bef451d 100644 --- a/common/jack/types.h +++ b/common/jack/types.h @@ -23,6 +23,14 @@ #include +/* To facilitate direct sharing between 32-bit and 64-bit code, declare + * fully-aligned typedefs for types which would otherwise have differing + * alignment between the two. + */ +typedef JACK_ALIGNED_TYPE(double) jack_double; +typedef JACK_ALIGNED_TYPE(int64_t) jack_int64_t; +typedef JACK_ALIGNED_TYPE(uint64_t) jack_uint64_t; + typedef int32_t jack_shmsize_t; /** @@ -39,7 +47,7 @@ typedef uint32_t jack_nframes_t; * Type used to represent the value of free running * monotonic clock with units of microseconds. */ -typedef uint64_t jack_time_t; +typedef jack_uint64_t jack_time_t; /** * Maximum size of @a load_init string passed to an internal client @@ -530,7 +538,7 @@ typedef enum { } jack_transport_state_t; -typedef uint64_t jack_unique_t; /**< Unique ID (opaque) */ +typedef jack_uint64_t jack_unique_t; /**< Unique ID (opaque) */ /** * Optional struct jack_position_t fields. @@ -564,16 +572,16 @@ struct _jack_position { int32_t bar; /**< current bar */ int32_t beat; /**< current beat-within-bar */ int32_t tick; /**< current tick-within-beat */ - double bar_start_tick; + jack_double bar_start_tick; float beats_per_bar; /**< time signature "numerator" */ float beat_type; /**< time signature "denominator" */ - double ticks_per_beat; - double beats_per_minute; + jack_double ticks_per_beat; + jack_double beats_per_minute; /* JackPositionTimecode fields: (EXPERIMENTAL: could change) */ - double frame_time; /**< current time in seconds */ - double next_time; /**< next sequential frame_time + jack_double frame_time; /**< current time in seconds */ + jack_double next_time; /**< next sequential frame_time (unless repositioned) */ /* JackBBTFrameOffset fields: */ From 933ed40d4caa6e69d6b9678207485a4d2ba8ff48 Mon Sep 17 00:00:00 2001 From: Basil Nutmeg Date: Sat, 21 Jul 2012 17:44:01 -0700 Subject: [PATCH 2/3] Make internal types 32/64 clean. Update internal types to have the same layout between 32-bit and 64-bit, using the new alignment macros and types. --- common/JackEngineControl.h | 8 +++++--- common/shm.h | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/common/JackEngineControl.h b/common/JackEngineControl.h index 2a254b8f1..436bd0a40 100644 --- a/common/JackEngineControl.h +++ b/common/JackEngineControl.h @@ -41,6 +41,8 @@ class JackGraphManager; #define JACK_ENGINE_ROLLING_COUNT 32 #define JACK_ENGINE_ROLLING_INTERVAL 1024 +typedef JACK_ALIGNED_TYPE(UInt64) jack_UInt64; + /*! \brief Engine control in shared memory. */ @@ -81,9 +83,9 @@ struct SERVER_EXPORT JackEngineControl : public JackShmMem float fCPULoad; // For OSX thread - UInt64 fPeriod; - UInt64 fComputation; - UInt64 fConstraint; + jack_UInt64 fPeriod; + jack_UInt64 fComputation; + jack_UInt64 fConstraint; // Timer JackFrameTimer fFrameTimer; diff --git a/common/shm.h b/common/shm.h index c539aa9fb..0f8504e44 100644 --- a/common/shm.h +++ b/common/shm.h @@ -153,7 +153,7 @@ extern "C" struct _jack_shm_info { jack_shm_registry_index_t index; /* offset into the registry */ uint32_t size; - union { + JACK_ALIGN(8) union { void *attached_at; /* address where attached */ char ptr_size[8]; } ptr; /* a "pointer" that has the same 8 bytes size when compling in 32 or 64 bits */ From 30741acbceed2c2f9466a3a1a2e06f1b7d039846 Mon Sep 17 00:00:00 2001 From: Basil Nutmeg Date: Sat, 21 Jul 2012 17:54:52 -0700 Subject: [PATCH 3/3] Remove use of packed structs. Remove use of packed structs, now that the infrastructure for consistently aligning types between 32-bit and 64-bit platforms is in place. This fixes crashes on platforms which enforce alignment rules (because there are places in the code where pointers to packed fields are used). Also, it theoretically improves performance, though I haven't actually performed any measurements. ABI implications: jack_latency_range_t and jack_position_t are no longer packed. The layouts of these structs themselves are unmodified, though the layouts of any structs which include these structs as members may be affected. --- common/JackActivationCount.h | 4 ++-- common/JackAtomicArrayState.h | 8 ++++---- common/JackAtomicState.h | 8 ++++---- common/JackClientControl.h | 4 ++-- common/JackConnectionManager.h | 24 ++++++++++++------------ common/JackEngineControl.h | 4 ++-- common/JackEngineProfiling.h | 16 ++++++++-------- common/JackFilters.h | 12 ++++++------ common/JackFrameTimer.h | 8 ++++---- common/JackGraphManager.h | 4 ++-- common/JackNetTool.h | 12 ++++++------ common/JackPort.h | 4 ++-- common/JackTransportEngine.h | 4 ++-- common/jack/systemdeps.h | 25 +------------------------ common/jack/types.h | 8 ++++---- common/shm.h | 4 ++-- 16 files changed, 63 insertions(+), 86 deletions(-) diff --git a/common/JackActivationCount.h b/common/JackActivationCount.h index 7efc031c9..a77e6e6db 100644 --- a/common/JackActivationCount.h +++ b/common/JackActivationCount.h @@ -33,7 +33,7 @@ struct JackClientControl; \brief Client activation counter. */ -PRE_PACKED_STRUCTURE +/* Note: This class must be kept 32/64 clean! */ class JackActivationCount { @@ -74,7 +74,7 @@ class JackActivationCount return fValue; } -} POST_PACKED_STRUCTURE; +}; } // end of namespace diff --git a/common/JackAtomicArrayState.h b/common/JackAtomicArrayState.h index a2c0139d6..16d2f19c6 100644 --- a/common/JackAtomicArrayState.h +++ b/common/JackAtomicArrayState.h @@ -30,7 +30,7 @@ namespace Jack /*! \brief Counter for CAS */ -PRE_PACKED_STRUCTURE +/* Note: This class must be kept 32/64 clean! */ struct AtomicArrayCounter { union { @@ -68,7 +68,7 @@ struct AtomicArrayCounter return *this; } -} POST_PACKED_STRUCTURE; +}; #define Counter1(e) (e).info.fLongVal #define GetIndex1(e, state) ((e).info.scounter.fByteVal[state]) @@ -109,7 +109,7 @@ struct AtomicArrayCounter // CHECK livelock -PRE_PACKED_STRUCTURE +/* Note: This class must be kept 32/64 clean! */ template class JackAtomicArrayState { @@ -249,7 +249,7 @@ class JackAtomicArrayState WriteNextStateStopAux(state); } -} POST_PACKED_STRUCTURE; +}; } // end of namespace diff --git a/common/JackAtomicState.h b/common/JackAtomicState.h index 1eef4e11b..ea166c156 100644 --- a/common/JackAtomicState.h +++ b/common/JackAtomicState.h @@ -31,7 +31,7 @@ namespace Jack \brief Counter for CAS */ -PRE_PACKED_STRUCTURE +/* Note: This class must be kept 32/64 clean! */ struct AtomicCounter { union { @@ -70,7 +70,7 @@ struct AtomicCounter return *this; } -} POST_PACKED_STRUCTURE; +}; #define Counter(e) (e).info.fLongVal #define CurIndex(e) (e).info.scounter.fShortVal1 @@ -85,7 +85,7 @@ struct AtomicCounter // CHECK livelock -PRE_PACKED_STRUCTURE +/* Note: This class must be kept 32/64 clean! */ template class JackAtomicState { @@ -254,7 +254,7 @@ class JackAtomicState } */ -} POST_PACKED_STRUCTURE; +}; } // end of namespace diff --git a/common/JackClientControl.h b/common/JackClientControl.h index 23b536afa..7c4b51505 100644 --- a/common/JackClientControl.h +++ b/common/JackClientControl.h @@ -34,7 +34,7 @@ namespace Jack \brief Client control possibly in shared memory. */ -PRE_PACKED_STRUCTURE +/* Note: This class must be kept 32/64 clean! */ struct JackClientControl : public JackShmMemAble { char fName[JACK_CLIENT_NAME_SIZE + 1]; @@ -89,7 +89,7 @@ struct JackClientControl : public JackShmMemAble fSessionID = uuid; } -} POST_PACKED_STRUCTURE; +}; } // end of namespace diff --git a/common/JackConnectionManager.h b/common/JackConnectionManager.h index 5041557a1..23bd0f88a 100644 --- a/common/JackConnectionManager.h +++ b/common/JackConnectionManager.h @@ -36,7 +36,7 @@ struct JackClientControl; \brief Utility class. */ -PRE_PACKED_STRUCTURE +/* Note: This class must be kept 32/64 clean! */ template class JackFixedArray { @@ -117,13 +117,13 @@ class JackFixedArray return fCounter; } -} POST_PACKED_STRUCTURE; +}; /*! \brief Utility class. */ -PRE_PACKED_STRUCTURE +/* Note: This class must be kept 32/64 clean! */ template class JackFixedArray1 : public JackFixedArray { @@ -154,13 +154,13 @@ class JackFixedArray1 : public JackFixedArray } } -} POST_PACKED_STRUCTURE; +}; /*! \brief Utility class. */ -PRE_PACKED_STRUCTURE +/* Note: This class must be kept 32/64 clean! */ template class JackFixedMatrix { @@ -250,13 +250,13 @@ class JackFixedMatrix } -} POST_PACKED_STRUCTURE; +}; /*! \brief Utility class. */ -PRE_PACKED_STRUCTURE +/* Note: This class must be kept 32/64 clean! */ template class JackLoopFeedback { @@ -364,13 +364,13 @@ class JackLoopFeedback return -1; } -} POST_PACKED_STRUCTURE; +}; /*! \brief For client timing measurements. */ -PRE_PACKED_STRUCTURE +/* Note: This class must be kept 32/64 clean! */ struct JackClientTiming { jack_time_t fSignaledAt; @@ -393,7 +393,7 @@ struct JackClientTiming fStatus = NotTriggered; } -} POST_PACKED_STRUCTURE; +}; /*! \brief Connection manager. @@ -407,7 +407,7 @@ struct JackClientTiming */ -PRE_PACKED_STRUCTURE +/* Note: This class must be kept 32/64 clean! */ class SERVER_EXPORT JackConnectionManager { @@ -487,7 +487,7 @@ class SERVER_EXPORT JackConnectionManager int SuspendRefNum(JackClientControl* control, JackSynchro* table, JackClientTiming* timing, long time_out_usec); void TopologicalSort(std::vector& sorted); -} POST_PACKED_STRUCTURE; +}; } // end of namespace diff --git a/common/JackEngineControl.h b/common/JackEngineControl.h index 436bd0a40..efb359ca8 100644 --- a/common/JackEngineControl.h +++ b/common/JackEngineControl.h @@ -47,7 +47,7 @@ typedef JACK_ALIGNED_TYPE(UInt64) jack_UInt64; \brief Engine control in shared memory. */ -PRE_PACKED_STRUCTURE +/* Note: This class must be kept 32/64 clean! */ struct SERVER_EXPORT JackEngineControl : public JackShmMem { // Shared state @@ -184,7 +184,7 @@ struct SERVER_EXPORT JackEngineControl : public JackShmMem void CalcCPULoad(JackClientInterface** table, JackGraphManager* manager, jack_time_t cur_cycle_begin, jack_time_t prev_cycle_end); void ResetRollingUsecs(); -} POST_PACKED_STRUCTURE; +}; } // end of namespace diff --git a/common/JackEngineProfiling.h b/common/JackEngineProfiling.h index 04fdb953d..88be1cd54 100644 --- a/common/JackEngineProfiling.h +++ b/common/JackEngineProfiling.h @@ -37,7 +37,7 @@ namespace Jack \brief Timing stucture for a client. */ -PRE_PACKED_STRUCTURE +/* Note: This class must be kept 32/64 clean! */ struct JackTimingMeasureClient { int fRefNum; @@ -54,13 +54,13 @@ struct JackTimingMeasureClient fStatus((jack_client_state_t)0) {} -} POST_PACKED_STRUCTURE; +}; /*! \brief Timing interval in the global table for a given client */ -PRE_PACKED_STRUCTURE +/* Note: This class must be kept 32/64 clean! */ struct JackTimingClientInterval { int fRefNum; @@ -74,13 +74,13 @@ struct JackTimingClientInterval fEndInterval(-1) {} -} POST_PACKED_STRUCTURE; +}; /*! \brief Timing stucture for a table of clients. */ -PRE_PACKED_STRUCTURE +/* Note: This class must be kept 32/64 clean! */ struct JackTimingMeasure { unsigned int fAudioCycle; @@ -96,7 +96,7 @@ struct JackTimingMeasure fPrevCycleEnd(0) {} -} POST_PACKED_STRUCTURE; +}; /*! \brief Client timing monitoring. @@ -105,7 +105,7 @@ struct JackTimingMeasure class JackClientInterface; class JackGraphManager; -PRE_PACKED_STRUCTURE +/* Note: This class must be kept 32/64 clean! */ class SERVER_EXPORT JackEngineProfiling { @@ -132,7 +132,7 @@ class SERVER_EXPORT JackEngineProfiling JackTimingMeasure* GetCurMeasure(); -} POST_PACKED_STRUCTURE; +}; } // end of namespace diff --git a/common/JackFilters.h b/common/JackFilters.h index e245d58bf..cf990b67e 100644 --- a/common/JackFilters.h +++ b/common/JackFilters.h @@ -38,7 +38,7 @@ namespace Jack #define MAX_SIZE 64 - PRE_PACKED_STRUCTURE + /* Note: This class must be kept 32/64 clean! */ struct JackFilter { @@ -66,9 +66,9 @@ namespace Jack return mean / MAX_SIZE; } - } POST_PACKED_STRUCTURE; + }; - PRE_PACKED_STRUCTURE + /* Note: This class must be kept 32/64 clean! */ class JackDelayLockedLoop { @@ -149,9 +149,9 @@ namespace Jack return fCurrentWakeup; } - } POST_PACKED_STRUCTURE; + }; - PRE_PACKED_STRUCTURE + /* Note: This class must be kept 32/64 clean! */ class JackAtomicDelayLockedLoop : public JackAtomicState { public: @@ -215,7 +215,7 @@ namespace Jack return res; } - } POST_PACKED_STRUCTURE; + }; #endif diff --git a/common/JackFrameTimer.h b/common/JackFrameTimer.h index a32e7423f..13916e1f3 100644 --- a/common/JackFrameTimer.h +++ b/common/JackFrameTimer.h @@ -32,7 +32,7 @@ namespace Jack \brief A structure used for time management. */ -PRE_PACKED_STRUCTURE +/* Note: This class must be kept 32/64 clean! */ class SERVER_EXPORT JackTimer { @@ -69,13 +69,13 @@ class SERVER_EXPORT JackTimer return fCurrentWakeup; } -} POST_PACKED_STRUCTURE; +}; /*! \brief A class using the JackAtomicState to manage jack time. */ -PRE_PACKED_STRUCTURE +/* Note: This class must be kept 32/64 clean! */ class SERVER_EXPORT JackFrameTimer : public JackAtomicState { @@ -97,7 +97,7 @@ class SERVER_EXPORT JackFrameTimer : public JackAtomicState void IncFrameTime(jack_nframes_t buffer_size, jack_time_t callback_usecs, jack_time_t period_usecs); void ReadFrameTime(JackTimer* timer); -} POST_PACKED_STRUCTURE; +}; } // end of namespace diff --git a/common/JackGraphManager.h b/common/JackGraphManager.h index 15f0275f2..9c6d8aad0 100644 --- a/common/JackGraphManager.h +++ b/common/JackGraphManager.h @@ -36,7 +36,7 @@ namespace Jack \brief Graph manager: contains the connection manager and the port array. */ -PRE_PACKED_STRUCTURE +/* Note: This class must be kept 32/64 clean! */ class SERVER_EXPORT JackGraphManager : public JackShmMem, public JackAtomicState { @@ -137,7 +137,7 @@ class SERVER_EXPORT JackGraphManager : public JackShmMem, public JackAtomicState static JackGraphManager* Allocate(int port_max); static void Destroy(JackGraphManager* manager); -} POST_PACKED_STRUCTURE; +}; } // end of namespace diff --git a/common/JackNetTool.h b/common/JackNetTool.h index 5d4559a1b..dad7d4439 100644 --- a/common/JackNetTool.h +++ b/common/JackNetTool.h @@ -84,7 +84,7 @@ namespace Jack are kept in LITTLE_ENDIAN format (to avoid 2 conversions in the more common LITTLE_ENDIAN <==> LITTLE_ENDIAN connection case). */ - PRE_PACKED_STRUCTURE + /* Note: This class must be kept 32/64 clean! */ struct _session_params { char fPacketType[8]; //packet type ('param') @@ -106,7 +106,7 @@ namespace Jack uint32_t fKBps; //KB per second for CELT encoder uint32_t fSlaveSyncMode; //is the slave in sync mode ? uint32_t fNetworkLatency; //network latency - } POST_PACKED_STRUCTURE; + }; //net status ********************************************************************************** @@ -167,7 +167,7 @@ namespace Jack */ - PRE_PACKED_STRUCTURE + /* Note: This class must be kept 32/64 clean! */ struct _packet_header { char fPacketType[8]; //packet type ('headr') @@ -180,7 +180,7 @@ namespace Jack uint32_t fCycle; //process cycle counter uint32_t fSubCycle; //midi/audio subcycle counter uint32_t fIsLastPckt; //is it the last packet of a given cycle ('y' or 'n') - } POST_PACKED_STRUCTURE; + }; //net timebase master @@ -205,14 +205,14 @@ namespace Jack \Brief This structure contains transport data to be sent over the network */ - PRE_PACKED_STRUCTURE + /* Note: This class must be kept 32/64 clean! */ struct _net_transport_data { uint32_t fNewState; //is it a state change uint32_t fTimebaseMaster; //is there a new timebase master int32_t fState; //current cycle state jack_position_t fPosition; //current cycle position - } POST_PACKED_STRUCTURE; + }; //midi data *********************************************************************************** diff --git a/common/JackPort.h b/common/JackPort.h index f7a601ed3..4198d83c3 100644 --- a/common/JackPort.h +++ b/common/JackPort.h @@ -35,7 +35,7 @@ namespace Jack \brief Base class for port. */ -PRE_PACKED_STRUCTURE +/* Note: This class must be kept 32/64 clean! */ class SERVER_EXPORT JackPort { @@ -113,7 +113,7 @@ class SERVER_EXPORT JackPort int GetRefNum() const; -} POST_PACKED_STRUCTURE; +}; } // end of namespace diff --git a/common/JackTransportEngine.h b/common/JackTransportEngine.h index b6a4ddcf8..348467834 100644 --- a/common/JackTransportEngine.h +++ b/common/JackTransportEngine.h @@ -89,7 +89,7 @@ We have: class JackClientInterface; -PRE_PACKED_STRUCTURE +/* Note: This class must be kept 32/64 clean! */ class SERVER_EXPORT JackTransportEngine : public JackAtomicArrayState { @@ -194,7 +194,7 @@ class SERVER_EXPORT JackTransportEngine : public JackAtomicArrayState