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 <ja...@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 <ja...@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 > >
_______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel