• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2  * Use of this source code is governed by a BSD-style license that can be
3  * found in the LICENSE file.
4  */
5 
6 #ifndef _GNU_SOURCE
7 #define _GNU_SOURCE /* for ppoll and asprintf*/
8 #endif
9 
10 #include <pthread.h>
11 #include <poll.h>
12 #include <stdbool.h>
13 #include <stdio.h>
14 #include <sys/param.h>
15 #include <syslog.h>
16 
17 #include "audio_thread_log.h"
18 #include "cras_audio_thread_monitor.h"
19 #include "cras_config.h"
20 #include "cras_device_monitor.h"
21 #include "cras_fmt_conv.h"
22 #include "cras_iodev.h"
23 #include "cras_rstream.h"
24 #include "cras_server_metrics.h"
25 #include "cras_system_state.h"
26 #include "cras_types.h"
27 #include "cras_util.h"
28 #include "dev_stream.h"
29 #include "audio_thread.h"
30 #include "utlist.h"
31 
32 #define MIN_PROCESS_TIME_US 500 /* 0.5ms - min amount of time to mix/src. */
33 #define SLEEP_FUZZ_FRAMES 10 /* # to consider "close enough" to sleep frames. */
34 #define MIN_READ_WAIT_US 2000 /* 2ms */
35 /*
36  * # to check whether a busyloop event happens
37  */
38 #define MAX_CONTINUOUS_ZERO_SLEEP_COUNT 2
39 
40 /*
41  * If the number of continuous zero sleep is equal to this limit, the value
42  * will be recorded immediately. It can ensure all busyloop will be recorded
43  * even if the busyloop does not stop.
44  */
45 #define MAX_CONTINUOUS_ZERO_SLEEP_METRIC_LIMIT 1000
46 
47 /* Messages that can be sent from the main context to the audio thread. */
48 enum AUDIO_THREAD_COMMAND {
49 	AUDIO_THREAD_ADD_OPEN_DEV,
50 	AUDIO_THREAD_RM_OPEN_DEV,
51 	AUDIO_THREAD_IS_DEV_OPEN,
52 	AUDIO_THREAD_ADD_STREAM,
53 	AUDIO_THREAD_DISCONNECT_STREAM,
54 	AUDIO_THREAD_STOP,
55 	AUDIO_THREAD_DUMP_THREAD_INFO,
56 	AUDIO_THREAD_DRAIN_STREAM,
57 	AUDIO_THREAD_CONFIG_GLOBAL_REMIX,
58 	AUDIO_THREAD_DEV_START_RAMP,
59 	AUDIO_THREAD_REMOVE_CALLBACK,
60 	AUDIO_THREAD_AEC_DUMP,
61 };
62 
63 struct audio_thread_msg {
64 	size_t length;
65 	enum AUDIO_THREAD_COMMAND id;
66 };
67 
68 struct audio_thread_config_global_remix {
69 	struct audio_thread_msg header;
70 	struct cras_fmt_conv *fmt_conv;
71 };
72 
73 struct audio_thread_open_device_msg {
74 	struct audio_thread_msg header;
75 	struct cras_iodev *dev;
76 };
77 
78 struct audio_thread_rm_device_msg {
79 	struct audio_thread_msg header;
80 	enum CRAS_STREAM_DIRECTION dir;
81 	unsigned dev_idx;
82 };
83 
84 struct audio_thread_rm_callback_msg {
85 	struct audio_thread_msg header;
86 	int fd;
87 };
88 
89 struct audio_thread_add_rm_stream_msg {
90 	struct audio_thread_msg header;
91 	struct cras_rstream *stream;
92 	struct cras_iodev **devs;
93 	unsigned int num_devs;
94 };
95 
96 struct audio_thread_dump_debug_info_msg {
97 	struct audio_thread_msg header;
98 	struct audio_debug_info *info;
99 };
100 
101 struct audio_thread_dev_start_ramp_msg {
102 	struct audio_thread_msg header;
103 	unsigned int dev_idx;
104 	enum CRAS_IODEV_RAMP_REQUEST request;
105 };
106 
107 struct audio_thread_aec_dump_msg {
108 	struct audio_thread_msg header;
109 	cras_stream_id_t stream_id;
110 	unsigned int start; /* */
111 	int fd;
112 };
113 
114 /* Audio thread logging. If atlog is successfully created from cras_shm_setup,
115  * then the fds should have valid value. Or audio thread will fallback to use
116  * calloc to create atlog and leave the fds as -1.
117  */
118 struct audio_thread_event_log *atlog;
119 char *atlog_name;
120 int atlog_rw_shm_fd;
121 int atlog_ro_shm_fd;
122 
123 static struct iodev_callback_list *iodev_callbacks;
124 
125 struct iodev_callback_list {
126 	int fd;
127 	int events;
128 	enum AUDIO_THREAD_EVENTS_CB_TRIGGER trigger;
129 	thread_callback cb;
130 	void *cb_data;
131 	struct pollfd *pollfd;
132 	struct iodev_callback_list *prev, *next;
133 };
134 
audio_thread_add_events_callback(int fd,thread_callback cb,void * data,int events)135 void audio_thread_add_events_callback(int fd, thread_callback cb, void *data,
136 				      int events)
137 {
138 	struct iodev_callback_list *iodev_cb;
139 
140 	/* Don't add iodev_cb twice */
141 	DL_FOREACH (iodev_callbacks, iodev_cb)
142 		if (iodev_cb->fd == fd && iodev_cb->cb_data == data)
143 			return;
144 
145 	iodev_cb = (struct iodev_callback_list *)calloc(1, sizeof(*iodev_cb));
146 	iodev_cb->fd = fd;
147 	iodev_cb->cb = cb;
148 	iodev_cb->cb_data = data;
149 	iodev_cb->trigger = TRIGGER_POLL;
150 	iodev_cb->events = events;
151 
152 	DL_APPEND(iodev_callbacks, iodev_cb);
153 }
154 
audio_thread_rm_callback(int fd)155 void audio_thread_rm_callback(int fd)
156 {
157 	struct iodev_callback_list *iodev_cb;
158 
159 	DL_FOREACH (iodev_callbacks, iodev_cb) {
160 		if (iodev_cb->fd == fd) {
161 			DL_DELETE(iodev_callbacks, iodev_cb);
162 			free(iodev_cb);
163 			return;
164 		}
165 	}
166 }
167 
audio_thread_config_events_callback(int fd,enum AUDIO_THREAD_EVENTS_CB_TRIGGER trigger)168 void audio_thread_config_events_callback(
169 	int fd, enum AUDIO_THREAD_EVENTS_CB_TRIGGER trigger)
170 {
171 	struct iodev_callback_list *iodev_cb;
172 
173 	DL_FOREACH (iodev_callbacks, iodev_cb) {
174 		if (iodev_cb->fd == fd) {
175 			iodev_cb->trigger = trigger;
176 			return;
177 		}
178 	}
179 }
180 
181 /* Sends a response (error code) from the audio thread to the main thread.
182  * Indicates that the last message sent to the audio thread has been handled
183  * with an error code of rc.
184  * Args:
185  *    thread - thread responding to command.
186  *    rc - Result code to send back to the main thread.
187  * Returns:
188  *    The number of bytes written to the main thread.
189  */
audio_thread_send_response(struct audio_thread * thread,int rc)190 static int audio_thread_send_response(struct audio_thread *thread, int rc)
191 {
192 	return write(thread->to_main_fds[1], &rc, sizeof(rc));
193 }
194 
195 /* Reads from a file descriptor until all bytes are read.
196  *
197  * Args:
198  *    fd - file descriptor to read
199  *    buf - the buffer to be written.
200  *    count - the number of bytes to read from fd
201  * Returns:
202  *    |count| on success, negative error code on failure.
203  */
read_until_finished(int fd,void * buf,size_t count)204 static int read_until_finished(int fd, void *buf, size_t count)
205 {
206 	int nread, count_left = count;
207 
208 	while (count_left > 0) {
209 		nread = read(fd, (uint8_t *)buf + count - count_left,
210 			     count_left);
211 		if (nread < 0) {
212 			if (errno == EINTR)
213 				continue;
214 			else
215 				return nread;
216 		} else if (nread == 0) {
217 			syslog(LOG_ERR, "Pipe has been closed.");
218 			return -EPIPE;
219 		}
220 		count_left -= nread;
221 	}
222 	return count;
223 }
224 
225 /* Reads a command from the main thread.  Called from the playback/capture
226  * thread.  This will read the next available command from the main thread and
227  * put it in buf.
228  * Args:
229  *    thread - thread reading the command.
230  *    buf - Message is stored here on return.
231  *    max_len - maximum length of message to put into buf.
232  * Returns:
233  *    0 on success, negative error code on failure.
234  */
audio_thread_read_command(struct audio_thread * thread,uint8_t * buf,size_t max_len)235 static int audio_thread_read_command(struct audio_thread *thread, uint8_t *buf,
236 				     size_t max_len)
237 {
238 	int to_read, nread, rc;
239 	struct audio_thread_msg *msg = (struct audio_thread_msg *)buf;
240 
241 	/* Get the length of the message first */
242 	nread = read_until_finished(thread->to_thread_fds[0], buf,
243 				    sizeof(msg->length));
244 	if (nread < 0)
245 		return nread;
246 
247 	if (msg->length > max_len)
248 		return -ENOMEM;
249 
250 	to_read = msg->length - sizeof(msg->length);
251 	rc = read_until_finished(thread->to_thread_fds[0],
252 				 &buf[0] + sizeof(msg->length), to_read);
253 	if (rc < 0)
254 		return rc;
255 	return 0;
256 }
257 
258 /* Builds an initial buffer to avoid an underrun. Adds min_level of latency. */
fill_odevs_zeros_min_level(struct cras_iodev * odev)259 static void fill_odevs_zeros_min_level(struct cras_iodev *odev)
260 {
261 	cras_iodev_fill_odev_zeros(odev, odev->min_buffer_level);
262 }
263 
264 /* Handles messages from main thread to add a new active device. */
thread_add_open_dev(struct audio_thread * thread,struct cras_iodev * iodev)265 static int thread_add_open_dev(struct audio_thread *thread,
266 			       struct cras_iodev *iodev)
267 {
268 	struct open_dev *adev;
269 
270 	DL_SEARCH_SCALAR(thread->open_devs[iodev->direction], adev, dev, iodev);
271 	if (adev)
272 		return -EEXIST;
273 
274 	adev = (struct open_dev *)calloc(1, sizeof(*adev));
275 	adev->dev = iodev;
276 
277 	/*
278 	 * Start output devices by padding the output. This avoids a burst of
279 	 * audio callbacks when the stream starts
280 	 */
281 	if (iodev->direction == CRAS_STREAM_OUTPUT)
282 		fill_odevs_zeros_min_level(iodev);
283 
284 	ATLOG(atlog, AUDIO_THREAD_DEV_ADDED, iodev->info.idx, 0, 0);
285 
286 	DL_APPEND(thread->open_devs[iodev->direction], adev);
287 
288 	return 0;
289 }
290 
291 /* Handles messages from the main thread to remove an active device. */
thread_rm_open_dev(struct audio_thread * thread,enum CRAS_STREAM_DIRECTION dir,unsigned int dev_idx)292 static int thread_rm_open_dev(struct audio_thread *thread,
293 			      enum CRAS_STREAM_DIRECTION dir,
294 			      unsigned int dev_idx)
295 {
296 	struct open_dev *adev =
297 		dev_io_find_open_dev(thread->open_devs[dir], dev_idx);
298 	if (!adev)
299 		return -EINVAL;
300 
301 	dev_io_rm_open_dev(&thread->open_devs[dir], adev);
302 	return 0;
303 }
304 
305 /*
306  * Handles message from the main thread to check if an iodev is in the
307  * open dev list.
308  */
thread_is_dev_open(struct audio_thread * thread,struct cras_iodev * iodev)309 static int thread_is_dev_open(struct audio_thread *thread,
310 			      struct cras_iodev *iodev)
311 {
312 	struct open_dev *adev = dev_io_find_open_dev(
313 		thread->open_devs[iodev->direction], iodev->info.idx);
314 	return !!adev;
315 }
316 
317 /*
318  * Handles messages from the main thread to start ramping on a device.
319  * Start ramping in audio thread and set mute/unmute
320  * state on device. This should only be done when
321  * device is running with valid streams.
322  *
323  * 1. Mute -> Unmute: Set device unmute state after
324  *                    ramping is started.
325  * 2. Unmute -> Mute: Set device mute state after
326  *                    ramping is done.
327  *
328  * The above transition will be handled by cras_iodev_start_ramp.
329  */
thread_dev_start_ramp(struct audio_thread * thread,unsigned int dev_idx,enum CRAS_IODEV_RAMP_REQUEST request)330 static int thread_dev_start_ramp(struct audio_thread *thread,
331 				 unsigned int dev_idx,
332 				 enum CRAS_IODEV_RAMP_REQUEST request)
333 {
334 	/* Do nothing if device wasn't already in the active dev list. */
335 	struct cras_iodev *iodev;
336 	struct open_dev *adev = dev_io_find_open_dev(
337 		thread->open_devs[CRAS_STREAM_OUTPUT], dev_idx);
338 	if (!adev)
339 		return -EINVAL;
340 	iodev = adev->dev;
341 
342 	/*
343 	 * Checks if a device should start ramping for mute/unmute change.
344 	 * Device must meet all the conditions:
345 	 *
346 	 * - Device has ramp support.
347 	 * - Device is in normal run state, that is, it must be running with valid
348 	 *   streams.
349 	 * - Device volume, which considers both system volume and adjusted active
350 	 *   node volume, is not zero. If device volume is zero, all the samples are
351 	 *   suppressed to zero and there is no need to ramp.
352 	 */
353 	if (iodev->ramp &&
354 	    cras_iodev_state(iodev) == CRAS_IODEV_STATE_NORMAL_RUN &&
355 	    !cras_iodev_is_zero_volume(iodev))
356 		return cras_iodev_start_ramp(iodev, request);
357 	else
358 		return cras_device_monitor_set_device_mute_state(
359 			iodev->info.idx);
360 }
361 
362 /* Return non-zero if the stream is attached to any device. */
thread_find_stream(struct audio_thread * thread,struct cras_rstream * rstream)363 static int thread_find_stream(struct audio_thread *thread,
364 			      struct cras_rstream *rstream)
365 {
366 	struct open_dev *open_dev;
367 	struct dev_stream *s;
368 
369 	DL_FOREACH (thread->open_devs[rstream->direction], open_dev) {
370 		DL_FOREACH (open_dev->dev->streams, s) {
371 			if (s->stream == rstream)
372 				return 1;
373 		}
374 	}
375 	return 0;
376 }
377 
378 /* Handles the disconnect_stream message from the main thread. */
thread_disconnect_stream(struct audio_thread * thread,struct cras_rstream * stream,struct cras_iodev * dev)379 static int thread_disconnect_stream(struct audio_thread *thread,
380 				    struct cras_rstream *stream,
381 				    struct cras_iodev *dev)
382 {
383 	int rc;
384 
385 	if (!thread_find_stream(thread, stream))
386 		return 0;
387 
388 	rc = dev_io_remove_stream(&thread->open_devs[stream->direction], stream,
389 				  dev);
390 
391 	return rc;
392 }
393 
394 /* Initiates draining of a stream or returns the status of a draining stream.
395  * If the stream has completed draining the thread forfeits ownership and must
396  * never reference it again.  Returns the number of milliseconds it will take to
397  * finish draining, a minimum of one ms if any samples remain.
398  */
thread_drain_stream_ms_remaining(struct audio_thread * thread,struct cras_rstream * rstream)399 static int thread_drain_stream_ms_remaining(struct audio_thread *thread,
400 					    struct cras_rstream *rstream)
401 {
402 	int fr_in_buff;
403 	struct cras_audio_shm *shm;
404 
405 	if (rstream->direction != CRAS_STREAM_OUTPUT)
406 		return 0;
407 
408 	shm = cras_rstream_shm(rstream);
409 	fr_in_buff = cras_shm_get_frames(shm);
410 
411 	if (fr_in_buff <= 0)
412 		return 0;
413 
414 	cras_rstream_set_is_draining(rstream, 1);
415 
416 	return 1 + cras_frames_to_ms(fr_in_buff, rstream->format.frame_rate);
417 }
418 
419 /* Handles a request to begin draining and return the amount of time left to
420  * draing a stream.
421  */
thread_drain_stream(struct audio_thread * thread,struct cras_rstream * rstream)422 static int thread_drain_stream(struct audio_thread *thread,
423 			       struct cras_rstream *rstream)
424 {
425 	int ms_left;
426 
427 	if (!thread_find_stream(thread, rstream))
428 		return 0;
429 
430 	ms_left = thread_drain_stream_ms_remaining(thread, rstream);
431 	if (ms_left == 0)
432 		dev_io_remove_stream(&thread->open_devs[rstream->direction],
433 				     rstream, NULL);
434 
435 	return ms_left;
436 }
437 
438 /* Handles the add_stream message from the main thread. */
thread_add_stream(struct audio_thread * thread,struct cras_rstream * stream,struct cras_iodev ** iodevs,unsigned int num_iodevs)439 static int thread_add_stream(struct audio_thread *thread,
440 			     struct cras_rstream *stream,
441 			     struct cras_iodev **iodevs,
442 			     unsigned int num_iodevs)
443 {
444 	int rc;
445 
446 	rc = dev_io_append_stream(&thread->open_devs[CRAS_STREAM_OUTPUT],
447 				  &thread->open_devs[CRAS_STREAM_INPUT], stream,
448 				  iodevs, num_iodevs);
449 	if (rc < 0)
450 		return rc;
451 
452 	return 0;
453 }
454 
455 /* Starts or stops aec dump task. */
thread_set_aec_dump(struct audio_thread * thread,cras_stream_id_t stream_id,unsigned int start,int fd)456 static int thread_set_aec_dump(struct audio_thread *thread,
457 			       cras_stream_id_t stream_id, unsigned int start,
458 			       int fd)
459 {
460 	struct open_dev *idev_list = thread->open_devs[CRAS_STREAM_INPUT];
461 	struct open_dev *adev;
462 	struct dev_stream *stream;
463 
464 	DL_FOREACH (idev_list, adev) {
465 		if (!cras_iodev_is_open(adev->dev))
466 			continue;
467 
468 		DL_FOREACH (adev->dev->streams, stream) {
469 			if ((stream->stream->apm_list == NULL) ||
470 			    (stream->stream->stream_id != stream_id))
471 				continue;
472 
473 			cras_apm_list_set_aec_dump(stream->stream->apm_list,
474 						   adev->dev, start, fd);
475 		}
476 	}
477 	return 0;
478 }
479 
480 /* Stop the playback thread */
terminate_pb_thread()481 static void terminate_pb_thread()
482 {
483 	pthread_exit(0);
484 }
485 
append_dev_dump_info(struct audio_dev_debug_info * di,struct open_dev * adev)486 static void append_dev_dump_info(struct audio_dev_debug_info *di,
487 				 struct open_dev *adev)
488 {
489 	struct cras_audio_format *fmt = adev->dev->format;
490 	struct timespec now, time_since;
491 	strncpy(di->dev_name, adev->dev->info.name, sizeof(di->dev_name));
492 	di->buffer_size = adev->dev->buffer_size;
493 	di->min_buffer_level = adev->dev->min_buffer_level;
494 	di->min_cb_level = adev->dev->min_cb_level;
495 	di->max_cb_level = adev->dev->max_cb_level;
496 	di->direction = adev->dev->direction;
497 	di->num_underruns = cras_iodev_get_num_underruns(adev->dev);
498 	di->num_severe_underruns =
499 		cras_iodev_get_num_severe_underruns(adev->dev);
500 	di->highest_hw_level = adev->dev->highest_hw_level;
501 	di->software_gain_scaler = (adev->dev->direction == CRAS_STREAM_INPUT) ?
502 					   adev->dev->software_gain_scaler :
503 					   0.0f;
504 
505 	clock_gettime(CLOCK_MONOTONIC_RAW, &now);
506 	subtract_timespecs(&now, &adev->dev->open_ts, &time_since);
507 	di->runtime_sec = time_since.tv_sec;
508 	di->runtime_nsec = time_since.tv_nsec;
509 	di->longest_wake_sec = adev->longest_wake.tv_sec;
510 	di->longest_wake_nsec = adev->longest_wake.tv_nsec;
511 
512 	if (fmt) {
513 		di->frame_rate = fmt->frame_rate;
514 		di->num_channels = fmt->num_channels;
515 		di->est_rate_ratio = cras_iodev_get_est_rate_ratio(adev->dev);
516 	} else {
517 		di->frame_rate = 0;
518 		di->num_channels = 0;
519 		di->est_rate_ratio = 0;
520 	}
521 }
522 
523 /* Put stream info for the given stream into the info struct. */
append_stream_dump_info(struct audio_debug_info * info,struct dev_stream * stream,unsigned int dev_idx,int index)524 static void append_stream_dump_info(struct audio_debug_info *info,
525 				    struct dev_stream *stream,
526 				    unsigned int dev_idx, int index)
527 {
528 	struct audio_stream_debug_info *si;
529 	struct timespec now, time_since;
530 
531 	si = &info->streams[index];
532 
533 	si->stream_id = stream->stream->stream_id;
534 	si->dev_idx = dev_idx;
535 	si->direction = stream->stream->direction;
536 	si->stream_type = stream->stream->stream_type;
537 	si->client_type = stream->stream->client_type;
538 	si->buffer_frames = stream->stream->buffer_frames;
539 	si->cb_threshold = stream->stream->cb_threshold;
540 	si->frame_rate = stream->stream->format.frame_rate;
541 	si->num_channels = stream->stream->format.num_channels;
542 	memcpy(si->channel_layout, stream->stream->format.channel_layout,
543 	       sizeof(si->channel_layout));
544 	si->longest_fetch_sec = stream->stream->longest_fetch_interval.tv_sec;
545 	si->longest_fetch_nsec = stream->stream->longest_fetch_interval.tv_nsec;
546 	si->num_overruns = cras_shm_num_overruns(stream->stream->shm);
547 	si->effects = cras_apm_list_get_effects(stream->stream->apm_list);
548 	si->pinned_dev_idx = stream->stream->pinned_dev_idx;
549 	si->is_pinned = stream->stream->is_pinned;
550 	si->num_missed_cb = stream->stream->num_missed_cb;
551 	si->stream_volume = cras_rstream_get_volume_scaler(stream->stream);
552 
553 	clock_gettime(CLOCK_MONOTONIC_RAW, &now);
554 	subtract_timespecs(&now, &stream->stream->start_ts, &time_since);
555 	si->runtime_sec = time_since.tv_sec;
556 	si->runtime_nsec = time_since.tv_nsec;
557 }
558 
559 /* Handle a message sent from main thread to the audio thread.
560  * Returns:
561  *    Error code when reading or sending message fails.
562  */
handle_audio_thread_message(struct audio_thread * thread)563 static int handle_audio_thread_message(struct audio_thread *thread)
564 {
565 	uint8_t buf[256];
566 	struct audio_thread_msg *msg = (struct audio_thread_msg *)buf;
567 	int ret = 0;
568 	int err;
569 
570 	err = audio_thread_read_command(thread, buf, 256);
571 	if (err < 0)
572 		return err;
573 
574 	ATLOG(atlog, AUDIO_THREAD_PB_MSG, msg->id, 0, 0);
575 
576 	switch (msg->id) {
577 	case AUDIO_THREAD_ADD_STREAM: {
578 		struct audio_thread_add_rm_stream_msg *amsg;
579 		amsg = (struct audio_thread_add_rm_stream_msg *)msg;
580 		ATLOG(atlog, AUDIO_THREAD_WRITE_STREAMS_WAIT,
581 		      amsg->stream->stream_id, 0, 0);
582 		ret = thread_add_stream(thread, amsg->stream, amsg->devs,
583 					amsg->num_devs);
584 		break;
585 	}
586 	case AUDIO_THREAD_DISCONNECT_STREAM: {
587 		struct audio_thread_add_rm_stream_msg *rmsg;
588 
589 		rmsg = (struct audio_thread_add_rm_stream_msg *)msg;
590 
591 		ret = thread_disconnect_stream(thread, rmsg->stream,
592 					       rmsg->devs[0]);
593 		break;
594 	}
595 	case AUDIO_THREAD_ADD_OPEN_DEV: {
596 		struct audio_thread_open_device_msg *rmsg;
597 
598 		rmsg = (struct audio_thread_open_device_msg *)msg;
599 		ret = thread_add_open_dev(thread, rmsg->dev);
600 		break;
601 	}
602 	case AUDIO_THREAD_RM_OPEN_DEV: {
603 		struct audio_thread_rm_device_msg *rmsg;
604 
605 		rmsg = (struct audio_thread_rm_device_msg *)msg;
606 		ret = thread_rm_open_dev(thread, rmsg->dir, rmsg->dev_idx);
607 		break;
608 	}
609 	case AUDIO_THREAD_IS_DEV_OPEN: {
610 		struct audio_thread_open_device_msg *rmsg;
611 
612 		rmsg = (struct audio_thread_open_device_msg *)msg;
613 		ret = thread_is_dev_open(thread, rmsg->dev);
614 		break;
615 	}
616 	case AUDIO_THREAD_STOP:
617 		ret = 0;
618 		err = audio_thread_send_response(thread, ret);
619 		if (err < 0)
620 			return err;
621 		terminate_pb_thread();
622 		break;
623 	case AUDIO_THREAD_DUMP_THREAD_INFO: {
624 		struct dev_stream *curr;
625 		struct open_dev *adev;
626 		struct audio_thread_dump_debug_info_msg *dmsg;
627 		struct audio_debug_info *info;
628 		unsigned int num_streams = 0;
629 		unsigned int num_devs = 0;
630 
631 		ret = 0;
632 		dmsg = (struct audio_thread_dump_debug_info_msg *)msg;
633 		info = dmsg->info;
634 
635 		/* Go through all open devices. */
636 		DL_FOREACH (thread->open_devs[CRAS_STREAM_OUTPUT], adev) {
637 			append_dev_dump_info(&info->devs[num_devs], adev);
638 			if (++num_devs == MAX_DEBUG_DEVS)
639 				break;
640 			DL_FOREACH (adev->dev->streams, curr) {
641 				if (num_streams == MAX_DEBUG_STREAMS)
642 					break;
643 				append_stream_dump_info(info, curr,
644 							adev->dev->info.idx,
645 							num_streams++);
646 			}
647 		}
648 		DL_FOREACH (thread->open_devs[CRAS_STREAM_INPUT], adev) {
649 			if (num_devs == MAX_DEBUG_DEVS)
650 				break;
651 			append_dev_dump_info(&info->devs[num_devs], adev);
652 			DL_FOREACH (adev->dev->streams, curr) {
653 				if (num_streams == MAX_DEBUG_STREAMS)
654 					break;
655 				append_stream_dump_info(info, curr,
656 							adev->dev->info.idx,
657 							num_streams++);
658 			}
659 			++num_devs;
660 		}
661 		info->num_devs = num_devs;
662 
663 		info->num_streams = num_streams;
664 
665 		memcpy(&info->log, atlog, sizeof(info->log));
666 		break;
667 	}
668 	case AUDIO_THREAD_DRAIN_STREAM: {
669 		struct audio_thread_add_rm_stream_msg *rmsg;
670 
671 		rmsg = (struct audio_thread_add_rm_stream_msg *)msg;
672 		ret = thread_drain_stream(thread, rmsg->stream);
673 		break;
674 	}
675 	case AUDIO_THREAD_REMOVE_CALLBACK: {
676 		struct audio_thread_rm_callback_msg *rmsg;
677 
678 		rmsg = (struct audio_thread_rm_callback_msg *)msg;
679 		audio_thread_rm_callback(rmsg->fd);
680 		break;
681 	}
682 	case AUDIO_THREAD_CONFIG_GLOBAL_REMIX: {
683 		struct audio_thread_config_global_remix *rmsg;
684 		void *rsp;
685 
686 		/* Respond the pointer to the old remix converter, so it can be
687 		 * freed later in main thread. */
688 		rsp = (void *)thread->remix_converter;
689 
690 		rmsg = (struct audio_thread_config_global_remix *)msg;
691 		thread->remix_converter = rmsg->fmt_conv;
692 
693 		return write(thread->to_main_fds[1], &rsp, sizeof(rsp));
694 	}
695 	case AUDIO_THREAD_DEV_START_RAMP: {
696 		struct audio_thread_dev_start_ramp_msg *rmsg;
697 
698 		rmsg = (struct audio_thread_dev_start_ramp_msg *)msg;
699 		ret = thread_dev_start_ramp(thread, rmsg->dev_idx,
700 					    rmsg->request);
701 		break;
702 	}
703 	case AUDIO_THREAD_AEC_DUMP: {
704 		struct audio_thread_aec_dump_msg *rmsg;
705 		rmsg = (struct audio_thread_aec_dump_msg *)msg;
706 		ret = thread_set_aec_dump(thread, rmsg->stream_id, rmsg->start,
707 					  rmsg->fd);
708 		break;
709 	}
710 	default:
711 		ret = -EINVAL;
712 		break;
713 	}
714 
715 	err = audio_thread_send_response(thread, ret);
716 	if (err < 0)
717 		return err;
718 	return 0;
719 }
720 
721 /* Returns the number of active streams plus the number of active devices. */
fill_next_sleep_interval(struct audio_thread * thread,struct timespec * ts)722 static int fill_next_sleep_interval(struct audio_thread *thread,
723 				    struct timespec *ts)
724 {
725 	struct timespec min_ts;
726 	struct timespec now;
727 	int ret;
728 
729 	ts->tv_sec = 0;
730 	ts->tv_nsec = 0;
731 	/* Limit the sleep time to 20 seconds. */
732 	min_ts.tv_sec = 20;
733 	min_ts.tv_nsec = 0;
734 	clock_gettime(CLOCK_MONOTONIC_RAW, &now);
735 	add_timespecs(&min_ts, &now);
736 	ret = dev_io_next_output_wake(&thread->open_devs[CRAS_STREAM_OUTPUT],
737 				      &min_ts);
738 	ret += dev_io_next_input_wake(&thread->open_devs[CRAS_STREAM_INPUT],
739 				      &min_ts);
740 	if (timespec_after(&min_ts, &now))
741 		subtract_timespecs(&min_ts, &now, ts);
742 
743 	return ret;
744 }
745 
add_pollfd(struct audio_thread * thread,int fd,int events)746 static struct pollfd *add_pollfd(struct audio_thread *thread, int fd,
747 				 int events)
748 {
749 	thread->pollfds[thread->num_pollfds].fd = fd;
750 	thread->pollfds[thread->num_pollfds].events = events;
751 	thread->num_pollfds++;
752 	if (thread->num_pollfds >= thread->pollfds_size) {
753 		thread->pollfds_size *= 2;
754 		thread->pollfds = (struct pollfd *)realloc(
755 			thread->pollfds,
756 			sizeof(*thread->pollfds) * thread->pollfds_size);
757 		return NULL;
758 	}
759 
760 	return &thread->pollfds[thread->num_pollfds - 1];
761 }
762 
763 static int continuous_zero_sleep_count = 0;
764 static unsigned busyloop_count = 0;
765 
766 /*
767  * Logs the number of busyloop during one audio thread running state
768  * (wait_ts != NULL).
769  */
log_busyloop(struct timespec * wait_ts)770 static void log_busyloop(struct timespec *wait_ts)
771 {
772 	static struct timespec start_time;
773 	static bool started = false;
774 	struct timespec diff, now;
775 
776 	/* If wait_ts is NULL, there is no stream running. */
777 	if (wait_ts && !started) {
778 		started = true;
779 		busyloop_count = 0;
780 		clock_gettime(CLOCK_MONOTONIC_RAW, &start_time);
781 	} else if (!wait_ts && started) {
782 		started = false;
783 		clock_gettime(CLOCK_MONOTONIC_RAW, &now);
784 		subtract_timespecs(&now, &start_time, &diff);
785 		cras_server_metrics_busyloop(&diff, busyloop_count);
786 	}
787 }
788 
check_busyloop(struct timespec * wait_ts)789 static void check_busyloop(struct timespec *wait_ts)
790 {
791 	if (wait_ts->tv_sec == 0 && wait_ts->tv_nsec == 0) {
792 		continuous_zero_sleep_count++;
793 		if (continuous_zero_sleep_count ==
794 		    MAX_CONTINUOUS_ZERO_SLEEP_COUNT) {
795 			busyloop_count++;
796 			cras_audio_thread_event_busyloop();
797 		}
798 		if (continuous_zero_sleep_count ==
799 		    MAX_CONTINUOUS_ZERO_SLEEP_METRIC_LIMIT)
800 			cras_server_metrics_busyloop_length(
801 				continuous_zero_sleep_count);
802 
803 	} else {
804 		if (continuous_zero_sleep_count >=
805 			    MAX_CONTINUOUS_ZERO_SLEEP_COUNT &&
806 		    continuous_zero_sleep_count <
807 			    MAX_CONTINUOUS_ZERO_SLEEP_METRIC_LIMIT)
808 			cras_server_metrics_busyloop_length(
809 				continuous_zero_sleep_count);
810 		continuous_zero_sleep_count = 0;
811 	}
812 }
813 
814 /* For playback, fill the audio buffer when needed, for capture, pull out
815  * samples when they are ready.
816  * This thread will attempt to run at a high priority to allow for low latency
817  * streams.  This thread sleeps while the device plays back or captures audio,
818  * it will wake up as little as it can while avoiding xruns.  It can also be
819  * woken by sending it a message using the "audio_thread_post_message" function.
820  */
audio_io_thread(void * arg)821 static void *audio_io_thread(void *arg)
822 {
823 	struct audio_thread *thread = (struct audio_thread *)arg;
824 	struct open_dev *adev;
825 	struct dev_stream *curr;
826 	struct timespec ts;
827 	int msg_fd;
828 	int rc;
829 
830 	msg_fd = thread->to_thread_fds[0];
831 
832 	/* Attempt to get realtime scheduling */
833 	if (cras_set_rt_scheduling(CRAS_SERVER_RT_THREAD_PRIORITY) == 0)
834 		cras_set_thread_priority(CRAS_SERVER_RT_THREAD_PRIORITY);
835 
836 	thread->pollfds[0].fd = msg_fd;
837 	thread->pollfds[0].events = POLLIN;
838 
839 	while (1) {
840 		struct timespec *wait_ts;
841 		struct iodev_callback_list *iodev_cb;
842 		int non_empty;
843 
844 		wait_ts = NULL;
845 		thread->num_pollfds = 1;
846 
847 		/* device opened */
848 		dev_io_run(&thread->open_devs[CRAS_STREAM_OUTPUT],
849 			   &thread->open_devs[CRAS_STREAM_INPUT],
850 			   thread->remix_converter);
851 
852 		non_empty = dev_io_check_non_empty_state_transition(
853 			thread->open_devs[CRAS_STREAM_OUTPUT]);
854 
855 		if (fill_next_sleep_interval(thread, &ts))
856 			wait_ts = &ts;
857 
858 	restart_poll_loop:
859 		thread->num_pollfds = 1;
860 
861 		DL_FOREACH (iodev_callbacks, iodev_cb) {
862 			if (iodev_cb->trigger != TRIGGER_POLL) {
863 				iodev_cb->pollfd = NULL;
864 				continue;
865 			}
866 			iodev_cb->pollfd = add_pollfd(thread, iodev_cb->fd,
867 						      iodev_cb->events);
868 			if (!iodev_cb->pollfd)
869 				goto restart_poll_loop;
870 		}
871 
872 		/* TODO(dgreid) - once per rstream not per dev_stream */
873 		DL_FOREACH (thread->open_devs[CRAS_STREAM_OUTPUT], adev) {
874 			DL_FOREACH (adev->dev->streams, curr) {
875 				int fd = dev_stream_poll_stream_fd(curr);
876 				if (fd < 0)
877 					continue;
878 				if (!add_pollfd(thread, fd, POLLIN))
879 					goto restart_poll_loop;
880 			}
881 		}
882 		DL_FOREACH (thread->open_devs[CRAS_STREAM_INPUT], adev) {
883 			DL_FOREACH (adev->dev->streams, curr) {
884 				int fd = dev_stream_poll_stream_fd(curr);
885 				if (fd < 0)
886 					continue;
887 				if (!add_pollfd(thread, fd, POLLIN))
888 					goto restart_poll_loop;
889 			}
890 		}
891 
892 		log_busyloop(wait_ts);
893 
894 		ATLOG(atlog, AUDIO_THREAD_SLEEP, wait_ts ? wait_ts->tv_sec : 0,
895 		      wait_ts ? wait_ts->tv_nsec : 0, non_empty);
896 		if (wait_ts)
897 			check_busyloop(wait_ts);
898 
899 		/* Sync atlog with shared memory. */
900 		__sync_synchronize();
901 		atlog->sync_write_pos = atlog->write_pos;
902 
903 		rc = ppoll(thread->pollfds, thread->num_pollfds, wait_ts, NULL);
904 		ATLOG(atlog, AUDIO_THREAD_WAKE, rc, 0, 0);
905 
906 		/* Handle callbacks registered by TRIGGER_WAKEUP */
907 		DL_FOREACH (iodev_callbacks, iodev_cb) {
908 			if (iodev_cb->trigger == TRIGGER_WAKEUP) {
909 				ATLOG(atlog, AUDIO_THREAD_IODEV_CB, 0, 0, 0);
910 				iodev_cb->cb(iodev_cb->cb_data, 0);
911 			}
912 		}
913 
914 		/* If there's no pollfd ready to handle. */
915 		if (rc <= 0)
916 			continue;
917 
918 		if (thread->pollfds[0].revents & POLLIN) {
919 			rc = handle_audio_thread_message(thread);
920 			if (rc < 0)
921 				syslog(LOG_ERR, "handle message %d", rc);
922 		}
923 
924 		DL_FOREACH (iodev_callbacks, iodev_cb) {
925 			if (iodev_cb->pollfd &&
926 			    iodev_cb->pollfd->revents & iodev_cb->events) {
927 				ATLOG(atlog, AUDIO_THREAD_IODEV_CB,
928 				      iodev_cb->pollfd->revents,
929 				      iodev_cb->events, 0);
930 				iodev_cb->cb(iodev_cb->cb_data,
931 					     iodev_cb->pollfd->revents);
932 			}
933 		}
934 	}
935 
936 	return NULL;
937 }
938 
939 /* Write a message to the playback thread and wait for an ack, This keeps these
940  * operations synchronous for the main server thread.  For instance when the
941  * RM_STREAM message is sent, the stream can be deleted after the function
942  * returns.  Making this synchronous also allows the thread to return an error
943  * code that can be handled by the caller.
944  * Args:
945  *    thread - thread to receive message.
946  *    msg - The message to send.
947  * Returns:
948  *    A return code from the message handler in the thread.
949  */
audio_thread_post_message(struct audio_thread * thread,struct audio_thread_msg * msg)950 static int audio_thread_post_message(struct audio_thread *thread,
951 				     struct audio_thread_msg *msg)
952 {
953 	int err, rsp;
954 
955 	err = write(thread->to_thread_fds[1], msg, msg->length);
956 	if (err < 0) {
957 		syslog(LOG_ERR, "Failed to post message to thread.");
958 		return err;
959 	}
960 	/* Synchronous action, wait for response. */
961 	err = read_until_finished(thread->to_main_fds[0], &rsp, sizeof(rsp));
962 	if (err < 0) {
963 		syslog(LOG_ERR, "Failed to read reply from thread.");
964 		return err;
965 	}
966 
967 	return rsp;
968 }
969 
init_open_device_msg(struct audio_thread_open_device_msg * msg,enum AUDIO_THREAD_COMMAND id,struct cras_iodev * dev)970 static void init_open_device_msg(struct audio_thread_open_device_msg *msg,
971 				 enum AUDIO_THREAD_COMMAND id,
972 				 struct cras_iodev *dev)
973 {
974 	memset(msg, 0, sizeof(*msg));
975 	msg->header.id = id;
976 	msg->header.length = sizeof(*msg);
977 	msg->dev = dev;
978 }
979 
init_rm_device_msg(struct audio_thread_rm_device_msg * msg,enum CRAS_STREAM_DIRECTION dir,unsigned int dev_idx)980 static void init_rm_device_msg(struct audio_thread_rm_device_msg *msg,
981 			       enum CRAS_STREAM_DIRECTION dir,
982 			       unsigned int dev_idx)
983 {
984 	memset(msg, 0, sizeof(*msg));
985 	msg->header.id = AUDIO_THREAD_RM_OPEN_DEV;
986 	msg->header.length = sizeof(*msg);
987 	msg->dir = dir;
988 	msg->dev_idx = dev_idx;
989 }
990 
init_add_rm_stream_msg(struct audio_thread_add_rm_stream_msg * msg,enum AUDIO_THREAD_COMMAND id,struct cras_rstream * stream,struct cras_iodev ** devs,unsigned int num_devs)991 static void init_add_rm_stream_msg(struct audio_thread_add_rm_stream_msg *msg,
992 				   enum AUDIO_THREAD_COMMAND id,
993 				   struct cras_rstream *stream,
994 				   struct cras_iodev **devs,
995 				   unsigned int num_devs)
996 {
997 	memset(msg, 0, sizeof(*msg));
998 	msg->header.id = id;
999 	msg->header.length = sizeof(*msg);
1000 	msg->stream = stream;
1001 	msg->devs = devs;
1002 	msg->num_devs = num_devs;
1003 }
1004 
1005 static void
init_dump_debug_info_msg(struct audio_thread_dump_debug_info_msg * msg,struct audio_debug_info * info)1006 init_dump_debug_info_msg(struct audio_thread_dump_debug_info_msg *msg,
1007 			 struct audio_debug_info *info)
1008 {
1009 	memset(msg, 0, sizeof(*msg));
1010 	msg->header.id = AUDIO_THREAD_DUMP_THREAD_INFO;
1011 	msg->header.length = sizeof(*msg);
1012 	msg->info = info;
1013 }
1014 
1015 static void
init_config_global_remix_msg(struct audio_thread_config_global_remix * msg)1016 init_config_global_remix_msg(struct audio_thread_config_global_remix *msg)
1017 {
1018 	memset(msg, 0, sizeof(*msg));
1019 	msg->header.id = AUDIO_THREAD_CONFIG_GLOBAL_REMIX;
1020 	msg->header.length = sizeof(*msg);
1021 }
1022 
1023 static void
init_device_start_ramp_msg(struct audio_thread_dev_start_ramp_msg * msg,enum AUDIO_THREAD_COMMAND id,unsigned int dev_idx,enum CRAS_IODEV_RAMP_REQUEST request)1024 init_device_start_ramp_msg(struct audio_thread_dev_start_ramp_msg *msg,
1025 			   enum AUDIO_THREAD_COMMAND id, unsigned int dev_idx,
1026 			   enum CRAS_IODEV_RAMP_REQUEST request)
1027 {
1028 	memset(msg, 0, sizeof(*msg));
1029 	msg->header.id = id;
1030 	msg->header.length = sizeof(*msg);
1031 	msg->dev_idx = dev_idx;
1032 	msg->request = request;
1033 }
1034 
1035 /* Exported Interface */
1036 
audio_thread_event_log_shm_fd()1037 int audio_thread_event_log_shm_fd()
1038 {
1039 	return atlog_ro_shm_fd;
1040 }
1041 
audio_thread_add_stream(struct audio_thread * thread,struct cras_rstream * stream,struct cras_iodev ** devs,unsigned int num_devs)1042 int audio_thread_add_stream(struct audio_thread *thread,
1043 			    struct cras_rstream *stream,
1044 			    struct cras_iodev **devs, unsigned int num_devs)
1045 {
1046 	struct audio_thread_add_rm_stream_msg msg;
1047 
1048 	assert(thread && stream);
1049 
1050 	if (!thread->started)
1051 		return -EINVAL;
1052 
1053 	init_add_rm_stream_msg(&msg, AUDIO_THREAD_ADD_STREAM, stream, devs,
1054 			       num_devs);
1055 	return audio_thread_post_message(thread, &msg.header);
1056 }
1057 
audio_thread_disconnect_stream(struct audio_thread * thread,struct cras_rstream * stream,struct cras_iodev * dev)1058 int audio_thread_disconnect_stream(struct audio_thread *thread,
1059 				   struct cras_rstream *stream,
1060 				   struct cras_iodev *dev)
1061 {
1062 	struct audio_thread_add_rm_stream_msg msg;
1063 
1064 	assert(thread && stream);
1065 
1066 	init_add_rm_stream_msg(&msg, AUDIO_THREAD_DISCONNECT_STREAM, stream,
1067 			       &dev, 0);
1068 	return audio_thread_post_message(thread, &msg.header);
1069 }
1070 
audio_thread_drain_stream(struct audio_thread * thread,struct cras_rstream * stream)1071 int audio_thread_drain_stream(struct audio_thread *thread,
1072 			      struct cras_rstream *stream)
1073 {
1074 	struct audio_thread_add_rm_stream_msg msg;
1075 
1076 	assert(thread && stream);
1077 
1078 	init_add_rm_stream_msg(&msg, AUDIO_THREAD_DRAIN_STREAM, stream, NULL,
1079 			       0);
1080 	return audio_thread_post_message(thread, &msg.header);
1081 }
1082 
audio_thread_dump_thread_info(struct audio_thread * thread,struct audio_debug_info * info)1083 int audio_thread_dump_thread_info(struct audio_thread *thread,
1084 				  struct audio_debug_info *info)
1085 {
1086 	struct audio_thread_dump_debug_info_msg msg;
1087 
1088 	init_dump_debug_info_msg(&msg, info);
1089 	return audio_thread_post_message(thread, &msg.header);
1090 }
1091 
audio_thread_set_aec_dump(struct audio_thread * thread,cras_stream_id_t stream_id,unsigned int start,int fd)1092 int audio_thread_set_aec_dump(struct audio_thread *thread,
1093 			      cras_stream_id_t stream_id, unsigned int start,
1094 			      int fd)
1095 {
1096 	struct audio_thread_aec_dump_msg msg;
1097 
1098 	memset(&msg, 0, sizeof(msg));
1099 	msg.header.id = AUDIO_THREAD_AEC_DUMP;
1100 	msg.header.length = sizeof(msg);
1101 	msg.stream_id = stream_id;
1102 	msg.start = start;
1103 	msg.fd = fd;
1104 	return audio_thread_post_message(thread, &msg.header);
1105 }
1106 
audio_thread_rm_callback_sync(struct audio_thread * thread,int fd)1107 int audio_thread_rm_callback_sync(struct audio_thread *thread, int fd)
1108 {
1109 	struct audio_thread_rm_callback_msg msg;
1110 
1111 	memset(&msg, 0, sizeof(msg));
1112 	msg.header.id = AUDIO_THREAD_REMOVE_CALLBACK;
1113 	msg.header.length = sizeof(msg);
1114 	msg.fd = fd;
1115 
1116 	return audio_thread_post_message(thread, &msg.header);
1117 }
1118 
audio_thread_config_global_remix(struct audio_thread * thread,unsigned int num_channels,const float * coefficient)1119 int audio_thread_config_global_remix(struct audio_thread *thread,
1120 				     unsigned int num_channels,
1121 				     const float *coefficient)
1122 {
1123 	int err;
1124 	int identity_remix = 1;
1125 	unsigned int i, j;
1126 	struct audio_thread_config_global_remix msg;
1127 	void *rsp;
1128 
1129 	init_config_global_remix_msg(&msg);
1130 
1131 	/* Check if the coefficients represent an identity matrix for remix
1132 	 * conversion, which means no remix at all. If so then leave the
1133 	 * converter as NULL. */
1134 	for (i = 0; i < num_channels; i++) {
1135 		if (coefficient[i * num_channels + i] != 1.0f) {
1136 			identity_remix = 0;
1137 			break;
1138 		}
1139 		for (j = i + 1; j < num_channels; j++) {
1140 			if (coefficient[i * num_channels + j] != 0 ||
1141 			    coefficient[j * num_channels + i] != 0) {
1142 				identity_remix = 0;
1143 				break;
1144 			}
1145 		}
1146 	}
1147 
1148 	if (!identity_remix) {
1149 		msg.fmt_conv = cras_channel_remix_conv_create(num_channels,
1150 							      coefficient);
1151 		if (NULL == msg.fmt_conv)
1152 			return -ENOMEM;
1153 	}
1154 
1155 	err = write(thread->to_thread_fds[1], &msg, msg.header.length);
1156 	if (err < 0) {
1157 		syslog(LOG_ERR, "Failed to post message to thread.");
1158 		return err;
1159 	}
1160 	/* Synchronous action, wait for response. */
1161 	err = read_until_finished(thread->to_main_fds[0], &rsp, sizeof(rsp));
1162 	if (err < 0) {
1163 		syslog(LOG_ERR, "Failed to read reply from thread.");
1164 		return err;
1165 	}
1166 
1167 	if (rsp)
1168 		cras_fmt_conv_destroy((struct cras_fmt_conv **)&rsp);
1169 	return 0;
1170 }
1171 
audio_thread_create()1172 struct audio_thread *audio_thread_create()
1173 {
1174 	int rc;
1175 	struct audio_thread *thread;
1176 
1177 	thread = (struct audio_thread *)calloc(1, sizeof(*thread));
1178 	if (!thread)
1179 		return NULL;
1180 
1181 	thread->to_thread_fds[0] = -1;
1182 	thread->to_thread_fds[1] = -1;
1183 	thread->to_main_fds[0] = -1;
1184 	thread->to_main_fds[1] = -1;
1185 
1186 	/* Two way pipes for communication with the device's audio thread. */
1187 	rc = pipe(thread->to_thread_fds);
1188 	if (rc < 0) {
1189 		syslog(LOG_ERR, "Failed to pipe");
1190 		free(thread);
1191 		return NULL;
1192 	}
1193 	rc = pipe(thread->to_main_fds);
1194 	if (rc < 0) {
1195 		syslog(LOG_ERR, "Failed to pipe");
1196 		free(thread);
1197 		return NULL;
1198 	}
1199 
1200 	if (asprintf(&atlog_name, "/ATlog-%d", getpid()) < 0) {
1201 		syslog(LOG_ERR, "Failed to generate ATlog name.");
1202 		exit(-1);
1203 	}
1204 
1205 	atlog = audio_thread_event_log_init(atlog_name);
1206 
1207 	thread->pollfds_size = 32;
1208 	thread->pollfds = (struct pollfd *)malloc(sizeof(*thread->pollfds) *
1209 						  thread->pollfds_size);
1210 
1211 	return thread;
1212 }
1213 
audio_thread_add_open_dev(struct audio_thread * thread,struct cras_iodev * dev)1214 int audio_thread_add_open_dev(struct audio_thread *thread,
1215 			      struct cras_iodev *dev)
1216 {
1217 	struct audio_thread_open_device_msg msg;
1218 
1219 	assert(thread && dev);
1220 
1221 	if (!thread->started)
1222 		return -EINVAL;
1223 
1224 	init_open_device_msg(&msg, AUDIO_THREAD_ADD_OPEN_DEV, dev);
1225 	return audio_thread_post_message(thread, &msg.header);
1226 }
1227 
audio_thread_rm_open_dev(struct audio_thread * thread,enum CRAS_STREAM_DIRECTION dir,unsigned int dev_idx)1228 int audio_thread_rm_open_dev(struct audio_thread *thread,
1229 			     enum CRAS_STREAM_DIRECTION dir,
1230 			     unsigned int dev_idx)
1231 {
1232 	struct audio_thread_rm_device_msg msg;
1233 
1234 	assert(thread);
1235 	if (!thread->started)
1236 		return -EINVAL;
1237 
1238 	init_rm_device_msg(&msg, dir, dev_idx);
1239 	return audio_thread_post_message(thread, &msg.header);
1240 }
1241 
audio_thread_is_dev_open(struct audio_thread * thread,struct cras_iodev * dev)1242 int audio_thread_is_dev_open(struct audio_thread *thread,
1243 			     struct cras_iodev *dev)
1244 {
1245 	struct audio_thread_open_device_msg msg;
1246 
1247 	if (!dev)
1248 		return 0;
1249 
1250 	init_open_device_msg(&msg, AUDIO_THREAD_IS_DEV_OPEN, dev);
1251 	return audio_thread_post_message(thread, &msg.header);
1252 }
1253 
audio_thread_dev_start_ramp(struct audio_thread * thread,unsigned int dev_idx,enum CRAS_IODEV_RAMP_REQUEST request)1254 int audio_thread_dev_start_ramp(struct audio_thread *thread,
1255 				unsigned int dev_idx,
1256 				enum CRAS_IODEV_RAMP_REQUEST request)
1257 {
1258 	struct audio_thread_dev_start_ramp_msg msg;
1259 
1260 	assert(thread);
1261 
1262 	if (!thread->started)
1263 		return -EINVAL;
1264 
1265 	init_device_start_ramp_msg(&msg, AUDIO_THREAD_DEV_START_RAMP, dev_idx,
1266 				   request);
1267 	return audio_thread_post_message(thread, &msg.header);
1268 }
1269 
audio_thread_start(struct audio_thread * thread)1270 int audio_thread_start(struct audio_thread *thread)
1271 {
1272 	int rc;
1273 
1274 	rc = pthread_create(&thread->tid, NULL, audio_io_thread, thread);
1275 	if (rc) {
1276 		syslog(LOG_ERR, "Failed pthread_create");
1277 		return rc;
1278 	}
1279 
1280 	thread->started = 1;
1281 
1282 	return 0;
1283 }
1284 
audio_thread_destroy(struct audio_thread * thread)1285 void audio_thread_destroy(struct audio_thread *thread)
1286 {
1287 	if (thread->started) {
1288 		struct audio_thread_msg msg;
1289 
1290 		msg.id = AUDIO_THREAD_STOP;
1291 		msg.length = sizeof(msg);
1292 		audio_thread_post_message(thread, &msg);
1293 		pthread_join(thread->tid, NULL);
1294 	}
1295 
1296 	free(thread->pollfds);
1297 
1298 	audio_thread_event_log_deinit(atlog, atlog_name);
1299 	free(atlog_name);
1300 
1301 	if (thread->to_thread_fds[0] != -1) {
1302 		close(thread->to_thread_fds[0]);
1303 		close(thread->to_thread_fds[1]);
1304 	}
1305 	if (thread->to_main_fds[0] != -1) {
1306 		close(thread->to_main_fds[0]);
1307 		close(thread->to_main_fds[1]);
1308 	}
1309 
1310 	if (thread->remix_converter)
1311 		cras_fmt_conv_destroy(&thread->remix_converter);
1312 
1313 	free(thread);
1314 }
1315