Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3e9f240c authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "audio HAL: fix thread starvation"

parents 27fb4059 d53b669c
Loading
Loading
Loading
Loading
+34 −18
Original line number Diff line number Diff line
@@ -1162,6 +1162,20 @@ error_config:
    return ret;
}

void lock_input_stream(struct stream_in *in)
{
    pthread_mutex_lock(&in->pre_lock);
    pthread_mutex_lock(&in->lock);
    pthread_mutex_unlock(&in->pre_lock);
}

void lock_output_stream(struct stream_out *out)
{
    pthread_mutex_lock(&out->pre_lock);
    pthread_mutex_lock(&out->lock);
    pthread_mutex_unlock(&out->pre_lock);
}

/* must be called with out->lock locked */
static int send_offload_cmd_l(struct stream_out* out, int command)
{
@@ -1250,7 +1264,7 @@ static void *offload_thread_loop(void *context)
    prctl(PR_SET_NAME, (unsigned long)"Offload Callback", 0, 0, 0);

    ALOGV("%s", __func__);
    pthread_mutex_lock(&out->lock);
    lock_output_stream(out);
    for (;;) {
        struct offload_cmd *cmd = NULL;
        stream_callback_event_t event;
@@ -1329,7 +1343,7 @@ static void *offload_thread_loop(void *context)
            ALOGE("%s unknown command received: %d", __func__, cmd->cmd);
            break;
        }
        pthread_mutex_lock(&out->lock);
        lock_output_stream(out);
        out->offload_thread_blocked = false;
        pthread_cond_signal(&out->cond);
        if (send_callback && out->offload_callback) {
@@ -1361,7 +1375,7 @@ static int create_offload_callback_thread(struct stream_out *out)

static int destroy_offload_callback_thread(struct stream_out *out)
{
    pthread_mutex_lock(&out->lock);
    lock_output_stream(out);
    stop_compressed_output_l(out);
    send_offload_cmd_l(out, OFFLOAD_CMD_EXIT);

@@ -1814,7 +1828,7 @@ static int out_standby(struct audio_stream *stream)
        return 0;
    }

    pthread_mutex_lock(&out->lock);
    lock_output_stream(out);
    if (!out->standby) {
        if (adev->adm_deregister_stream)
            adev->adm_deregister_stream(adev->adm_data, out->handle);
@@ -1903,7 +1917,7 @@ static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
    err = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
    if (err >= 0) {
        val = atoi(value);
        pthread_mutex_lock(&out->lock);
        lock_output_stream(out);
        pthread_mutex_lock(&adev->lock);

        /*
@@ -1967,7 +1981,7 @@ static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
        pthread_mutex_unlock(&adev->lock);
    }
    if (is_offload_usecase(out->usecase)) {
        pthread_mutex_lock(&out->lock);
        lock_output_stream(out);
        parse_compress_metadata(out, parms);

        audio_extn_dts_create_state_notifier_node(out->usecase);
@@ -2123,7 +2137,7 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
    int snd_scard_state = get_snd_card_state(adev);
    ssize_t ret = 0;

    pthread_mutex_lock(&out->lock);
    lock_output_stream(out);

    if (SND_CARD_STATE_OFFLINE == snd_scard_state) {
        // increase written size during SSR to avoid mismatch
@@ -2268,7 +2282,7 @@ static int out_get_render_position(const struct audio_stream_out *stream,
    *dsp_frames = 0;
    if (is_offload_usecase(out->usecase)) {
        ssize_t ret = 0;
        pthread_mutex_lock(&out->lock);
        lock_output_stream(out);
        if (out->compr != NULL) {
            ret = compress_get_tstamp(out->compr, (unsigned long *)dsp_frames,
                    &out->sample_rate);
@@ -2327,7 +2341,7 @@ static int out_get_presentation_position(const struct audio_stream_out *stream,
    int ret = -1;
    unsigned long dsp_frames;

    pthread_mutex_lock(&out->lock);
    lock_output_stream(out);

    if (is_offload_usecase(out->usecase)) {
        if (out->compr != NULL) {
@@ -2379,7 +2393,7 @@ static int out_set_callback(struct audio_stream_out *stream,
    struct stream_out *out = (struct stream_out *)stream;

    ALOGV("%s", __func__);
    pthread_mutex_lock(&out->lock);
    lock_output_stream(out);
    out->offload_callback = callback;
    out->offload_cookie = cookie;
    pthread_mutex_unlock(&out->lock);
@@ -2393,7 +2407,7 @@ static int out_pause(struct audio_stream_out* stream)
    ALOGV("%s", __func__);
    if (is_offload_usecase(out->usecase)) {
        ALOGD("copl(%p):pause compress driver", out);
        pthread_mutex_lock(&out->lock);
        lock_output_stream(out);
        if (out->compr != NULL && out->offload_state == OFFLOAD_STATE_PLAYING) {
            struct audio_device *adev = out->dev;
            int snd_scard_state = get_snd_card_state(adev);
@@ -2421,7 +2435,7 @@ static int out_resume(struct audio_stream_out* stream)
    if (is_offload_usecase(out->usecase)) {
        ALOGD("copl(%p):resume compress driver", out);
        status = 0;
        pthread_mutex_lock(&out->lock);
        lock_output_stream(out);
        if (out->compr != NULL && out->offload_state == OFFLOAD_STATE_PAUSED) {
            struct audio_device *adev = out->dev;
            int snd_scard_state = get_snd_card_state(adev);
@@ -2446,7 +2460,7 @@ static int out_drain(struct audio_stream_out* stream, audio_drain_type_t type )
    int status = -ENOSYS;
    ALOGV("%s", __func__);
    if (is_offload_usecase(out->usecase)) {
        pthread_mutex_lock(&out->lock);
        lock_output_stream(out);
        if (type == AUDIO_DRAIN_EARLY_NOTIFY)
            status = send_offload_cmd_l(out, OFFLOAD_CMD_PARTIAL_DRAIN);
        else
@@ -2462,7 +2476,7 @@ static int out_flush(struct audio_stream_out* stream)
    ALOGV("%s", __func__);
    if (is_offload_usecase(out->usecase)) {
        ALOGD("copl(%p):calling compress flush", out);
        pthread_mutex_lock(&out->lock);
        lock_output_stream(out);
        stop_compressed_output_l(out);
        pthread_mutex_unlock(&out->lock);
        ALOGD("copl(%p):out of compress flush", out);
@@ -2534,7 +2548,7 @@ static int in_standby(struct audio_stream *stream)
        return status;
    }

    pthread_mutex_lock(&in->lock);
    lock_input_stream(in);
    if (!in->standby && in->is_st_session) {
        ALOGD("%s: sound trigger pcm stop lab", __func__);
        audio_extn_sound_trigger_stop_lab(in);
@@ -2579,7 +2593,7 @@ static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)

    if (!parms)
        goto error;
    pthread_mutex_lock(&in->lock);
    lock_input_stream(in);
    pthread_mutex_lock(&adev->lock);

    err = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_INPUT_SOURCE, value, sizeof(value));
@@ -2663,7 +2677,7 @@ static ssize_t in_read(struct audio_stream_in *stream, void *buffer,
    int i, ret = -1;
    int snd_scard_state = get_snd_card_state(adev);

    pthread_mutex_lock(&in->lock);
    lock_input_stream(in);

    if (in->is_st_session) {
        ALOGVV(" %s: reading on st session bytes=%zu", __func__, bytes);
@@ -2763,7 +2777,7 @@ static int add_remove_audio_effect(const struct audio_stream *stream,
    if (status != 0)
        return status;

    pthread_mutex_lock(&in->lock);
    lock_input_stream(in);
    pthread_mutex_lock(&in->dev->lock);
    if ((in->source == AUDIO_SOURCE_VOICE_COMMUNICATION) &&
            in->enable_aec != enable &&
@@ -2831,6 +2845,7 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
    }

    pthread_mutex_init(&out->lock, (const pthread_mutexattr_t *) NULL);
    pthread_mutex_init(&out->pre_lock, (const pthread_mutexattr_t *) NULL);
    pthread_cond_init(&out->cond, (const pthread_condattr_t *) NULL);

    if (devices == AUDIO_DEVICE_NONE)
@@ -3485,6 +3500,7 @@ static int adev_open_input_stream(struct audio_hw_device *dev,
        devices, &in->stream, handle, source);

    pthread_mutex_init(&in->lock, (const pthread_mutexattr_t *) NULL);
    pthread_mutex_init(&in->pre_lock, (const pthread_mutexattr_t *) NULL);

    in->stream.common.get_sample_rate = in_get_sample_rate;
    in->stream.common.set_sample_rate = in_set_sample_rate;
+2 −0
Original line number Diff line number Diff line
@@ -181,6 +181,7 @@ struct stream_app_type_cfg {
struct stream_out {
    struct audio_stream_out stream;
    pthread_mutex_t lock; /* see note below on mutex acquisition order */
    pthread_mutex_t pre_lock; /* acquire before lock to avoid DOS by playback thread */
    pthread_cond_t  cond;
    struct pcm_config config;
    struct compr_config compr_config;
@@ -225,6 +226,7 @@ struct stream_out {
struct stream_in {
    struct audio_stream_in stream;
    pthread_mutex_t lock; /* see note below on mutex acquisition order */
    pthread_mutex_t pre_lock; /* acquire before lock to avoid DOS by playback thread */
    struct pcm_config config;
    struct pcm *pcm;
    int standby;