Jinoh Kang (@iamahuman) commented about server/mapping.c:
+ { + for (index = 0; index < session.object_count; index++) + if (!session.shared->objects[index].obj.id) + break; + if (index == session.object_count) + { + if (grow_session_mapping()) return -1; + index = session.object_count++; + } + } + + SHARED_WRITE_BEGIN( &session.shared->objects[index], session_obj_t ) + { + shared->obj.id = ++session.last_object_id; + } + SHARED_WRITE_END; This will scan the entire objects array once the last index has been occupied (object\_count full).
Instead, how about replacing `object_count` with `last_object_index`? This field doesn't actually count valid objects anyway, since some objects in the middle could be freed later. Instead, I would keep track of the *last* object index and start from there. ```suggestion:-20+0 unsigned int index = session.last_object_index; for (;;) { index = (index + 1) % session.shared->object_capacity; if (!session.shared->objects[index].obj.id) { /* found a free index */ break; } /* check if we're back to the starting point */ if (index == session.last_object_index) { /* all slots exhausted; skip to first index to be allocated */ index = session.shared->object_capacity; break; } } while (index >= session.shared->object_capacity) { if (grow_session_mapping()) return -1; } session.last_object_index = index; SHARED_WRITE_BEGIN( &session.shared->objects[index], session_obj_t ) { assert(!shared->obj.id); shared->obj.id = ++session.last_object_id; } SHARED_WRITE_END; ``` Note that the following initialization is also required: ```c session.last_object_index = -1; ``` -- https://gitlab.winehq.org/wine/wine/-/merge_requests/3103#note_64987