mirror of https://github.com/thesofproject/sof.git
notifier: handle new aggregate flag
Implements handling of new notifier aggregate flag. With this flag set the notifier will automatically use existing handle instead of creating a new one. It's helpful when we want to register only once for an event, but it's very hard to explicitly keep track of number of registrations. Signed-off-by: Tomasz Lauda <tomasz.lauda@linux.intel.com>
This commit is contained in:
parent
8d9e61f698
commit
b42234247b
|
@ -8,6 +8,7 @@
|
|||
#ifndef __SOF_LIB_NOTIFIER_H__
|
||||
#define __SOF_LIB_NOTIFIER_H__
|
||||
|
||||
#include <sof/bit.h>
|
||||
#include <sof/list.h>
|
||||
#include <sof/sof.h>
|
||||
#include <stdint.h>
|
||||
|
@ -17,6 +18,9 @@
|
|||
#define NOTIFIER_TARGET_CORE_LOCAL NOTIFIER_TARGET_CORE_MASK(cpu_get_id())
|
||||
#define NOTIFIER_TARGET_CORE_ALL_MASK 0xFFFFFFFF
|
||||
|
||||
/** \brief Notifier flags. */
|
||||
#define NOTIFIER_FLAG_AGGREGATE BIT(0)
|
||||
|
||||
enum notify_id {
|
||||
NOTIFIER_ID_CPU_FREQ = 0, /* struct clock_notify_data * */
|
||||
NOTIFIER_ID_SSP_FREQ, /* struct clock_notify_data * */
|
||||
|
|
|
@ -31,6 +31,7 @@ struct callback_handle {
|
|||
void *caller;
|
||||
void (*cb)(void *arg, enum notify_id, void *data);
|
||||
struct list_item list;
|
||||
uint32_t num_registrations;
|
||||
};
|
||||
|
||||
int notifier_register(void *receiver, void *caller, enum notify_id type,
|
||||
|
@ -42,6 +43,16 @@ int notifier_register(void *receiver, void *caller, enum notify_id type,
|
|||
|
||||
assert(type >= NOTIFIER_ID_CPU_FREQ && type < NOTIFIER_ID_COUNT);
|
||||
|
||||
/* Find already registered event of this type */
|
||||
if (flags & NOTIFIER_FLAG_AGGREGATE &&
|
||||
!list_is_empty(¬ify->list[type])) {
|
||||
handle = container_of((¬ify->list[type])->next,
|
||||
struct callback_handle, list);
|
||||
handle->num_registrations++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
handle = rzalloc(SOF_MEM_ZONE_SYS_RUNTIME, 0, SOF_MEM_CAPS_RAM,
|
||||
sizeof(*handle));
|
||||
|
||||
|
@ -53,6 +64,7 @@ int notifier_register(void *receiver, void *caller, enum notify_id type,
|
|||
handle->receiver = receiver;
|
||||
handle->caller = caller;
|
||||
handle->cb = cb;
|
||||
handle->num_registrations = 1;
|
||||
|
||||
list_item_prepend(&handle->list, ¬ify->list[type]);
|
||||
|
||||
|
@ -82,8 +94,10 @@ void notifier_unregister(void *receiver, void *caller, enum notify_id type)
|
|||
handle = container_of(wlist, struct callback_handle, list);
|
||||
if ((!receiver || handle->receiver == receiver) &&
|
||||
(!caller || handle->caller == caller)) {
|
||||
list_item_del(&handle->list);
|
||||
rfree(handle);
|
||||
if (!--handle->num_registrations) {
|
||||
list_item_del(&handle->list);
|
||||
rfree(handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue