From bf13ecf7cf182d4a33de07d2258106bcf7c3e8b6 Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Wed, 12 Feb 2025 16:42:00 -0500 Subject: [PATCH] registrar: Avoid cloning buffers when delivering messages in most cases. If we succeed in sending the message on the first try, then we don't need to allocate anything at all. This two allocations and a memcpy in the fast path (which is hit the vast majority of the time, it appears.) --- src/servers/registrar/MessageDeliverer.cpp | 35 ++++++++++++---------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/src/servers/registrar/MessageDeliverer.cpp b/src/servers/registrar/MessageDeliverer.cpp index 4ba6737a5e..4d092c9517 100644 --- a/src/servers/registrar/MessageDeliverer.cpp +++ b/src/servers/registrar/MessageDeliverer.cpp @@ -640,19 +640,7 @@ MessageDeliverer::DeliverMessage(const void *messageData, int32 messageSize, if (!messageData || messageSize <= 0) return B_BAD_VALUE; - // clone the buffer - void *data = malloc(messageSize); - if (!data) - return B_NO_MEMORY; - memcpy(data, messageData, messageSize); - - // create a Message - Message *message = new(nothrow) Message(data, messageSize, timeout); - if (!message) { - free(data); - return B_NO_MEMORY; - } - BReference _(message, true); + BReference messageRef; // add the message to the respective target ports BAutolock locker(fLock); @@ -668,7 +656,8 @@ MessageDeliverer::DeliverMessage(const void *messageData, int32 messageSize, // try sending the message, if there are no queued messages yet if (port->IsEmpty()) { - status_t error = _SendMessage(message, portID, token); + status_t error = BMessage::Private::SendFlattenedMessage((void*)messageData, + messageSize, portID, token, 0); // if the message was delivered OK, we're done with the target if (error == B_OK) { _PutTargetPort(port); @@ -684,8 +673,24 @@ MessageDeliverer::DeliverMessage(const void *messageData, int32 messageSize, } } + if (!messageRef.IsSet()) { + // clone the buffer + void *data = malloc(messageSize); + if (!data) + return B_NO_MEMORY; + memcpy(data, messageData, messageSize); + + // create a Message + Message *message = new(nothrow) Message(data, messageSize, timeout); + if (!message) { + free(data); + return B_NO_MEMORY; + } + messageRef.SetTo(message, true); + } + // add the message - status_t error = port->PushMessage(message, token); + status_t error = port->PushMessage(messageRef, token); _PutTargetPort(port); if (error != B_OK) return error;