/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef _GNU_SOURCE
#define _GNU_SOURCE /* for ppoll and asprintf*/
#endif

#include <pthread.h>
#include <poll.h>
#include <stdbool.h>
#include <stdio.h>
#include <sys/param.h>
#include <syslog.h>

#include "audio_thread_log.h"
#include "cras_audio_thread_monitor.h"
#include "cras_config.h"
#include "cras_device_monitor.h"
#include "cras_fmt_conv.h"
#include "cras_iodev.h"
#include "cras_rstream.h"
#include "cras_server_metrics.h"
#include "cras_system_state.h"
#include "cras_types.h"
#include "cras_util.h"
#include "dev_stream.h"
#include "audio_thread.h"
#include "utlist.h"

#define MIN_PROCESS_TIME_US 500 /* 0.5ms - min amount of time to mix/src. */
#define SLEEP_FUZZ_FRAMES 10 /* # to consider "close enough" to sleep frames. */
#define MIN_READ_WAIT_US 2000 /* 2ms */
/*
 * # to check whether a busyloop event happens
 */
#define MAX_CONTINUOUS_ZERO_SLEEP_COUNT 2

/*
 * If the number of continuous zero sleep is equal to this limit, the value
 * will be recorded immediately. It can ensure all busyloop will be recorded
 * even if the busyloop does not stop.
 */
#define MAX_CONTINUOUS_ZERO_SLEEP_METRIC_LIMIT 1000

/* Messages that can be sent from the main context to the audio thread. */
enum AUDIO_THREAD_COMMAND {
	AUDIO_THREAD_ADD_OPEN_DEV,
	AUDIO_THREAD_RM_OPEN_DEV,
	AUDIO_THREAD_IS_DEV_OPEN,
	AUDIO_THREAD_ADD_STREAM,
	AUDIO_THREAD_DISCONNECT_STREAM,
	AUDIO_THREAD_STOP,
	AUDIO_THREAD_DUMP_THREAD_INFO,
	AUDIO_THREAD_DRAIN_STREAM,
	AUDIO_THREAD_CONFIG_GLOBAL_REMIX,
	AUDIO_THREAD_DEV_START_RAMP,
	AUDIO_THREAD_REMOVE_CALLBACK,
	AUDIO_THREAD_AEC_DUMP,
};

struct audio_thread_msg {
	size_t length;
	enum AUDIO_THREAD_COMMAND id;
};

struct audio_thread_config_global_remix {
	struct audio_thread_msg header;
	struct cras_fmt_conv *fmt_conv;
};

struct audio_thread_open_device_msg {
	struct audio_thread_msg header;
	struct cras_iodev *dev;
};

struct audio_thread_rm_device_msg {
	struct audio_thread_msg header;
	enum CRAS_STREAM_DIRECTION dir;
	unsigned dev_idx;
};

struct audio_thread_rm_callback_msg {
	struct audio_thread_msg header;
	int fd;
};

struct audio_thread_add_rm_stream_msg {
	struct audio_thread_msg header;
	struct cras_rstream *stream;
	struct cras_iodev **devs;
	unsigned int num_devs;
};

struct audio_thread_dump_debug_info_msg {
	struct audio_thread_msg header;
	struct audio_debug_info *info;
};

struct audio_thread_dev_start_ramp_msg {
	struct audio_thread_msg header;
	unsigned int dev_idx;
	enum CRAS_IODEV_RAMP_REQUEST request;
};

struct audio_thread_aec_dump_msg {
	struct audio_thread_msg header;
	cras_stream_id_t stream_id;
	unsigned int start; /* */
	int fd;
};

/* Audio thread logging. If atlog is successfully created from cras_shm_setup,
 * then the fds should have valid value. Or audio thread will fallback to use
 * calloc to create atlog and leave the fds as -1.
 */
struct audio_thread_event_log *atlog;
char *atlog_name;
int atlog_rw_shm_fd;
int atlog_ro_shm_fd;

static struct iodev_callback_list *iodev_callbacks;

struct iodev_callback_list {
	int fd;
	int events;
	enum AUDIO_THREAD_EVENTS_CB_TRIGGER trigger;
	thread_callback cb;
	void *cb_data;
	struct pollfd *pollfd;
	struct iodev_callback_list *prev, *next;
};

void audio_thread_add_events_callback(int fd, thread_callback cb, void *data,
				      int events)
{
	struct iodev_callback_list *iodev_cb;

	/* Don't add iodev_cb twice */
	DL_FOREACH (iodev_callbacks, iodev_cb)
		if (iodev_cb->fd == fd && iodev_cb->cb_data == data)
			return;

	iodev_cb = (struct iodev_callback_list *)calloc(1, sizeof(*iodev_cb));
	iodev_cb->fd = fd;
	iodev_cb->cb = cb;
	iodev_cb->cb_data = data;
	iodev_cb->trigger = TRIGGER_POLL;
	iodev_cb->events = events;

	DL_APPEND(iodev_callbacks, iodev_cb);
}

void audio_thread_rm_callback(int fd)
{
	struct iodev_callback_list *iodev_cb;

	DL_FOREACH (iodev_callbacks, iodev_cb) {
		if (iodev_cb->fd == fd) {
			DL_DELETE(iodev_callbacks, iodev_cb);
			free(iodev_cb);
			return;
		}
	}
}

void audio_thread_config_events_callback(
	int fd, enum AUDIO_THREAD_EVENTS_CB_TRIGGER trigger)
{
	struct iodev_callback_list *iodev_cb;

	DL_FOREACH (iodev_callbacks, iodev_cb) {
		if (iodev_cb->fd == fd) {
			iodev_cb->trigger = trigger;
			return;
		}
	}
}

/* Sends a response (error code) from the audio thread to the main thread.
 * Indicates that the last message sent to the audio thread has been handled
 * with an error code of rc.
 * Args:
 *    thread - thread responding to command.
 *    rc - Result code to send back to the main thread.
 * Returns:
 *    The number of bytes written to the main thread.
 */
static int audio_thread_send_response(struct audio_thread *thread, int rc)
{
	return write(thread->to_main_fds[1], &rc, sizeof(rc));
}

/* Reads from a file descriptor until all bytes are read.
 *
 * Args:
 *    fd - file descriptor to read
 *    buf - the buffer to be written.
 *    count - the number of bytes to read from fd
 * Returns:
 *    |count| on success, negative error code on failure.
 */
static int read_until_finished(int fd, void *buf, size_t count)
{
	int nread, count_left = count;

	while (count_left > 0) {
		nread = read(fd, (uint8_t *)buf + count - count_left,
			     count_left);
		if (nread < 0) {
			if (errno == EINTR)
				continue;
			else
				return nread;
		} else if (nread == 0) {
			syslog(LOG_ERR, "Pipe has been closed.");
			return -EPIPE;
		}
		count_left -= nread;
	}
	return count;
}

/* Reads a command from the main thread.  Called from the playback/capture
 * thread.  This will read the next available command from the main thread and
 * put it in buf.
 * Args:
 *    thread - thread reading the command.
 *    buf - Message is stored here on return.
 *    max_len - maximum length of message to put into buf.
 * Returns:
 *    0 on success, negative error code on failure.
 */
static int audio_thread_read_command(struct audio_thread *thread, uint8_t *buf,
				     size_t max_len)
{
	int to_read, nread, rc;
	struct audio_thread_msg *msg = (struct audio_thread_msg *)buf;

	/* Get the length of the message first */
	nread = read_until_finished(thread->to_thread_fds[0], buf,
				    sizeof(msg->length));
	if (nread < 0)
		return nread;

	if (msg->length > max_len)
		return -ENOMEM;

	to_read = msg->length - sizeof(msg->length);
	rc = read_until_finished(thread->to_thread_fds[0],
				 &buf[0] + sizeof(msg->length), to_read);
	if (rc < 0)
		return rc;
	return 0;
}

/* Builds an initial buffer to avoid an underrun. Adds min_level of latency. */
static void fill_odevs_zeros_min_level(struct cras_iodev *odev)
{
	cras_iodev_fill_odev_zeros(odev, odev->min_buffer_level);
}

/* Handles messages from main thread to add a new active device. */
static int thread_add_open_dev(struct audio_thread *thread,
			       struct cras_iodev *iodev)
{
	struct open_dev *adev;

	DL_SEARCH_SCALAR(thread->open_devs[iodev->direction], adev, dev, iodev);
	if (adev)
		return -EEXIST;

	adev = (struct open_dev *)calloc(1, sizeof(*adev));
	adev->dev = iodev;

	/*
	 * Start output devices by padding the output. This avoids a burst of
	 * audio callbacks when the stream starts
	 */
	if (iodev->direction == CRAS_STREAM_OUTPUT)
		fill_odevs_zeros_min_level(iodev);

	ATLOG(atlog, AUDIO_THREAD_DEV_ADDED, iodev->info.idx, 0, 0);

	DL_APPEND(thread->open_devs[iodev->direction], adev);

	return 0;
}

/* Handles messages from the main thread to remove an active device. */
static int thread_rm_open_dev(struct audio_thread *thread,
			      enum CRAS_STREAM_DIRECTION dir,
			      unsigned int dev_idx)
{
	struct open_dev *adev =
		dev_io_find_open_dev(thread->open_devs[dir], dev_idx);
	if (!adev)
		return -EINVAL;

	dev_io_rm_open_dev(&thread->open_devs[dir], adev);
	return 0;
}

/*
 * Handles message from the main thread to check if an iodev is in the
 * open dev list.
 */
static int thread_is_dev_open(struct audio_thread *thread,
			      struct cras_iodev *iodev)
{
	struct open_dev *adev = dev_io_find_open_dev(
		thread->open_devs[iodev->direction], iodev->info.idx);
	return !!adev;
}

/*
 * Handles messages from the main thread to start ramping on a device.
 * Start ramping in audio thread and set mute/unmute
 * state on device. This should only be done when
 * device is running with valid streams.
 *
 * 1. Mute -> Unmute: Set device unmute state after
 *                    ramping is started.
 * 2. Unmute -> Mute: Set device mute state after
 *                    ramping is done.
 *
 * The above transition will be handled by cras_iodev_start_ramp.
 */
static int thread_dev_start_ramp(struct audio_thread *thread,
				 unsigned int dev_idx,
				 enum CRAS_IODEV_RAMP_REQUEST request)
{
	/* Do nothing if device wasn't already in the active dev list. */
	struct cras_iodev *iodev;
	struct open_dev *adev = dev_io_find_open_dev(
		thread->open_devs[CRAS_STREAM_OUTPUT], dev_idx);
	if (!adev)
		return -EINVAL;
	iodev = adev->dev;

	/*
	 * Checks if a device should start ramping for mute/unmute change.
	 * Device must meet all the conditions:
	 *
	 * - Device has ramp support.
	 * - Device is in normal run state, that is, it must be running with valid
	 *   streams.
	 * - Device volume, which considers both system volume and adjusted active
	 *   node volume, is not zero. If device volume is zero, all the samples are
	 *   suppressed to zero and there is no need to ramp.
	 */
	if (iodev->ramp &&
	    cras_iodev_state(iodev) == CRAS_IODEV_STATE_NORMAL_RUN &&
	    !cras_iodev_is_zero_volume(iodev))
		return cras_iodev_start_ramp(iodev, request);
	else
		return cras_device_monitor_set_device_mute_state(
			iodev->info.idx);
}

/* Return non-zero if the stream is attached to any device. */
static int thread_find_stream(struct audio_thread *thread,
			      struct cras_rstream *rstream)
{
	struct open_dev *open_dev;
	struct dev_stream *s;

	DL_FOREACH (thread->open_devs[rstream->direction], open_dev) {
		DL_FOREACH (open_dev->dev->streams, s) {
			if (s->stream == rstream)
				return 1;
		}
	}
	return 0;
}

/* Handles the disconnect_stream message from the main thread. */
static int thread_disconnect_stream(struct audio_thread *thread,
				    struct cras_rstream *stream,
				    struct cras_iodev *dev)
{
	int rc;

	if (!thread_find_stream(thread, stream))
		return 0;

	rc = dev_io_remove_stream(&thread->open_devs[stream->direction], stream,
				  dev);

	return rc;
}

/* Initiates draining of a stream or returns the status of a draining stream.
 * If the stream has completed draining the thread forfeits ownership and must
 * never reference it again.  Returns the number of milliseconds it will take to
 * finish draining, a minimum of one ms if any samples remain.
 */
static int thread_drain_stream_ms_remaining(struct audio_thread *thread,
					    struct cras_rstream *rstream)
{
	int fr_in_buff;
	struct cras_audio_shm *shm;

	if (rstream->direction != CRAS_STREAM_OUTPUT)
		return 0;

	shm = cras_rstream_shm(rstream);
	fr_in_buff = cras_shm_get_frames(shm);

	if (fr_in_buff <= 0)
		return 0;

	cras_rstream_set_is_draining(rstream, 1);

	return 1 + cras_frames_to_ms(fr_in_buff, rstream->format.frame_rate);
}

/* Handles a request to begin draining and return the amount of time left to
 * draing a stream.
 */
static int thread_drain_stream(struct audio_thread *thread,
			       struct cras_rstream *rstream)
{
	int ms_left;

	if (!thread_find_stream(thread, rstream))
		return 0;

	ms_left = thread_drain_stream_ms_remaining(thread, rstream);
	if (ms_left == 0)
		dev_io_remove_stream(&thread->open_devs[rstream->direction],
				     rstream, NULL);

	return ms_left;
}

/* Handles the add_stream message from the main thread. */
static int thread_add_stream(struct audio_thread *thread,
			     struct cras_rstream *stream,
			     struct cras_iodev **iodevs,
			     unsigned int num_iodevs)
{
	int rc;

	rc = dev_io_append_stream(&thread->open_devs[CRAS_STREAM_OUTPUT],
				  &thread->open_devs[CRAS_STREAM_INPUT], stream,
				  iodevs, num_iodevs);
	if (rc < 0)
		return rc;

	return 0;
}

/* Starts or stops aec dump task. */
static int thread_set_aec_dump(struct audio_thread *thread,
			       cras_stream_id_t stream_id, unsigned int start,
			       int fd)
{
	struct open_dev *idev_list = thread->open_devs[CRAS_STREAM_INPUT];
	struct open_dev *adev;
	struct dev_stream *stream;

	DL_FOREACH (idev_list, adev) {
		if (!cras_iodev_is_open(adev->dev))
			continue;

		DL_FOREACH (adev->dev->streams, stream) {
			if ((stream->stream->apm_list == NULL) ||
			    (stream->stream->stream_id != stream_id))
				continue;

			cras_apm_list_set_aec_dump(stream->stream->apm_list,
						   adev->dev, start, fd);
		}
	}
	return 0;
}

/* Stop the playback thread */
static void terminate_pb_thread()
{
	pthread_exit(0);
}

static void append_dev_dump_info(struct audio_dev_debug_info *di,
				 struct open_dev *adev)
{
	struct cras_audio_format *fmt = adev->dev->format;
	struct timespec now, time_since;
	strncpy(di->dev_name, adev->dev->info.name, sizeof(di->dev_name));
	di->buffer_size = adev->dev->buffer_size;
	di->min_buffer_level = adev->dev->min_buffer_level;
	di->min_cb_level = adev->dev->min_cb_level;
	di->max_cb_level = adev->dev->max_cb_level;
	di->direction = adev->dev->direction;
	di->num_underruns = cras_iodev_get_num_underruns(adev->dev);
	di->num_severe_underruns =
		cras_iodev_get_num_severe_underruns(adev->dev);
	di->highest_hw_level = adev->dev->highest_hw_level;
	di->software_gain_scaler = (adev->dev->direction == CRAS_STREAM_INPUT) ?
					   adev->dev->software_gain_scaler :
					   0.0f;

	clock_gettime(CLOCK_MONOTONIC_RAW, &now);
	subtract_timespecs(&now, &adev->dev->open_ts, &time_since);
	di->runtime_sec = time_since.tv_sec;
	di->runtime_nsec = time_since.tv_nsec;
	di->longest_wake_sec = adev->longest_wake.tv_sec;
	di->longest_wake_nsec = adev->longest_wake.tv_nsec;

	if (fmt) {
		di->frame_rate = fmt->frame_rate;
		di->num_channels = fmt->num_channels;
		di->est_rate_ratio = cras_iodev_get_est_rate_ratio(adev->dev);
	} else {
		di->frame_rate = 0;
		di->num_channels = 0;
		di->est_rate_ratio = 0;
	}
}

/* Put stream info for the given stream into the info struct. */
static void append_stream_dump_info(struct audio_debug_info *info,
				    struct dev_stream *stream,
				    unsigned int dev_idx, int index)
{
	struct audio_stream_debug_info *si;
	struct timespec now, time_since;

	si = &info->streams[index];

	si->stream_id = stream->stream->stream_id;
	si->dev_idx = dev_idx;
	si->direction = stream->stream->direction;
	si->stream_type = stream->stream->stream_type;
	si->client_type = stream->stream->client_type;
	si->buffer_frames = stream->stream->buffer_frames;
	si->cb_threshold = stream->stream->cb_threshold;
	si->frame_rate = stream->stream->format.frame_rate;
	si->num_channels = stream->stream->format.num_channels;
	memcpy(si->channel_layout, stream->stream->format.channel_layout,
	       sizeof(si->channel_layout));
	si->longest_fetch_sec = stream->stream->longest_fetch_interval.tv_sec;
	si->longest_fetch_nsec = stream->stream->longest_fetch_interval.tv_nsec;
	si->num_overruns = cras_shm_num_overruns(stream->stream->shm);
	si->effects = cras_apm_list_get_effects(stream->stream->apm_list);
	si->pinned_dev_idx = stream->stream->pinned_dev_idx;
	si->is_pinned = stream->stream->is_pinned;
	si->num_missed_cb = stream->stream->num_missed_cb;
	si->stream_volume = cras_rstream_get_volume_scaler(stream->stream);

	clock_gettime(CLOCK_MONOTONIC_RAW, &now);
	subtract_timespecs(&now, &stream->stream->start_ts, &time_since);
	si->runtime_sec = time_since.tv_sec;
	si->runtime_nsec = time_since.tv_nsec;
}

/* Handle a message sent from main thread to the audio thread.
 * Returns:
 *    Error code when reading or sending message fails.
 */
static int handle_audio_thread_message(struct audio_thread *thread)
{
	uint8_t buf[256];
	struct audio_thread_msg *msg = (struct audio_thread_msg *)buf;
	int ret = 0;
	int err;

	err = audio_thread_read_command(thread, buf, 256);
	if (err < 0)
		return err;

	ATLOG(atlog, AUDIO_THREAD_PB_MSG, msg->id, 0, 0);

	switch (msg->id) {
	case AUDIO_THREAD_ADD_STREAM: {
		struct audio_thread_add_rm_stream_msg *amsg;
		amsg = (struct audio_thread_add_rm_stream_msg *)msg;
		ATLOG(atlog, AUDIO_THREAD_WRITE_STREAMS_WAIT,
		      amsg->stream->stream_id, 0, 0);
		ret = thread_add_stream(thread, amsg->stream, amsg->devs,
					amsg->num_devs);
		break;
	}
	case AUDIO_THREAD_DISCONNECT_STREAM: {
		struct audio_thread_add_rm_stream_msg *rmsg;

		rmsg = (struct audio_thread_add_rm_stream_msg *)msg;

		ret = thread_disconnect_stream(thread, rmsg->stream,
					       rmsg->devs[0]);
		break;
	}
	case AUDIO_THREAD_ADD_OPEN_DEV: {
		struct audio_thread_open_device_msg *rmsg;

		rmsg = (struct audio_thread_open_device_msg *)msg;
		ret = thread_add_open_dev(thread, rmsg->dev);
		break;
	}
	case AUDIO_THREAD_RM_OPEN_DEV: {
		struct audio_thread_rm_device_msg *rmsg;

		rmsg = (struct audio_thread_rm_device_msg *)msg;
		ret = thread_rm_open_dev(thread, rmsg->dir, rmsg->dev_idx);
		break;
	}
	case AUDIO_THREAD_IS_DEV_OPEN: {
		struct audio_thread_open_device_msg *rmsg;

		rmsg = (struct audio_thread_open_device_msg *)msg;
		ret = thread_is_dev_open(thread, rmsg->dev);
		break;
	}
	case AUDIO_THREAD_STOP:
		ret = 0;
		err = audio_thread_send_response(thread, ret);
		if (err < 0)
			return err;
		terminate_pb_thread();
		break;
	case AUDIO_THREAD_DUMP_THREAD_INFO: {
		struct dev_stream *curr;
		struct open_dev *adev;
		struct audio_thread_dump_debug_info_msg *dmsg;
		struct audio_debug_info *info;
		unsigned int num_streams = 0;
		unsigned int num_devs = 0;

		ret = 0;
		dmsg = (struct audio_thread_dump_debug_info_msg *)msg;
		info = dmsg->info;

		/* Go through all open devices. */
		DL_FOREACH (thread->open_devs[CRAS_STREAM_OUTPUT], adev) {
			append_dev_dump_info(&info->devs[num_devs], adev);
			if (++num_devs == MAX_DEBUG_DEVS)
				break;
			DL_FOREACH (adev->dev->streams, curr) {
				if (num_streams == MAX_DEBUG_STREAMS)
					break;
				append_stream_dump_info(info, curr,
							adev->dev->info.idx,
							num_streams++);
			}
		}
		DL_FOREACH (thread->open_devs[CRAS_STREAM_INPUT], adev) {
			if (num_devs == MAX_DEBUG_DEVS)
				break;
			append_dev_dump_info(&info->devs[num_devs], adev);
			DL_FOREACH (adev->dev->streams, curr) {
				if (num_streams == MAX_DEBUG_STREAMS)
					break;
				append_stream_dump_info(info, curr,
							adev->dev->info.idx,
							num_streams++);
			}
			++num_devs;
		}
		info->num_devs = num_devs;

		info->num_streams = num_streams;

		memcpy(&info->log, atlog, sizeof(info->log));
		break;
	}
	case AUDIO_THREAD_DRAIN_STREAM: {
		struct audio_thread_add_rm_stream_msg *rmsg;

		rmsg = (struct audio_thread_add_rm_stream_msg *)msg;
		ret = thread_drain_stream(thread, rmsg->stream);
		break;
	}
	case AUDIO_THREAD_REMOVE_CALLBACK: {
		struct audio_thread_rm_callback_msg *rmsg;

		rmsg = (struct audio_thread_rm_callback_msg *)msg;
		audio_thread_rm_callback(rmsg->fd);
		break;
	}
	case AUDIO_THREAD_CONFIG_GLOBAL_REMIX: {
		struct audio_thread_config_global_remix *rmsg;
		void *rsp;

		/* Respond the pointer to the old remix converter, so it can be
		 * freed later in main thread. */
		rsp = (void *)thread->remix_converter;

		rmsg = (struct audio_thread_config_global_remix *)msg;
		thread->remix_converter = rmsg->fmt_conv;

		return write(thread->to_main_fds[1], &rsp, sizeof(rsp));
	}
	case AUDIO_THREAD_DEV_START_RAMP: {
		struct audio_thread_dev_start_ramp_msg *rmsg;

		rmsg = (struct audio_thread_dev_start_ramp_msg *)msg;
		ret = thread_dev_start_ramp(thread, rmsg->dev_idx,
					    rmsg->request);
		break;
	}
	case AUDIO_THREAD_AEC_DUMP: {
		struct audio_thread_aec_dump_msg *rmsg;
		rmsg = (struct audio_thread_aec_dump_msg *)msg;
		ret = thread_set_aec_dump(thread, rmsg->stream_id, rmsg->start,
					  rmsg->fd);
		break;
	}
	default:
		ret = -EINVAL;
		break;
	}

	err = audio_thread_send_response(thread, ret);
	if (err < 0)
		return err;
	return 0;
}

/* Returns the number of active streams plus the number of active devices. */
static int fill_next_sleep_interval(struct audio_thread *thread,
				    struct timespec *ts)
{
	struct timespec min_ts;
	struct timespec now;
	int ret;

	ts->tv_sec = 0;
	ts->tv_nsec = 0;
	/* Limit the sleep time to 20 seconds. */
	min_ts.tv_sec = 20;
	min_ts.tv_nsec = 0;
	clock_gettime(CLOCK_MONOTONIC_RAW, &now);
	add_timespecs(&min_ts, &now);
	ret = dev_io_next_output_wake(&thread->open_devs[CRAS_STREAM_OUTPUT],
				      &min_ts);
	ret += dev_io_next_input_wake(&thread->open_devs[CRAS_STREAM_INPUT],
				      &min_ts);
	if (timespec_after(&min_ts, &now))
		subtract_timespecs(&min_ts, &now, ts);

	return ret;
}

static struct pollfd *add_pollfd(struct audio_thread *thread, int fd,
				 int events)
{
	thread->pollfds[thread->num_pollfds].fd = fd;
	thread->pollfds[thread->num_pollfds].events = events;
	thread->num_pollfds++;
	if (thread->num_pollfds >= thread->pollfds_size) {
		thread->pollfds_size *= 2;
		thread->pollfds = (struct pollfd *)realloc(
			thread->pollfds,
			sizeof(*thread->pollfds) * thread->pollfds_size);
		return NULL;
	}

	return &thread->pollfds[thread->num_pollfds - 1];
}

static int continuous_zero_sleep_count = 0;
static unsigned busyloop_count = 0;

/*
 * Logs the number of busyloop during one audio thread running state
 * (wait_ts != NULL).
 */
static void log_busyloop(struct timespec *wait_ts)
{
	static struct timespec start_time;
	static bool started = false;
	struct timespec diff, now;

	/* If wait_ts is NULL, there is no stream running. */
	if (wait_ts && !started) {
		started = true;
		busyloop_count = 0;
		clock_gettime(CLOCK_MONOTONIC_RAW, &start_time);
	} else if (!wait_ts && started) {
		started = false;
		clock_gettime(CLOCK_MONOTONIC_RAW, &now);
		subtract_timespecs(&now, &start_time, &diff);
		cras_server_metrics_busyloop(&diff, busyloop_count);
	}
}

