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:
Tomasz Lauda 2020-03-30 10:00:43 +02:00 committed by Janusz Jankowski
parent 8d9e61f698
commit b42234247b
2 changed files with 20 additions and 2 deletions

View File

@ -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 * */

View File

@ -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(&notify->list[type])) {
handle = container_of((&notify->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, &notify->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);
}
}
}
}