diff options
author | Takashi Iwai <tiwai@suse.de> | 2021-10-11 16:57:45 +0200 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2021-10-11 16:57:45 +0200 |
commit | 63e7c13d86141f3c9de51dcf2cf3510dc753b45e (patch) | |
tree | 8b3875227ba91a03a36b513542e849bb128913f1 | |
parent | 54b6914338e0369cf20eb6fa8b2d99cd9c472777 (diff) | |
download | salsa-lib-63e7c13d86141f3c9de51dcf2cf3510dc753b45e.tar.gz |
Allow enforcing 64bit timespec build
Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r-- | configure.ac | 14 | ||||
-rw-r--r-- | src/asound.h | 164 | ||||
-rw-r--r-- | src/pcm.c | 8 | ||||
-rw-r--r-- | src/pcm_macros.h | 12 | ||||
-rw-r--r-- | src/rawmidi_macros.h | 2 | ||||
-rw-r--r-- | src/recipe.h.in | 3 | ||||
-rw-r--r-- | src/timer_macros.h | 2 |
7 files changed, 173 insertions, 32 deletions
diff --git a/configure.ac b/configure.ac index 69a0ddf..8058556 100644 --- a/configure.ac +++ b/configure.ac @@ -142,6 +142,11 @@ AC_ARG_ENABLE(ctlasciiparser, [enable ctl ASCII parser (for amixer)]), ctlasciiparser="$enableval", ctlasciiparser="no") +AC_ARG_ENABLE(time64, + AS_HELP_STRING([--enable-time64], + [enforce 64bit timespec for ioctls]), + struct_time64="$enableval", struct_time64="no") + AC_ARG_ENABLE(everything, AS_HELP_STRING([--enable-everything], [enable everything :)]), @@ -166,6 +171,7 @@ if test "$everything" = "yes"; then support_4bit="yes" abicheck="yes" ctlasciiparser="yes" + struct_time64="yes" fi SALSA_DEPLIBS="" @@ -259,6 +265,13 @@ else fi AC_SUBST(SALSA_CTL_ASCII_PARSER) +if test "$struct_time64" = "yes"; then + SALSA_STRUCT_TIME64=1 +else + SALSA_STRUCT_TIME64=0 +fi +AC_SUBST(SALSA_STRUCT_TIME64) + if test "$delight_valgrind" = "yes"; then AC_DEFINE(DELIGHT_VALGRIND) fi @@ -319,3 +332,4 @@ echo " - Support string-output via snd_output: $output_buffer" echo " - Support floating-point: $support_float" echo " - Enable library ABI check: $abicheck" echo " - Support ctl ASCII parser: $ctlasciiparser" +echo " - Enforce 64bit timespec: $struct_time64" diff --git a/src/asound.h b/src/asound.h index d919f65..e405c3d 100644 --- a/src/asound.h +++ b/src/asound.h @@ -20,6 +20,7 @@ #include <sys/time.h> #include <sys/types.h> #include <sys/ioctl.h> +#include <stdint.h> #include <endian.h> #if __BYTE_ORDER == __LITTLE_ENDIAN #define SND_LITTLE_ENDIAN @@ -33,6 +34,38 @@ #define SNDRV_PROTOCOL_VERSION(major, minor, subminor) \ (((major) << 16) | ((minor) << 8) | (subminor)) +typedef struct timeval snd_timestamp_t; +typedef struct timespec snd_htimestamp_t; + +struct __snd_timespec64 { + int64_t tv_sec; + int64_t tv_nsec; +}; + +#if __TIMESIZE == 32 && SALSA_STRUCT_TIME64 +#define __snd_timespec __snd_timespec64 +typedef struct { unsigned char pad[sizeof(int64_t) - sizeof(int)]; } __time_pad; + +static inline void __copy_to_snd_htimestamp(const struct __snd_timespec *src, snd_htimestamp_t *dst) +{ + dst->tv_sec = src->tv_sec; + dst->tv_nsec = src->tv_nsec; +} + +static inline snd_htimestamp_t __to_snd_htimestamp(const struct __snd_timespec *src) +{ + snd_htimestamp_t val; + __copy_to_snd_htimestamp(src, &val); + return val; +} +#else +#define __snd_timespec timespec +typedef struct { unsigned char pad[sizeof(time_t) - sizeof(int)]; } __time_pad; + +#define __copy_to_snd_htimestamp(src, dst) do { *(dst) = *(src); } while (0) +#define __to_snd_htimestamp(src) *(src) +#endif + /* IEC958 status bits definition */ typedef struct snd_aes_iec958 { unsigned char status[24]; @@ -99,10 +132,10 @@ enum { /* PCM interface */ -#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 12) +#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 15) typedef unsigned long snd_pcm_uframes_t; -typedef long snd_pcm_sframes_t; +typedef signed long snd_pcm_sframes_t; typedef enum _snd_pcm_class { SND_PCM_CLASS_GENERIC = 0, @@ -229,6 +262,12 @@ typedef enum _snd_pcm_subformat { #define SNDRV_PCM_INFO_SYNC_START 0x00400000 #define SNDRV_PCM_INFO_NO_PERIOD_WAKEUP 0x00800000 #define SNDRV_PCM_INFO_HAS_WALL_CLOCK 0x01000000 +#define SNDRV_PCM_INFO_HAS_WALL_CLOCK 0x01000000 +#define SNDRV_PCM_INFO_HAS_LINK_ATIME 0x01000000 +#define SNDRV_PCM_INFO_HAS_LINK_ABSOLUTE_ATIME 0x02000000 +#define SNDRV_PCM_INFO_HAS_LINK_ESTIMATED_ATIME 0x04000000 +#define SNDRV_PCM_INFO_HAS_LINK_SYNCHRONIZED_ATIME 0x08000000 +#define SNDRV_PCM_INFO_EXPLICIT_SYNC 0x10000000 typedef enum _snd_pcm_state { SND_PCM_STATE_OPEN = 0, @@ -245,8 +284,17 @@ typedef enum _snd_pcm_state { enum { SNDRV_PCM_MMAP_OFFSET_DATA = 0x00000000, - SNDRV_PCM_MMAP_OFFSET_STATUS = 0x80000000, - SNDRV_PCM_MMAP_OFFSET_CONTROL = 0x81000000, + SNDRV_PCM_MMAP_OFFSET_STATUS_OLD = 0x80000000, + SNDRV_PCM_MMAP_OFFSET_CONTROL_OLD = 0x81000000, + SNDRV_PCM_MMAP_OFFSET_STATUS_NEW = 0x82000000, + SNDRV_PCM_MMAP_OFFSET_CONTROL_NEW = 0x83000000, +#if __TIMESIZE == 64 || SALSA_STRUCT_TIME64 + SNDRV_PCM_MMAP_OFFSET_STATUS = SNDRV_PCM_MMAP_OFFSET_STATUS_NEW, + SNDRV_PCM_MMAP_OFFSET_CONTROL = SNDRV_PCM_MMAP_OFFSET_CONTROL_NEW, +#else + SNDRV_PCM_MMAP_OFFSET_STATUS = SNDRV_PCM_MMAP_OFFSET_STATUS_OLD, + SNDRV_PCM_MMAP_OFFSET_CONTROL = SNDRV_PCM_MMAP_OFFSET_CONTROL_OLD, +#endif }; typedef union _snd_pcm_sync_id { @@ -369,10 +417,31 @@ struct sndrv_pcm_channel_info { unsigned int step; }; +typedef enum _snd_pcm_audio_tstamp_type { + SND_PCM_AUDIO_TSTAMP_TYPE_COMPAT = 0, + SND_PCM_AUDIO_TSTAMP_TYPE_DEFAULT = 1, + SND_PCM_AUDIO_TSTAMP_TYPE_LINK = 2, + SND_PCM_AUDIO_TSTAMP_TYPE_LINK_ABSOLUTE = 3, + SND_PCM_AUDIO_TSTAMP_TYPE_LINK_ESTIMATED = 4, + SND_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED = 5, + SND_PCM_AUDIO_TSTAMP_TYPE_LAST = SND_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED +} snd_pcm_audio_tstamp_type_t; + +#if __TIMESIZE == 32 && SALSA_STRUCT_TIME64 +#define __snd_pcm_mmap_status64 snd_pcm_mmap_status +#define __snd_pcm_mmap_control64 snd_pcm_mmap_control +#define __snd_pcm_sync_ptr64 snd_pcm_sync_ptr +#else +#define __snd_pcm_mmap_status snd_pcm_mmap_status +#define __snd_pcm_mmap_control snd_pcm_mmap_control +#define __snd_pcm_sync_ptr snd_pcm_sync_ptr +#endif + typedef struct snd_pcm_status { int state; - struct timespec trigger_tstamp; - struct timespec tstamp; + __time_pad pad1; + struct __snd_timespec trigger_tstamp; + struct __snd_timespec tstamp; snd_pcm_uframes_t appl_ptr; snd_pcm_uframes_t hw_ptr; snd_pcm_sframes_t delay; @@ -380,20 +449,23 @@ typedef struct snd_pcm_status { snd_pcm_uframes_t avail_max; snd_pcm_uframes_t overrange; int suspended_state; - struct timespec audio_tstamp; - unsigned char reserved[60 - sizeof(struct timespec)]; + struct __snd_timespec audio_tstamp; + struct __snd_timespec driver_tstamp; + unsigned int audio_tstamp_accuracy; + + unsigned char reserved[52 - 2*sizeof(struct __snd_timespec)]; } snd_pcm_status_t; -struct snd_pcm_mmap_status { - int state; +struct __snd_pcm_mmap_status { + snd_pcm_state_t state; int pad1; snd_pcm_uframes_t hw_ptr; - struct timespec tstamp; - int suspended_state; - struct timespec audio_tstamp; + struct __snd_timespec tstamp; + snd_pcm_state_t suspended_state; + struct __snd_timespec audio_tstamp; }; -struct snd_pcm_mmap_control { +struct __snd_pcm_mmap_control { snd_pcm_uframes_t appl_ptr; snd_pcm_uframes_t avail_min; }; @@ -402,14 +474,56 @@ struct snd_pcm_mmap_control { #define SNDRV_PCM_SYNC_PTR_APPL (1<<1) #define SNDRV_PCM_SYNC_PTR_AVAIL_MIN (1<<2) -struct snd_pcm_sync_ptr { +struct __snd_pcm_sync_ptr { unsigned int flags; union { - struct snd_pcm_mmap_status status; + struct __snd_pcm_mmap_status status; unsigned char reserved[64]; } s; union { - struct snd_pcm_mmap_control control; + struct __snd_pcm_mmap_control control; + unsigned char reserved[64]; + } c; +}; + +#if defined(__BYTE_ORDER) ? __BYTE_ORDER == __BIG_ENDIAN : defined(__BIG_ENDIAN) +typedef char __pad_before_uframe[sizeof(int64_t) - sizeof(snd_pcm_uframes_t)]; +typedef char __pad_after_uframe[0]; +#else +typedef char __pad_before_uframe[0]; +typedef char __pad_after_uframe[sizeof(int64_t) - sizeof(snd_pcm_uframes_t)]; +#endif + +struct __snd_pcm_mmap_status64 { + snd_pcm_state_t state; + unsigned int pad1; + __pad_before_uframe __pad1; + snd_pcm_uframes_t hw_ptr; + __pad_after_uframe __pad2; + struct __snd_timespec64 tstamp; + snd_pcm_state_t suspended_state; + unsigned int pad3; + struct __snd_timespec64 audio_tstamp; +}; + +struct __snd_pcm_mmap_control64 { + __pad_before_uframe __pad1; + snd_pcm_uframes_t appl_ptr; + __pad_before_uframe __pad2; + __pad_before_uframe __pad3; + snd_pcm_uframes_t avail_min; + __pad_after_uframe __pad4; +}; + +struct __snd_pcm_sync_ptr64 { + unsigned int flags; + unsigned int pad1; + union { + struct __snd_pcm_mmap_status64 status; + unsigned char reserved[64]; + } s; + union { + struct __snd_pcm_mmap_control64 control; unsigned char reserved[64]; } c; }; @@ -431,6 +545,7 @@ enum { SNDRV_PCM_IOCTL_INFO = _IOR('A', 0x01, snd_pcm_info_t), SNDRV_PCM_IOCTL_TSTAMP = _IOW('A', 0x02, int), SNDRV_PCM_IOCTL_TTSTAMP = _IOW('A', 0x03, int), + SNDRV_PCM_IOCTL_USER_PVERSION = _IOW('A', 0x04, int), SNDRV_PCM_IOCTL_HW_REFINE = _IOWR('A', 0x10, snd_pcm_hw_params_t), SNDRV_PCM_IOCTL_HW_PARAMS = _IOWR('A', 0x11, snd_pcm_hw_params_t), SNDRV_PCM_IOCTL_HW_FREE = _IO('A', 0x12), @@ -438,7 +553,10 @@ enum { SNDRV_PCM_IOCTL_STATUS = _IOR('A', 0x20, snd_pcm_status_t), SNDRV_PCM_IOCTL_DELAY = _IOR('A', 0x21, snd_pcm_sframes_t), SNDRV_PCM_IOCTL_HWSYNC = _IO('A', 0x22), + __SNDRV_PCM_IOCTL_SYNC_PTR = _IOWR('A', 0x23, struct __snd_pcm_sync_ptr), + __SNDRV_PCM_IOCTL_SYNC_PTR64 = _IOWR('A', 0x23, struct __snd_pcm_sync_ptr64), SNDRV_PCM_IOCTL_SYNC_PTR = _IOWR('A', 0x23, struct snd_pcm_sync_ptr), + SNDRV_PCM_IOCTL_STATUS_EXT = _IOWR('A', 0x24, snd_pcm_status_t), SNDRV_PCM_IOCTL_CHANNEL_INFO = _IOR('A', 0x32, struct sndrv_pcm_channel_info), SNDRV_PCM_IOCTL_PREPARE = _IO('A', 0x40), SNDRV_PCM_IOCTL_RESET = _IO('A', 0x41), @@ -567,7 +685,7 @@ typedef struct snd_rawmidi_params { typedef struct snd_rawmidi_status { int stream; - struct timespec tstamp; + struct __snd_timespec tstamp; size_t avail; size_t xruns; unsigned char reserved[16]; @@ -678,7 +796,7 @@ typedef struct snd_timer_params { } snd_timer_params_t; typedef struct snd_timer_status { - struct timespec tstamp; + struct __snd_timespec tstamp; unsigned int resolution; unsigned int lost; unsigned int overrun; @@ -727,12 +845,9 @@ typedef enum _snd_timer_event { SND_TIMER_EVENT_MRESUME = SND_TIMER_EVENT_RESUME + 10 } snd_timer_event_t; -typedef struct timeval snd_timestamp_t; -typedef struct timespec snd_htimestamp_t; - typedef struct _snd_timer_tread { snd_timer_event_t event; - snd_htimestamp_t tstamp; + struct __snd_timespec tstamp; unsigned int val; } snd_timer_tread_t; @@ -865,8 +980,7 @@ typedef struct snd_ctl_elem_value { } bytes; struct snd_aes_iec958 iec958; } value; - struct timespec tstamp; - unsigned char reserved[128-sizeof(struct timespec)]; + unsigned char reserved[128]; } snd_ctl_elem_value_t; typedef struct snd_ctl_tlv { @@ -107,6 +107,14 @@ int snd_pcm_open(snd_pcm_t **pcmp, const char *name, goto error; } + if (SNDRV_PROTOCOL_VERSION(2, 0, 14) <= ver) { + unsigned int user_ver = SNDRV_PCM_VERSION; + if (ioctl(fd, SNDRV_PCM_IOCTL_USER_PVERSION, &user_ver) < 0) { + err = -errno; + goto error; + } + } + pcm = calloc(1, sizeof(*pcm)); if (!pcm) { err = -ENOMEM; diff --git a/src/pcm_macros.h b/src/pcm_macros.h index f252014..07cd538 100644 --- a/src/pcm_macros.h +++ b/src/pcm_macros.h @@ -151,7 +151,9 @@ int snd_pcm_hw_params_current(snd_pcm_t *pcm, snd_pcm_hw_params_t *params) __SALSA_EXPORT_FUNC int snd_pcm_status(snd_pcm_t *pcm, snd_pcm_status_t *status) { - if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_STATUS, status) < 0) + int cmd = pcm->protocol < SNDRV_PROTOCOL_VERSION(2, 0, 13) ? + SNDRV_PCM_IOCTL_STATUS : SNDRV_PCM_IOCTL_STATUS_EXT; + if (ioctl(pcm->fd, cmd, status) < 0) return -errno; return 0; } @@ -1991,7 +1993,7 @@ __SALSA_EXPORT_FUNC void snd_pcm_status_get_trigger_htstamp(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr) { - *ptr = obj->trigger_tstamp; + __copy_to_snd_htimestamp(&obj->trigger_tstamp, ptr); } __SALSA_EXPORT_FUNC @@ -2004,13 +2006,13 @@ void snd_pcm_status_get_tstamp(const snd_pcm_status_t *obj, snd_timestamp_t *ptr __SALSA_EXPORT_FUNC void snd_pcm_status_get_htstamp(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr) { - *ptr = obj->tstamp; + __copy_to_snd_htimestamp(&obj->tstamp, ptr); } __SALSA_EXPORT_FUNC void snd_pcm_status_get_audio_htstamp(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr) { - *ptr = obj->audio_tstamp; + __copy_to_snd_htimestamp(&obj->audio_tstamp, ptr); } __SALSA_EXPORT_FUNC @@ -2136,7 +2138,7 @@ int snd_pcm_htimestamp(snd_pcm_t *pcm, snd_pcm_uframes_t *avail, snd_htimestamp_t *tstamp) { *avail = snd_pcm_avail_update(pcm); - *tstamp = pcm->mmap_status->tstamp; + __copy_to_snd_htimestamp(&pcm->mmap_status->tstamp, tstamp); return 0; } diff --git a/src/rawmidi_macros.h b/src/rawmidi_macros.h index c3146cc..f312016 100644 --- a/src/rawmidi_macros.h +++ b/src/rawmidi_macros.h @@ -243,7 +243,7 @@ __SALSA_EXPORT_FUNC void snd_rawmidi_status_get_tstamp(const snd_rawmidi_status_t *obj, snd_htimestamp_t *ptr) { - *ptr = obj->tstamp; + __copy_to_snd_htimestamp(&obj->tstamp, ptr); } __SALSA_EXPORT_FUNC diff --git a/src/recipe.h.in b/src/recipe.h.in index 620745f..e1e0815 100644 --- a/src/recipe.h.in +++ b/src/recipe.h.in @@ -34,6 +34,9 @@ /* Support ASCII value parser for ctl */ #define SALSA_CTL_ASCII_PARSER @SALSA_CTL_ASCII_PARSER@ +/* Use 64bit time */ +#define SALSA_STRUCT_TIME64 @SALSA_STRUCT_TIME64@ + /* Default device path prefix */ #define SALSA_DEVPATH "@DEVPATH@" diff --git a/src/timer_macros.h b/src/timer_macros.h index 1cd37be..5b6a286 100644 --- a/src/timer_macros.h +++ b/src/timer_macros.h @@ -368,7 +368,7 @@ __snd_define_type(snd_timer_status); __SALSA_EXPORT_FUNC snd_htimestamp_t snd_timer_status_get_timestamp(snd_timer_status_t * status) { - return status->tstamp; + return __to_snd_htimestamp(&status->tstamp); } __SALSA_EXPORT_FUNC |