static void check_busyloop(struct timespec *wait_ts)
{
	if (wait_ts->tv_sec == 0 && wait_ts->tv_nsec == 0) {
		continuous_zero_sleep_count++;
		if (continuous_zero_sleep_count ==
		    MAX_CONTINUOUS_ZERO_SLEEP_COUNT) {
			busyloop_count++;
			cras_audio_thread_event_busyloop();
		}
		if (continuous_zero_sleep_count ==
		    MAX_CONTINUOUS_ZERO_SLEEP_METRIC_LIMIT)
			cras_server_metrics_busyloop_length(
				continuous_zero_sleep_count);

	} else {
		if (continuous_zero_sleep_count >=
			    MAX_CONTINUOUS_ZERO_SLEEP_COUNT &&
		    continuous_zero_sleep_count <
			    MAX_CONTINUOUS_ZERO_SLEEP_METRIC_LIMIT)
			cras_server_metrics_busyloop_length(
				continuous_zero_sleep_count);
		continuous_zero_sleep_count = 0;
	}
}

/* For playback, fill the audio buffer when needed, for capture, pull out
 * samples when they are ready.
 * This thread will attempt to run at a high priority to allow for low latency
 * streams.  This thread sleeps while the device plays back or captures audio,
 * it will wake up as little as it can while avoiding xruns.  It can also be
 * woken by sending it a message using the "audio_thread_post_message" function.
 */
static void *audio_io_thread(void *arg)
{
	struct audio_thread *thread = (struct audio_thread *)arg;
	struct open_dev *adev;
	struct dev_stream *curr;
	struct timespec ts;
	int msg_fd;
	int rc;

	msg_fd = thread->to_thread_fds[0];

	/* Attempt to get realtime scheduling */
	if (cras_set_rt_scheduling(CRAS_SERVER_RT_THREAD_PRIORITY) == 0)
		cras_set_thread_priority(CRAS_SERVER_RT_THREAD_PRIORITY);

	thread->pollfds[0].fd = msg_fd;
	thread->pollfds[0].events = POLLIN;

	while (1) {
		struct timespec *wait_ts;
		struct iodev_callback_list *iodev_cb;
		int non_empty;

		wait_ts = NULL;
		thread->num_pollfds = 1;

		/* device opened */
		dev_io_run(&thread->open_devs[CRAS_STREAM_OUTPUT],
			   &thread->open_devs[CRAS_STREAM_INPUT],
			   thread->remix_converter);

		non_empty = dev_io_check_non_empty_state_transition(
			thread->open_devs[CRAS_STREAM_OUTPUT]);

		if (fill_next_sleep_interval(thread, &ts))
			wait_ts = &ts;

	restart_poll_loop:
		thread->num_pollfds = 1;

		DL_FOREACH (iodev_callbacks, iodev_cb) {
			if (iodev_cb->trigger != TRIGGER_POLL) {
				iodev_cb->pollfd = NULL;
				continue;
			}
			iodev_cb->pollfd = add_pollfd(thread, iodev_cb->fd,
						      iodev_cb->events);
			if (!iodev_cb->pollfd)
				goto restart_poll_loop;
		}

		/* TODO(dgreid) - once per rstream not per dev_stream */
		DL_FOREACH (thread->open_devs[CRAS_STREAM_OUTPUT], adev) {
			DL_FOREACH (adev->dev->streams, curr) {
				int fd = dev_stream_poll_stream_fd(curr);
				if (fd < 0)
					continue;
				if (!add_pollfd(thread, fd, POLLIN))
					goto restart_poll_loop;
			}
		}
		DL_FOREACH (thread->open_devs[CRAS_STREAM_INPUT], adev) {
			DL_FOREACH (adev->dev->streams, curr) {
				int fd = dev_stream_poll_stream_fd(curr);
				if (fd < 0)
					continue;
				if (!add_pollfd(thread, fd, POLLIN))
					goto restart_poll_loop;
			}
		}

		log_busyloop(wait_ts);

		ATLOG(atlog, AUDIO_THREAD_SLEEP, wait_ts ? wait_ts->tv_sec : 0,
		      wait_ts ? wait_ts->tv_nsec : 0, non_empty);
		if (wait_ts)
			check_busyloop(wait_ts);

		/* Sync atlog with shared memory. */
		__sync_synchronize();
		atlog->sync_write_pos = atlog->write_pos;

		rc = ppoll(thread->pollfds, thread->num_pollfds, wait_ts, NULL);
		ATLOG(atlog, AUDIO_THREAD_WAKE, rc, 0, 0);

		/* Handle callbacks registered by TRIGGER_WAKEUP */
		DL_FOREACH (iodev_callbacks, iodev_cb) {
			if (iodev_cb->trigger == TRIGGER_WAKEUP) {
				ATLOG(atlog, AUDIO_THREAD_IODEV_CB, 0, 0, 0);
				iodev_cb->cb(iodev_cb->cb_data, 0);
			}
		}

		/* If there's no pollfd ready to handle. */
		if (rc <= 0)
			continue;

		if (thread->pollfds[0].revents & POLLIN) {
			rc = handle_audio_thread_message(thread);
			if (rc < 0)
				syslog(LOG_ERR, "handle message %d", rc);
		}

		DL_FOREACH (iodev_callbacks, iodev_cb) {
			if (iodev_cb->pollfd &&
			    iodev_cb->pollfd->revents & iodev_cb->events) {
				ATLOG(atlog, AUDIO_THREAD_IODEV_CB,
				      iodev_cb->pollfd->revents,
				      iodev_cb->events, 0);
				iodev_cb->cb(iodev_cb->cb_data,
					     iodev_cb->pollfd->revents);
			}
		}
	}

	return NULL;
}

