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

Commit cc81fd47 authored by Ravi Kumar Alamanda's avatar Ravi Kumar Alamanda Committed by Bruno Martins
Browse files

hal: Add support for perf lock management

Acquire perf lock before starting an input or output
stream to optimize the cold start latency.

Bug: 22537514

Cherry-pick of CAF commit:
390bcf3e

Change-Id: Iacedde8ff8531f8857e516e2671acd62197556a0
parent eb79ef40
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ ifneq ($(filter apq8084,$(TARGET_BOARD_PLATFORM)),)
endif
ifneq ($(filter msm8974,$(TARGET_BOARD_PLATFORM)),)
  LOCAL_CFLAGS := -DPLATFORM_MSM8974
  LOCAL_CFLAGS += -DKPI_OPTIMIZE_ENABLED
endif
endif

+73 −1
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@
 * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
 * Not a Contribution.
 *
 * Copyright (C) 2013 The Android Open Source Project
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -23,6 +23,7 @@

#include <stdlib.h>
#include <errno.h>
#include <dlfcn.h>
#include <cutils/properties.h>
#include <cutils/log.h>

@@ -461,3 +462,74 @@ int32_t audio_extn_read_xml(struct audio_device *adev, uint32_t mixer_card,
    return 0;
}
#endif /* AUXPCM_BT_ENABLED */


#ifdef KPI_OPTIMIZE_ENABLED
typedef int (*perf_lock_acquire_t)(int, int, int*, int);
typedef int (*perf_lock_release_t)(int);

static void *qcopt_handle;
static perf_lock_acquire_t perf_lock_acq;
static perf_lock_release_t perf_lock_rel;

static int perf_lock_handle;
char opt_lib_path[PROPERTY_VALUE_MAX] = {0};

int perf_lock_opts[] = {0x101, 0x20E, 0x30E};

int audio_extn_perf_lock_init(void)
{
    int ret = 0;
    if (qcopt_handle == NULL) {
        if (property_get("ro.vendor.extension_library",
                         opt_lib_path, NULL) <= 0) {
            ALOGE("%s: Failed getting perf property", __func__);
            ret = -EINVAL;
            goto err;
        }
        if ((qcopt_handle = dlopen(opt_lib_path, RTLD_NOW)) == NULL) {
            ALOGE("%s: Failed to open perf handle", __func__);
            ret = -EINVAL;
            goto err;
        } else {
            perf_lock_acq = (perf_lock_acquire_t)dlsym(qcopt_handle,
                                                       "perf_lock_acq");
            if (perf_lock_acq == NULL) {
                ALOGE("%s: Perf lock Acquire NULL", __func__);
                ret = -EINVAL;
                goto err;
            }
            perf_lock_rel = (perf_lock_release_t)dlsym(qcopt_handle,
                                                       "perf_lock_rel");
            if (perf_lock_rel == NULL) {
                ALOGE("%s: Perf lock Release NULL", __func__);
                ret = -EINVAL;
                goto err;
            }
            ALOGD("%s: Perf lock handles Success", __func__);
        }
    }
err:
    return ret;
}

void audio_extn_perf_lock_acquire(void)
{
    if (perf_lock_acq) {
        perf_lock_handle = perf_lock_acq(perf_lock_handle, 0, perf_lock_opts, 3);
        ALOGV("%s: Perf lock acquired", __func__);
    } else {
        ALOGE("%s: Perf lock acquire error", __func__);
    }
}

void audio_extn_perf_lock_release(void)
{
    if (perf_lock_rel && perf_lock_handle) {
        perf_lock_rel(perf_lock_handle);
        ALOGV("%s: Perf lock released", __func__);
    } else {
        ALOGE("%s: Perf lock release error", __func__);
    }
}
#endif /* KPI_OPTIMIZE_ENABLED */
+9 −0
Original line number Diff line number Diff line
@@ -252,4 +252,13 @@ audio_usecase_t audio_extn_hfp_get_usecase();
bool audio_extn_hfp_is_active(struct audio_device *adev);
#endif

#ifndef KPI_OPTIMIZE_ENABLED
#define audio_extn_perf_lock_init() (0)
#define audio_extn_perf_lock_acquire() (0)
#define audio_extn_perf_lock_release() (0)
#else
int audio_extn_perf_lock_init(void);
void audio_extn_perf_lock_acquire(void);
void audio_extn_perf_lock_release(void);
#endif /* KPI_OPTIMIZE_ENABLED */
#endif /* AUDIO_EXTN_H */
+12 −0
Original line number Diff line number Diff line
@@ -1109,6 +1109,9 @@ int start_input_stream(struct stream_in *in)
    uc_info->out_snd_device = SND_DEVICE_NONE;

    list_add_tail(&adev->usecase_list, &uc_info->list);

    audio_extn_perf_lock_acquire();

    select_devices(adev, in->usecase);

    ALOGV("%s: Opening PCM device card_id(%d) device_id(%d), channels %d",
@@ -1141,11 +1144,14 @@ int start_input_stream(struct stream_in *in)
        break;
    }

    audio_extn_perf_lock_release();

    ALOGV("%s: exit", __func__);
    return ret;

error_open:
    stop_input_stream(in);
    audio_extn_perf_lock_release();

error_config:
    adev->active_input = NULL;
@@ -1553,6 +1559,8 @@ int start_output_stream(struct stream_out *out)

    list_add_tail(&adev->usecase_list, &uc_info->list);

    audio_extn_perf_lock_acquire();

    select_devices(adev, out->usecase);

    audio_extn_extspk_update(adev->extspk);
@@ -1620,9 +1628,11 @@ int start_output_stream(struct stream_out *out)
        if (adev->offload_effects_start_output != NULL)
            adev->offload_effects_start_output(out->handle, out->pcm_device_id);
    }
    audio_extn_perf_lock_release();
    ALOGV("%s: exit", __func__);
    return 0;
error_open:
    audio_extn_perf_lock_release();
    stop_output_stream(out);
error_config:
    return ret;
@@ -3849,6 +3859,8 @@ static int adev_open(const hw_module_t *module, const char *name,

    pthread_mutex_unlock(&adev_init_lock);

    audio_extn_perf_lock_init();

    ALOGV("%s: exit", __func__);
    return 0;
}