JACK API headers
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

562 lines
16KB

  1. /* -*- mode: c; c-file-style: "bsd"; -*- */
  2. /*
  3. Internal shared data and functions.
  4. If you edit this file, you should carefully consider changing the
  5. JACK_PROTOCOL_VERSION in configure.in.
  6. Copyright (C) 2001-2003 Paul Davis
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or
  10. (at your option) any later version.
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU General Public License for more details.
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. */
  19. #ifndef __jack_internal_h__
  20. #define __jack_internal_h__
  21. #include <stdlib.h>
  22. #include <unistd.h>
  23. #include <limits.h>
  24. #include <dlfcn.h>
  25. #include <pthread.h>
  26. #include <sys/types.h>
  27. #include <sys/time.h>
  28. #ifndef POST_PACKED_STRUCTURE
  29. #ifdef __GNUC__
  30. /* POST_PACKED_STRUCTURE needs to be a macro which
  31. expands into a compiler directive. The directive must
  32. tell the compiler to arrange the preceding structure
  33. declaration so that it is packed on byte-boundaries rather
  34. than use the natural alignment of the processor and/or
  35. compiler.
  36. */
  37. #define POST_PACKED_STRUCTURE __attribute__((__packed__))
  38. #else
  39. /* Add other things here for non-gcc platforms */
  40. #endif
  41. #endif
  42. /* Needed by <sysdeps/time.h> */
  43. extern void jack_error (const char *fmt, ...);
  44. extern void jack_info (const char *fmt, ...);
  45. #include <jack/jack.h>
  46. #include <jack/types.h>
  47. #include <jack/port.h>
  48. #include <jack/transport.h>
  49. #include <jack/session.h>
  50. #include <jack/thread.h>
  51. extern jack_thread_creator_t jack_thread_creator;
  52. typedef enum {
  53. JACK_TIMER_SYSTEM_CLOCK,
  54. JACK_TIMER_CYCLE_COUNTER,
  55. JACK_TIMER_HPET,
  56. } jack_timer_type_t;
  57. void jack_init_time ();
  58. void jack_set_clock_source (jack_timer_type_t);
  59. const char* jack_clock_source_name (jack_timer_type_t);
  60. #include <sysdeps/time.h>
  61. #include <sysdeps/atomicity.h>
  62. #ifdef JACK_USE_MACH_THREADS
  63. #include <sysdeps/mach_port.h>
  64. #endif
  65. #include <jack/messagebuffer.h>
  66. #ifndef PATH_MAX
  67. #ifdef MAXPATHLEN
  68. #define PATH_MAX MAXPATHLEN
  69. #else
  70. #define PATH_MAX 1024
  71. #endif /* MAXPATHLEN */
  72. #endif /* !PATH_MAX */
  73. #ifdef DEBUG_ENABLED
  74. /* grab thread id instead of PID on linux */
  75. #if defined(__gnu_linux__)
  76. #ifdef gettid /* glibc has a version */
  77. #define GETTID() gettid()
  78. #else /* use our own version */
  79. #include <sys/syscall.h>
  80. #define GETTID() syscall(__NR_gettid)
  81. #endif
  82. #else
  83. #define GETTID() getpid()
  84. #endif
  85. #define DEBUG(format,args...) \
  86. MESSAGE("jack:%5d:%" PRIu64 " %s:%s:%d: " format "", GETTID(), jack_get_microseconds(), __FILE__, __FUNCTION__, __LINE__ , ## args)
  87. #else
  88. #if JACK_CPP_VARARGS_BROKEN
  89. #define DEBUG(format...)
  90. #else
  91. #define DEBUG(format,args...)
  92. #endif
  93. #endif
  94. /* Enable preemption checking for Linux Realtime Preemption kernels.
  95. *
  96. * This checks if any RT-safe code section does anything to cause CPU
  97. * preemption. Examples are sleep() or other system calls that block.
  98. * If a problem is detected, the kernel writes a syslog entry, and
  99. * sends SIGUSR2 to the client.
  100. */
  101. #ifdef DO_PREEMPTION_CHECKING
  102. #define CHECK_PREEMPTION(engine, onoff) \
  103. if ((engine)->real_time) gettimeofday (1, (onoff))
  104. #else
  105. #define CHECK_PREEMPTION(engine, onoff)
  106. #endif
  107. #ifndef FALSE
  108. #define FALSE (0)
  109. #endif
  110. #ifndef TRUE
  111. #define TRUE (1)
  112. #endif
  113. typedef struct _jack_engine jack_engine_t;
  114. typedef struct _jack_request jack_request_t;
  115. typedef void * dlhandle;
  116. typedef enum {
  117. TransportCommandNone = 0,
  118. TransportCommandStart = 1,
  119. TransportCommandStop = 2,
  120. } transport_command_t;
  121. typedef struct {
  122. volatile uint32_t guard1;
  123. volatile jack_nframes_t frames;
  124. volatile jack_time_t current_wakeup;
  125. volatile jack_time_t next_wakeup;
  126. volatile float second_order_integrator;
  127. volatile int32_t initialized;
  128. volatile uint32_t guard2;
  129. /* not accessed by clients */
  130. int32_t reset_pending; /* xrun happened, deal with it */
  131. float filter_coefficient; /* set once, never altered */
  132. } POST_PACKED_STRUCTURE jack_frame_timer_t;
  133. /* JACK engine shared memory data structure. */
  134. typedef struct {
  135. jack_transport_state_t transport_state;
  136. volatile transport_command_t transport_cmd;
  137. transport_command_t previous_cmd; /* previous transport_cmd */
  138. jack_position_t current_time; /* position for current cycle */
  139. jack_position_t pending_time; /* position for next cycle */
  140. jack_position_t request_time; /* latest requested position */
  141. jack_unique_t prev_request; /* previous request unique ID */
  142. volatile _Atomic_word seq_number; /* unique ID sequence number */
  143. int8_t new_pos; /* new position this cycle */
  144. int8_t pending_pos; /* new position request pending */
  145. jack_nframes_t pending_frame; /* pending frame number */
  146. int32_t sync_clients; /* number of active_slowsync clients */
  147. int32_t sync_remain; /* number of them with sync_poll */
  148. jack_time_t sync_timeout;
  149. jack_time_t sync_time_left;
  150. jack_frame_timer_t frame_timer;
  151. int32_t internal;
  152. jack_timer_type_t clock_source;
  153. pid_t engine_pid;
  154. jack_nframes_t buffer_size;
  155. int8_t real_time;
  156. int8_t do_mlock;
  157. int8_t do_munlock;
  158. int32_t client_priority;
  159. int32_t max_client_priority;
  160. int32_t has_capabilities;
  161. float cpu_load;
  162. float xrun_delayed_usecs;
  163. float max_delayed_usecs;
  164. uint32_t port_max;
  165. int32_t engine_ok;
  166. jack_port_type_id_t n_port_types;
  167. jack_port_type_info_t port_types[JACK_MAX_PORT_TYPES];
  168. jack_port_shared_t ports[0];
  169. } POST_PACKED_STRUCTURE jack_control_t;
  170. typedef enum {
  171. BufferSizeChange,
  172. SampleRateChange,
  173. AttachPortSegment,
  174. PortConnected,
  175. PortDisconnected,
  176. GraphReordered,
  177. PortRegistered,
  178. PortUnregistered,
  179. XRun,
  180. StartFreewheel,
  181. StopFreewheel,
  182. ClientRegistered,
  183. ClientUnregistered,
  184. SaveSession,
  185. LatencyCallback
  186. } JackEventType;
  187. typedef struct {
  188. JackEventType type;
  189. union {
  190. uint32_t n;
  191. char name[JACK_PORT_NAME_SIZE];
  192. jack_port_id_t port_id;
  193. jack_port_id_t self_id;
  194. } x;
  195. union {
  196. uint32_t n;
  197. jack_port_type_id_t ptid;
  198. jack_port_id_t other_id;
  199. } y;
  200. } POST_PACKED_STRUCTURE jack_event_t;
  201. typedef enum {
  202. ClientInternal, /* connect request just names .so */
  203. ClientDriver, /* code is loaded along with driver */
  204. ClientExternal /* client is in another process */
  205. } ClientType;
  206. typedef enum {
  207. NotTriggered,
  208. Triggered,
  209. Running,
  210. Finished
  211. } jack_client_state_t;
  212. /* JACK client shared memory data structure. */
  213. typedef volatile struct {
  214. volatile jack_client_id_t id; /* w: engine r: engine and client */
  215. volatile jack_client_id_t uid; /* w: engine r: engine and client */
  216. volatile jack_client_state_t state; /* w: engine and client r: engine */
  217. volatile char name[JACK_CLIENT_NAME_SIZE];
  218. volatile char session_command[JACK_PORT_NAME_SIZE];
  219. volatile jack_session_flags_t session_flags;
  220. volatile ClientType type; /* w: engine r: engine and client */
  221. volatile int8_t active; /* w: engine r: engine and client */
  222. volatile int8_t dead; /* r/w: engine */
  223. volatile int8_t timed_out; /* r/w: engine */
  224. volatile int8_t is_timebase; /* w: engine, r: engine and client */
  225. volatile int8_t timebase_new; /* w: engine and client, r: engine */
  226. volatile int8_t is_slowsync; /* w: engine, r: engine and client */
  227. volatile int8_t active_slowsync; /* w: engine, r: engine and client */
  228. volatile int8_t sync_poll; /* w: engine and client, r: engine */
  229. volatile int8_t sync_new; /* w: engine and client, r: engine */
  230. volatile pid_t pid; /* w: client r: engine; client pid */
  231. volatile pid_t pgrp; /* w: client r: engine; client pgrp */
  232. volatile uint64_t signalled_at;
  233. volatile uint64_t awake_at;
  234. volatile uint64_t finished_at;
  235. volatile int32_t last_status; /* w: client, r: engine and client */
  236. /* indicators for whether callbacks have been set for this client.
  237. We do not include ptrs to the callbacks here (or their arguments)
  238. so that we can avoid 32/64 bit pointer size mismatches between
  239. the jack server and a client. The pointers are in the client-
  240. local structure which is part of the libjack compiled for
  241. either 32 bit or 64 bit clients.
  242. */
  243. volatile uint8_t process_cbset;
  244. volatile uint8_t thread_init_cbset;
  245. volatile uint8_t bufsize_cbset;
  246. volatile uint8_t srate_cbset;
  247. volatile uint8_t port_register_cbset;
  248. volatile uint8_t port_connect_cbset;
  249. volatile uint8_t graph_order_cbset;
  250. volatile uint8_t xrun_cbset;
  251. volatile uint8_t sync_cb_cbset;
  252. volatile uint8_t timebase_cb_cbset;
  253. volatile uint8_t freewheel_cb_cbset;
  254. volatile uint8_t client_register_cbset;
  255. volatile uint8_t thread_cb_cbset;
  256. volatile uint8_t session_cbset;
  257. volatile uint8_t latency_cbset;
  258. } POST_PACKED_STRUCTURE jack_client_control_t;
  259. typedef struct {
  260. uint32_t protocol_v; /* protocol version, must go first */
  261. int32_t load;
  262. ClientType type;
  263. jack_options_t options;
  264. jack_client_id_t uuid;
  265. char name[JACK_CLIENT_NAME_SIZE];
  266. char object_path[PATH_MAX+1];
  267. char object_data[1024];
  268. } POST_PACKED_STRUCTURE jack_client_connect_request_t;
  269. typedef struct {
  270. jack_status_t status;
  271. jack_shm_registry_index_t client_shm_index;
  272. jack_shm_registry_index_t engine_shm_index;
  273. char fifo_prefix[PATH_MAX+1];
  274. int32_t realtime;
  275. int32_t realtime_priority;
  276. char name[JACK_CLIENT_NAME_SIZE]; /* unique name, if assigned */
  277. /* these are actually pointers, but they must
  278. be the same size regardless of whether the
  279. server and/or client are 64 bit or 32 bit.
  280. force them to be 64 bit.
  281. */
  282. uint64_t client_control;
  283. uint64_t engine_control;
  284. #ifdef JACK_USE_MACH_THREADS
  285. /* specific resources for server/client real-time thread communication */
  286. int32_t portnum;
  287. #endif
  288. } POST_PACKED_STRUCTURE jack_client_connect_result_t;
  289. typedef struct {
  290. jack_client_id_t client_id;
  291. } POST_PACKED_STRUCTURE jack_client_connect_ack_request_t;
  292. typedef struct {
  293. int8_t status;
  294. } POST_PACKED_STRUCTURE jack_client_connect_ack_result_t;
  295. typedef enum {
  296. RegisterPort = 1,
  297. UnRegisterPort = 2,
  298. ConnectPorts = 3,
  299. DisconnectPorts = 4,
  300. SetTimeBaseClient = 5,
  301. ActivateClient = 6,
  302. DeactivateClient = 7,
  303. DisconnectPort = 8,
  304. SetClientCapabilities = 9,
  305. GetPortConnections = 10,
  306. GetPortNConnections = 11,
  307. ResetTimeBaseClient = 12,
  308. SetSyncClient = 13,
  309. ResetSyncClient = 14,
  310. SetSyncTimeout = 15,
  311. SetBufferSize = 16,
  312. FreeWheel = 17,
  313. StopFreeWheel = 18,
  314. IntClientHandle = 19,
  315. IntClientLoad = 20,
  316. IntClientName = 21,
  317. IntClientUnload = 22,
  318. RecomputeTotalLatencies = 23,
  319. RecomputeTotalLatency = 24,
  320. SessionNotify = 25,
  321. GetClientByUUID = 26,
  322. ReserveName = 30,
  323. SessionReply = 31,
  324. SessionHasCallback = 32
  325. } RequestType;
  326. struct _jack_request {
  327. //RequestType type;
  328. uint32_t type;
  329. union {
  330. struct {
  331. char name[JACK_PORT_NAME_SIZE];
  332. char type[JACK_PORT_TYPE_SIZE];
  333. uint32_t flags;
  334. jack_shmsize_t buffer_size;
  335. jack_port_id_t port_id;
  336. jack_client_id_t client_id;
  337. } POST_PACKED_STRUCTURE port_info;
  338. struct {
  339. char source_port[JACK_PORT_NAME_SIZE];
  340. char destination_port[JACK_PORT_NAME_SIZE];
  341. } POST_PACKED_STRUCTURE connect;
  342. struct {
  343. char path[JACK_PORT_NAME_SIZE];
  344. jack_session_event_type_t type;
  345. char target[JACK_CLIENT_NAME_SIZE];
  346. } POST_PACKED_STRUCTURE session;
  347. struct {
  348. int32_t nports;
  349. const char **ports; /* this is only exposed to internal clients, so there
  350. is no 64/32 issue. external clients read the ports
  351. one by one from the server, and allocate their
  352. own "ports" array in their own address space.
  353. we are lucky, because this is part of a union
  354. whose other components are bigger than this one.
  355. otherwise it would change structure size when
  356. comparing the 64 and 32 bit versions.
  357. */
  358. } POST_PACKED_STRUCTURE port_connections;
  359. struct {
  360. jack_client_id_t client_id;
  361. int32_t conditional;
  362. } POST_PACKED_STRUCTURE timebase;
  363. struct {
  364. char name[JACK_CLIENT_NAME_SIZE];
  365. jack_client_id_t uuid;
  366. } POST_PACKED_STRUCTURE reservename;
  367. struct {
  368. //jack_options_t options;
  369. uint32_t options;
  370. jack_client_id_t id;
  371. char name[JACK_CLIENT_NAME_SIZE];
  372. char path[PATH_MAX+1];
  373. char init[JACK_LOAD_INIT_LIMIT];
  374. } POST_PACKED_STRUCTURE intclient;
  375. jack_client_id_t client_id;
  376. jack_nframes_t nframes;
  377. jack_time_t timeout;
  378. pid_t cap_pid;
  379. char name[JACK_CLIENT_NAME_SIZE];
  380. } POST_PACKED_STRUCTURE x;
  381. int32_t status;
  382. } POST_PACKED_STRUCTURE;
  383. /* Per-client structure allocated in the server's address space.
  384. * It's here because its not part of the engine structure.
  385. */
  386. typedef struct _jack_client_internal {
  387. jack_client_control_t *control;
  388. int request_fd;
  389. int event_fd;
  390. int subgraph_start_fd;
  391. int subgraph_wait_fd;
  392. JSList *ports; /* protected by engine->client_lock */
  393. JSList *truefeeds; /* protected by engine->client_lock */
  394. JSList *sortfeeds; /* protected by engine->client_lock */
  395. int fedcount;
  396. int tfedcount;
  397. jack_shm_info_t control_shm;
  398. unsigned long execution_order;
  399. struct _jack_client_internal *next_client; /* not a linked list! */
  400. dlhandle handle;
  401. int (*initialize)(jack_client_t*, const char*); /* int. clients only */
  402. void (*finish)(void *); /* internal clients only */
  403. int error;
  404. int session_reply_pending;
  405. #ifdef JACK_USE_MACH_THREADS
  406. /* specific resources for server/client real-time thread communication */
  407. mach_port_t serverport;
  408. trivial_message message;
  409. int running;
  410. int portnum;
  411. #endif /* JACK_USE_MACH_THREADS */
  412. jack_client_t *private_client;
  413. } jack_client_internal_t;
  414. typedef struct _jack_thread_arg {
  415. jack_client_t* client;
  416. void* (*work_function)(void*);
  417. int priority;
  418. int realtime;
  419. void* arg;
  420. pid_t cap_pid;
  421. } jack_thread_arg_t;
  422. extern int jack_client_handle_port_connection (jack_client_t *client,
  423. jack_event_t *event);
  424. extern jack_client_t *jack_driver_client_new (jack_engine_t *,
  425. const char *client_name);
  426. extern jack_client_t *jack_client_alloc_internal (jack_client_control_t*,
  427. jack_engine_t*);
  428. /* internal clients call this. it's defined in jack/engine.c */
  429. void handle_internal_client_request (jack_control_t*, jack_request_t*);
  430. extern char *jack_tmpdir;
  431. extern char *jack_user_dir (void);
  432. extern char *jack_server_dir (const char *server_name, char *server_dir);
  433. extern void *jack_zero_filled_buffer;
  434. extern jack_port_functions_t jack_builtin_audio_functions;
  435. extern jack_port_type_info_t jack_builtin_port_types[];
  436. extern void jack_client_fix_port_buffers (jack_client_t *client);
  437. extern void jack_transport_copy_position (jack_position_t *from,
  438. jack_position_t *to);
  439. extern void jack_call_sync_client (jack_client_t *client);
  440. extern void jack_call_timebase_master (jack_client_t *client);
  441. extern char *jack_default_server_name (void);
  442. void silent_jack_error_callback (const char *desc);
  443. /* needed for port management */
  444. extern jack_port_t *jack_port_by_id_int (const jack_client_t *client,
  445. jack_port_id_t id, int* free);
  446. extern jack_port_t *jack_port_by_name_int (jack_client_t *client,
  447. const char *port_name);
  448. extern int jack_port_name_equals (jack_port_shared_t* port, const char* target);
  449. /** Get the size (in bytes) of the data structure used to store
  450. * MIDI events internally.
  451. */
  452. extern size_t jack_midi_internal_event_size ();
  453. extern int jack_client_handle_latency_callback (jack_client_t *client, jack_event_t *event, int is_driver);
  454. #ifdef __GNUC__
  455. # define likely(x) __builtin_expect((x),1)
  456. # define unlikely(x) __builtin_expect((x),0)
  457. #else
  458. # define likely(x) (x)
  459. # define unlikely(x) (x)
  460. #endif
  461. #ifdef VALGRIND_CLEAN
  462. #include <string.h>
  463. #define VALGRIND_MEMSET(ptr,val,size) memset ((ptr),(val),(size))
  464. #else
  465. #define VALGRIND_MEMSET(ptr,val,size)
  466. #endif
  467. #endif /* __jack_internal_h__ */