[PATCH wayland] Clean up the internals of wl_map
Jason Ekstrand
jason at jlekstrand.net
Sat Jun 1 14:45:25 PDT 2013
Ignore these. Turns out I was trying to fix the wrong issue. New patches
to come
-- Jason Ekstrand
On Wed, May 29, 2013 at 10:06 PM, Jason Ekstrand <jason at jlekstrand.net>wrote:
> 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 <jason at jlekstrand.net>
> ---
>
> Ignore the previous patch as it contained an error. This one is the
> correct one.
>
> src/wayland-private.h | 10 ++-
> src/wayland-util.c | 177
> +++++++++++++++++++++++++++-----------------------
> 2 files changed, 102 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..10607d8 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,73 @@ 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)
> +{
> + uint32_t id;
> + if (side == WL_MAP_CLIENT_SIDE) {
> + return wl_simple_map_insert_new(&map->client_map, data);
> + } else {
> + id = wl_simple_map_insert_new(&map->server_map, data);
> + if (id == 0)
> + return 0;
> + else
> + return id + 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 +325,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
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/wayland-devel/attachments/20130601/ac857f61/attachment.html>
More information about the wayland-devel
mailing list