blob: 0bd547ba4249e0872800f1022ebae26fdb22e204 [file] [log] [blame]
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright 2019-2022 Google LLC
*/
#ifndef __GOOGLE_GVOTABLE_H_
#define __GOOGLE_GVOTABLE_H_
#include <linux/types.h>
#include <linux/mutex.h>
#define GVOTABLE_MAX_REASON_LEN 32
#define GVOTABLE_PTR_TO_INT(v) ((int)(uintptr_t)(v))
struct gvotable_election;
typedef int (*gvotable_cmp_fn)(void *a, void *b);
typedef int (*gvotable_callback_fn)(struct gvotable_election *el,
const char *reason,
void *vote);
struct gvotable_election *
gvotable_create_election(const char *name, int vote_size,
int (*cmp_fn)(void *, void *),
gvotable_callback_fn callback_fn,
void *data);
#define _GVOTABLE_EPC(a, ...) a ## __VA_ARGS__
#define GVOTABLE__ELECTION_HELPER(t) \
_GVOTABLE_EPC(_GVOTABLE_EPC(gvotable_create_, t)_election)(name, cmp_fn, cb_fn, data)
/* NOTE: cannot change the data after init to avoid adding a lock for it */
struct gvotable_election *
gvotable_create_int_election(const char *name, gvotable_cmp_fn cmp_fn,
gvotable_callback_fn callback_fn,
void *data);
struct gvotable_election *
gvotable_create_bool_election(const char *name, gvotable_callback_fn cb_fn,
void *data);
int gvotable_destroy_election(struct gvotable_election *el);
struct gvotable_election *gvotable_election_get_handle(const char *name);
/* TODO: redesign this API */
typedef int (*gvotable_foreach_callback_fn)(void *data, const char *reason,
void *vote);
int gvotable_election_for_each(struct gvotable_election *el,
gvotable_foreach_callback_fn callback_fn,
void *callback_data);
int gvotable_election_set_result(struct gvotable_election *el,
const char *reason, void *vote);
void *gvotable_get_data(struct gvotable_election *el);
int gvotable_get_current_reason(struct gvotable_election *el, char *reason,
int max_reason_len);
int gvotable_set_default(struct gvotable_election *el, void *default_val);
int gvotable_get_default(struct gvotable_election *el, void **default_val);
int gvotable_election_set_name(struct gvotable_election *el, const char *name);
int gvotable_use_default(struct gvotable_election *el, bool default_is_enabled);
int gvotable_cast_vote(struct gvotable_election *el, const char *reason,
void *vote, bool enabled);
static inline int gvotable_cast_int_vote(struct gvotable_election *el,
const char *reason, int vote,
bool enabled)
{
return gvotable_cast_vote(el, reason, (void *)(long)vote, enabled);
}
static inline int gvotable_cast_long_vote(struct gvotable_election *el,
const char *reason, long vote,
bool enabled)
{
return gvotable_cast_vote(el, reason, (void *)vote, enabled);
}
static inline int gvotable_cast_bool_vote(struct gvotable_election *el,
const char *reason, bool vote)
{
return gvotable_cast_vote(el, reason, 0, vote);
}
int gvotable_recast_ballot(struct gvotable_election *el, const char *reason,
bool enabled);
int gvotable_run_election(struct gvotable_election *el, bool force_callback);
int gvotable_get_vote(struct gvotable_election *el, const char *reason,
void **vote);
int gvotable_get_int_vote(struct gvotable_election *el, const char *reason);
int gvotable_is_enabled(struct gvotable_election *el, const char *reason,
bool *enabled);
int gvotable_get_current_int_vote(struct gvotable_election *el);
int gvotable_get_current_vote(struct gvotable_election *el, const void **vote);
int gvotable_copy_current_result(struct gvotable_election *el, void *vote,
int vote_size);
int gvotable_comparator_uint_max(void *a, void *b);
int gvotable_comparator_uint_min(void *a, void *b);
int gvotable_comparator_int_max(void *a, void *b);
int gvotable_comparator_int_min(void *a, void *b);
int gvotable_comparator_most_recent(void *a, void *b);
int gvotable_comparator_least_recent(void *a, void *b);
/* dump, debug */
typedef int (*gvotable_v2sfn_t)(char *str, size_t len, const void *);
int gvotable_v2s_int(char *str, size_t len, const void *vote);
int gvotable_v2s_uint(char *str, size_t len, const void *vote);
int gvotable_v2s_uint_hex(char *str, size_t len, const void *vote);
void gvotable_set_vote2str(struct gvotable_election *el,
gvotable_v2sfn_t vote2str);
int gvotable_disable_force_int_entry(struct gvotable_election *el);
#endif /* __GOOGLE_GVOTABLE_H_*/