osmo-remsim/src/slotmap.h

125 lines
3.8 KiB
C

#pragma once
#include <stdint.h>
#include <stdbool.h>
#include <pthread.h>
#include <osmocom/core/linuxlist.h>
#define REMSIM_SERVER 1
struct bank_slot {
uint16_t bank_id;
uint16_t slot_nr;
};
static inline bool bank_slot_equals(const struct bank_slot *a, const struct bank_slot *b)
{
if (a->bank_id == b->bank_id && a->slot_nr == b->slot_nr)
return true;
else
return false;
}
struct client_slot {
uint16_t client_id;
uint16_t slot_nr;
};
static inline bool client_slot_equals(const struct client_slot *a, const struct client_slot *b)
{
if (a->client_id == b->client_id && a->slot_nr == b->slot_nr)
return true;
else
return false;
}
enum slot_mapping_state {
SLMAP_S_NEW, /* created; not yet sent to bankd */
SLMAP_S_UNACKNOWLEDGED, /* created + sent to bankd but not yet acknowledge by bankd */
SLMAP_S_ACTIVE, /* fully active map; acknowledged by bankd */
SLMAP_S_DELETE_REQ, /* fully active map; REST has requested deletion */
SLMAP_S_DELETING, /* RSPRO has issued Remove to bankd, but bankd hasn't confirmed yet */
};
extern const struct value_string slot_map_state_name[];
static inline const char *slotmap_state_name(enum slot_mapping_state st)
{
return get_value_string(slot_map_state_name, st);
}
/* slot mappings are created / removed by the server */
struct slot_mapping {
/* global lits of bankd slot mappings */
struct llist_head list;
struct slotmaps *maps;
/* slot on bank side */
struct bank_slot bank;
/* slot on client side */
struct client_slot client;
#ifdef REMSIM_SERVER
struct llist_head bank_list;
enum slot_mapping_state state;
#endif
};
/* collection of slot mappings */
struct slotmaps {
struct llist_head mappings;
pthread_rwlock_t rwlock;
};
uint32_t slotmap_get_id(const struct slot_mapping *map);
/* thread-safe lookup of map by client:slot */
struct slot_mapping *slotmap_by_client(struct slotmaps *maps, const struct client_slot *client);
/* thread-safe lookup of map by bank:slot */
struct slot_mapping *slotmap_by_bank(struct slotmaps *maps, const struct bank_slot *bank);
/* thread-safe creating of a new bank<->client map */
struct slot_mapping *slotmap_add(struct slotmaps *maps, const struct bank_slot *bank, const struct client_slot *client);
/* thread-safe removal of a bank<->client map */
void slotmap_del(struct slotmaps *maps, struct slot_mapping *map);
void _slotmap_del(struct slotmaps *maps, struct slot_mapping *map);
/* thread-safe removal of all bank<->client maps */
void slotmap_del_all(struct slotmaps *maps);
/* initialize the entire map collection */
struct slotmaps *slotmap_init(void *ctx);
#ifdef SLOTMAP_DEBUG
#define slotmaps_rdlock(maps) do { \
printf("%s:%u = slotmap_rdlock()\n", __FILE__, __LINE__); \
pthread_rwlock_rdlock(&(maps)->rwlock); \
} while (0)
#define slotmaps_wrlock(maps) do { \
printf("%s:%u = slotmap_wrlock()\n", __FILE__, __LINE__); \
pthread_rwlock_wrlock(&(maps)->rwlock); \
} while (0)
#define slotmaps_unlock(maps) do { \
printf("%s:%u = slotmap_unlock()\n", __FILE__, __LINE__); \
pthread_rwlock_unlock(&(maps)->rwlock); \
} while (0)
#else
#define slotmaps_rdlock(maps) pthread_rwlock_rdlock(&(maps)->rwlock)
#define slotmaps_wrlock(maps) pthread_rwlock_wrlock(&(maps)->rwlock)
#define slotmaps_unlock(maps) pthread_rwlock_unlock(&(maps)->rwlock)
#endif
#ifdef REMSIM_SERVER
void _Slotmap_state_change(struct slot_mapping *map, enum slot_mapping_state new_state,
struct llist_head *new_bank_list, const char *file, int line);
/* thread-safe way to change the state of given slot map */
void Slotmap_state_change(struct slot_mapping *map, enum slot_mapping_state new_state,
struct llist_head *new_bank_list, const char *file, int line);
#define _slotmap_state_change(map, state, list) \
_Slotmap_state_change(map, state, list, __FILE__, __LINE__)
#define slotmap_state_change(map, state, list) \
Slotmap_state_change(map, state, list, __FILE__, __LINE__)
#endif