/* Write a message to the playback thread and wait for an ack, This keeps these
 * operations synchronous for the main server thread.  For instance when the
 * RM_STREAM message is sent, the stream can be deleted after the function
 * returns.  Making this synchronous also allows the thread to return an error
 * code that can be handled by the caller.
 * Args:
 *    thread - thread to receive message.
 *    msg - The message to send.
 * Returns:
 *    A return code from the message handler in the thread.
 */
static int audio_thread_post_message(struct audio_thread *thread,
				     struct audio_thread_msg *msg)
{
	int err, rsp;

	err = write(thread->to_thread_fds[1], msg, msg->length);
	if (err < 0) {
		syslog(LOG_ERR, "Failed to post message to thread.");
		return err;
	}
	/* Synchronous action, wait for response. */
	err = read_until_finished(thread->to_main_fds[0], &rsp, sizeof(rsp));
	if (err < 0) {
		syslog(LOG_ERR, "Failed to read reply from thread.");
		return err;
	}

	return rsp;
}

static void init_open_device_msg(struct audio_thread_open_device_msg *msg,
				 enum AUDIO_THREAD_COMMAND id,
				 struct cras_iodev *dev)
{
	memset(msg, 0, sizeof(*msg));
	msg->header.id = id;
	msg->header.length = sizeof(*msg);
	msg->dev = dev;
}

static void init_rm_device_msg(struct audio_thread_rm_device_msg *msg,
			       enum CRAS_STREAM_DIRECTION dir,
			       unsigned int dev_idx)
{
	memset(msg, 0, sizeof(*msg));
	msg->header.id = AUDIO_THREAD_RM_OPEN_DEV;
	msg->header.length = sizeof(*msg);
	msg->dir = dir;
	msg->dev_idx = dev_idx;
}

static void 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)
{
	memset(msg, 0, sizeof(*msg));
	msg->header.id = id;
	msg->header.length = sizeof(*msg);
	msg->stream = stream;
	msg->devs = devs;
	msg->num_devs = num_devs;
}

static void
init_dump_debug_info_msg(struct audio_thread_dump_debug_info_msg *msg,
			 struct audio_debug_info *info)
{
	memset(msg, 0, sizeof(*msg));
	msg->header.id = AUDIO_THREAD_DUMP_THREAD_INFO;
	msg->header.length = sizeof(*msg);
	msg->info = info;
}

static void
init_config_global_remix_msg(struct audio_thread_config_global_remix *msg)
{
	memset(msg, 0, sizeof(*msg));
	msg->header.id = AUDIO_THREAD_CONFIG_GLOBAL_REMIX;
	msg->header.length = sizeof(*msg);
}

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)
{
	memset(msg, 0, sizeof(*msg));
	msg->header.id = id;
	msg->header.length = sizeof(*msg);
	msg->dev_idx = dev_idx;
	msg->request = request;
}

/* Exported Interface */

int audio_thread_event_log_shm_fd()
{
	return atlog_ro_shm_fd;
}

int audio_thread_add_stream(struct audio_thread *thread,
			    struct cras_rstream *stream,
			    struct cras_iodev **devs, unsigned int num_devs)
{
	struct audio_thread_add_rm_stream_msg msg;

	assert(thread && stream);

	if (!thread->started)
		return -EINVAL;

	init_add_rm_stream_msg(&msg, AUDIO_THREAD_ADD_STREAM, stream, devs,
			       num_devs);
	return audio_thread_post_message(thread, &msg.header);
}

int audio_thread_disconnect_stream(struct audio_thread *thread,
				   struct cras_rstream *stream,
				   struct cras_iodev *dev)
{
	struct audio_thread_add_rm_stream_msg msg;

	assert(thread && stream);

	init_add_rm_stream_msg(&msg, AUDIO_THREAD_DISCONNECT_STREAM, stream,
			       &dev, 0);
	return audio_thread_post_message(thread, &msg.header);
}

int audio_thread_drain_stream(struct audio_thread *thread,
			      struct cras_rstream *stream)
{
	struct audio_thread_add_rm_stream_msg msg;

	assert(thread && stream);

	init_add_rm_stream_msg(&msg, AUDIO_THREAD_DRAIN_STREAM, stream, NULL,
			       0);
	return audio_thread_post_message(thread, &msg.header);
}

int audio_thread_dump_thread_info(struct audio_thread *thread,
				  struct audio_debug_info *info)
{
	struct audio_thread_dump_debug_info_msg msg;

	init_dump_debug_info_msg(&msg, info);
	return audio_thread_post_message(thread, &msg.header);
}

int audio_thread_set_aec_dump(struct audio_thread *thread,
			      cras_stream_id_t stream_id, unsigned int start,
			      int fd)
{
	struct audio_thread_aec_dump_msg msg;

	memset(&msg, 0, sizeof(msg));
	msg.header.id = AUDIO_THREAD_AEC_DUMP;
	msg.header.length = sizeof(msg);
	msg.stream_id = stream_id;
	msg.start = start;
	msg.fd = fd;
	return audio_thread_post_message(thread, &msg.header);
}

int audio_thread_rm_callback_sync(struct audio_thread *thread, int fd)
{
	struct audio_thread_rm_callback_msg msg;

	memset(&msg, 0, sizeof(msg));
	msg.header.id = AUDIO_THREAD_REMOVE_CALLBACK;
	msg.header.length = sizeof(msg);
	msg.fd = fd;

	return audio_thread_post_message(thread, &msg.header);
}

int audio_thread_config_global_remix(struct audio_thread *thread,
				     unsigned int num_channels,
				     const float *coefficient)
{
	int err;
	int identity_remix = 1;
	unsigned int i, j;
	struct audio_thread_config_global_remix msg;
	void *rsp;

	init_config_global_remix_msg(&msg);

	/* Check if the coefficients represent an identity matrix for remix
	 * conversion, which means no remix at all. If so then leave the
	 * converter as NULL. */
	for (i = 0; i < num_channels; i++) {
		if (coefficient[i * num_channels + i] != 1.0f) {
			identity_remix = 0;
			break;
		}
		for (j = i + 1; j < num_channels; j++) {
			if (coefficient[i * num_channels + j] != 0 ||
			    coefficient[j * num_channels + i] != 0) {
				identity_remix = 0;
				break;
			}
		}
	}

	if (!identity_remix) {
		msg.fmt_conv = cras_channel_remix_conv_create(num_channels,
							      coefficient);
		if (NULL == msg.fmt_conv)
			return -ENOMEM;
	}

	err = write(thread->to_thread_fds[1], &msg, msg.header.length);
	if (err < 0) {
		syslog(LOG_ERR, "Failed to post message to thread.");
		return err;
	}
	/* Synchronous action, wait for response. */
	err = read_until_finished(thread->to_main_fds[0], &rsp, sizeof(rsp));
	if (err < 0) {
		syslog(LOG_ERR, "Failed to read reply from thread.");
		return err;
	}

	if (rsp)
		cras_fmt_conv_destroy((struct cras_fmt_conv **)&rsp);
	return 0;
}

struct audio_thread *audio_thread_create()
{
	int rc;
	struct audio_thread *thread;

	thread = (struct audio_thread *)calloc(1, sizeof(*thread));
	if (!thread)
		return NULL;

	thread->to_thread_fds[0] = -1;
	thread->to_thread_fds[1] = -1;
	thread->to_main_fds[0] = -1;
	thread->to_main_fds[1] = -1;

	/* Two way pipes for communication with the device's audio thread. */
	rc = pipe(thread->to_thread_fds);
	if (rc < 0) {
		syslog(LOG_ERR, "Failed to pipe");
		free(thread);
		return NULL;
	}
	rc = pipe(thread->to_main_fds);
	if (rc < 0) {
		syslog(LOG_ERR, "Failed to pipe");
		free(thread);
		return NULL;
	}

	if (asprintf(&atlog_name, "/ATlog-%d", getpid()) < 0) {
		syslog(LOG_ERR, "Failed to generate ATlog name.");
		exit(-1);
	}

	atlog = audio_thread_event_log_init(atlog_name);

	thread->pollfds_size = 32;
	thread->pollfds = (struct pollfd *)malloc(sizeof(*thread->pollfds) *
						  thread->pollfds_size);

	return thread;
}

int audio_thread_add_open_dev(struct audio_thread *thread,
			      struct cras_iodev *dev)
{
	struct audio_thread_open_device_msg msg;

	assert(thread && dev);

	if (!thread->started)
		return -EINVAL;

	init_open_device_msg(&msg, AUDIO_THREAD_ADD_OPEN_DEV, dev);
	return audio_thread_post_message(thread, &msg.header);
}

int audio_thread_rm_open_dev(struct audio_thread *thread,
			     enum CRAS_STREAM_DIRECTION dir,
			     unsigned int dev_idx)
{
	struct audio_thread_rm_device_msg msg;

	assert(thread);
	if (!thread->started)
		return -EINVAL;

	init_rm_device_msg(&msg, dir, dev_idx);
	return audio_thread_post_message(thread, &msg.header);
}

int audio_thread_is_dev_open(struct audio_thread *thread,
			     struct cras_iodev *dev)
{
	struct audio_thread_open_device_msg msg;

	if (!dev)
		return 0;

	init_open_device_msg(&msg, AUDIO_THREAD_IS_DEV_OPEN, dev);
	return audio_thread_post_message(thread, &msg.header);
}

int audio_thread_dev_start_ramp(struct audio_thread *thread,
				unsigned int dev_idx,
				enum CRAS_IODEV_RAMP_REQUEST request)
{
	struct audio_thread_dev_start_ramp_msg msg;

	assert(thread);

	if (!thread->started)
		return -EINVAL;

	init_device_start_ramp_msg(&msg, AUDIO_THREAD_DEV_START_RAMP, dev_idx,
				   request);
	return audio_thread_post_message(thread, &msg.header);
}

int audio_thread_start(struct audio_thread *thread)
{
	int rc;

	rc = pthread_create(&thread->tid, NULL, audio_io_thread, thread);
	if (rc) {
		syslog(LOG_ERR, "Failed pthread_create");
		return rc;
	}

	thread->started = 1;

	return 0;
}

void audio_thread_destroy(struct audio_thread *thread)
{
	if (thread->started) {
		struct audio_thread_msg msg;

		msg.id = AUDIO_THREAD_STOP;
		msg.length = sizeof(msg);
		audio_thread_post_message(thread, &msg);
		pthread_join(thread->tid, NULL);
	}

	free(thread->pollfds);

	audio_thread_event_log_deinit(atlog, atlog_name);
	free(atlog_name);

	if (thread->to_thread_fds[0] != -1) {
		close(thread->to_thread_fds[0]);
		close(thread->to_thread_fds[1]);
	}
	if (thread->to_main_fds[0] != -1) {
		close(thread->to_main_fds[0]);
		close(thread->to_main_fds[1]);
	}

	if (thread->remix_converter)
		cras_fmt_conv_destroy(&thread->remix_converter);

	free(thread);
}
