#pragma once #include #include #include #include #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); /* 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