This commit cleans up the internals of wl_map by splitting it into two wl_simple_maps. This both makes the internals cleaner and also fixes potential issues with having a single free_list for both sides of the map.
Signed-off-by: Jason Ekstrand <ja...@jlekstrand.net> --- src/wayland-private.h | 10 ++- src/wayland-util.c | 172 ++++++++++++++++++++++++++------------------------ 2 files changed, 97 insertions(+), 85 deletions(-) diff --git a/src/wayland-private.h b/src/wayland-private.h index c4ce6b0..a733a96 100644 --- a/src/wayland-private.h +++ b/src/wayland-private.h @@ -41,12 +41,16 @@ #define WL_SERVER_ID_START 0xff000000 #define WL_CLOSURE_MAX_ARGS 20 -struct wl_map { - struct wl_array client_entries; - struct wl_array server_entries; +struct wl_simple_map { + struct wl_array entries; uint32_t free_list; }; +struct wl_map { + struct wl_simple_map client_map; + struct wl_simple_map server_map; +}; + typedef void (*wl_iterator_func_t)(void *element, void *data); void wl_map_init(struct wl_map *map); diff --git a/src/wayland-util.c b/src/wayland-util.c index 598ab42..b8831b8 100644 --- a/src/wayland-util.c +++ b/src/wayland-util.c @@ -151,102 +151,64 @@ union map_entry { void *data; }; -WL_EXPORT void -wl_map_init(struct wl_map *map) -{ - memset(map, 0, sizeof *map); -} - -WL_EXPORT void -wl_map_release(struct wl_map *map) -{ - wl_array_release(&map->client_entries); - wl_array_release(&map->server_entries); -} - -WL_EXPORT uint32_t -wl_map_insert_new(struct wl_map *map, uint32_t side, void *data) +static uint32_t +wl_simple_map_insert_new(struct wl_simple_map *map, void *data) { union map_entry *start, *entry; - struct wl_array *entries; - uint32_t base; - - if (side == WL_MAP_CLIENT_SIDE) { - entries = &map->client_entries; - base = 0; - } else { - entries = &map->server_entries; - base = WL_SERVER_ID_START; - } - if (map->free_list) { - start = entries->data; + start = map->entries.data; entry = &start[map->free_list >> 1]; map->free_list = entry->next; } else { - entry = wl_array_add(entries, sizeof *entry); + entry = wl_array_add(&map->entries, sizeof *entry); if (!entry) return 0; - start = entries->data; + start = map->entries.data; } entry->data = data; - return (entry - start) + base; + return (entry - start); } -WL_EXPORT int -wl_map_insert_at(struct wl_map *map, uint32_t i, void *data) +static int +wl_simple_map_insert_at(struct wl_simple_map *map, uint32_t i, void *data) { union map_entry *start; uint32_t count; - struct wl_array *entries; - - if (i < WL_SERVER_ID_START) { - entries = &map->client_entries; - } else { - entries = &map->server_entries; - i -= WL_SERVER_ID_START; - } - count = entries->size / sizeof *start; + count = map->entries.size / sizeof *start; if (count < i) return -1; if (count == i) - wl_array_add(entries, sizeof *start); + if (!wl_array_add(&map->entries, sizeof *start)) + return -1; - start = entries->data; + start = map->entries.data; start[i].data = data; return 0; } -WL_EXPORT int -wl_map_reserve_new(struct wl_map *map, uint32_t i) +static int +wl_simple_map_reserve_new(struct wl_simple_map *map, uint32_t i) { union map_entry *start; uint32_t count; - struct wl_array *entries; - if (i < WL_SERVER_ID_START) { - entries = &map->client_entries; - } else { - entries = &map->server_entries; - i -= WL_SERVER_ID_START; - } - - count = entries->size / sizeof *start; + count = map->entries.size / sizeof *start; if (count < i) return -1; if (count == i) { - wl_array_add(entries, sizeof *start); - start = entries->data; + if (!wl_array_add(&map->entries, sizeof *start)) + return -1; + start = map->entries.data; start[i].data = NULL; } else { - start = entries->data; + start = map->entries.data; if (start[i].data != NULL) { return -1; } @@ -255,40 +217,24 @@ wl_map_reserve_new(struct wl_map *map, uint32_t i) return 0; } -WL_EXPORT void -wl_map_remove(struct wl_map *map, uint32_t i) +static void +wl_simple_map_remove(struct wl_simple_map *map, uint32_t i) { union map_entry *start; - struct wl_array *entries; - if (i < WL_SERVER_ID_START) { - entries = &map->client_entries; - } else { - entries = &map->server_entries; - i -= WL_SERVER_ID_START; - } - - start = entries->data; + start = map->entries.data; start[i].next = map->free_list; map->free_list = (i << 1) | 1; } -WL_EXPORT void * -wl_map_lookup(struct wl_map *map, uint32_t i) +void * +wl_simple_map_lookup(struct wl_simple_map *map, uint32_t i) { union map_entry *start; uint32_t count; - struct wl_array *entries; - - if (i < WL_SERVER_ID_START) { - entries = &map->client_entries; - } else { - entries = &map->server_entries; - i -= WL_SERVER_ID_START; - } - start = entries->data; - count = entries->size / sizeof *start; + start = map->entries.data; + count = map->entries.size / sizeof *start; if (i < count && !(start[i].next & 1)) return start[i].data; @@ -296,6 +242,68 @@ wl_map_lookup(struct wl_map *map, uint32_t i) return NULL; } +WL_EXPORT void +wl_map_init(struct wl_map *map) +{ + memset(map, 0, sizeof *map); +} + +WL_EXPORT void +wl_map_release(struct wl_map *map) +{ + wl_array_release(&map->client_map.entries); + wl_array_release(&map->server_map.entries); +} + +WL_EXPORT uint32_t +wl_map_insert_new(struct wl_map *map, uint32_t side, void *data) +{ + if (side == WL_MAP_CLIENT_SIDE) + return wl_simple_map_insert_new(&map->client_map, data); + else + return wl_simple_map_insert_new(&map->server_map, data) + + WL_SERVER_ID_START; +} + +WL_EXPORT int +wl_map_insert_at(struct wl_map *map, uint32_t i, void *data) +{ + if (i < WL_SERVER_ID_START) + return wl_simple_map_insert_at(&map->client_map, i, data); + else + return wl_simple_map_insert_at(&map->server_map, + i - WL_SERVER_ID_START, data); +} + +WL_EXPORT int +wl_map_reserve_new(struct wl_map *map, uint32_t i) +{ + if (i < WL_SERVER_ID_START) + return wl_simple_map_reserve_new(&map->client_map, i); + else + return wl_simple_map_reserve_new(&map->server_map, + i - WL_SERVER_ID_START); +} + +WL_EXPORT void +wl_map_remove(struct wl_map *map, uint32_t i) +{ + if (i < WL_SERVER_ID_START) + wl_simple_map_remove(&map->client_map, i); + else + wl_simple_map_remove(&map->server_map, i - WL_SERVER_ID_START); +} + +WL_EXPORT void * +wl_map_lookup(struct wl_map *map, uint32_t i) +{ + if (i < WL_SERVER_ID_START) + return wl_simple_map_lookup(&map->client_map, i); + else + return wl_simple_map_lookup(&map->server_map, + i - WL_SERVER_ID_START); +} + static void for_each_helper(struct wl_array *entries, wl_iterator_func_t func, void *data) { @@ -312,8 +320,8 @@ for_each_helper(struct wl_array *entries, wl_iterator_func_t func, void *data) WL_EXPORT void wl_map_for_each(struct wl_map *map, wl_iterator_func_t func, void *data) { - for_each_helper(&map->client_entries, func, data); - for_each_helper(&map->server_entries, func, data); + for_each_helper(&map->client_map.entries, func, data); + for_each_helper(&map->server_map.entries, func, data); } static void -- 1.8.1.4 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel