diff --git a/benchmark/dgram/get-send-queue-info.js b/benchmark/dgram/get-send-queue-info.js new file mode 100644 index 00000000000000..448f09e6030a65 --- /dev/null +++ b/benchmark/dgram/get-send-queue-info.js @@ -0,0 +1,43 @@ +'use strict'; + +const common = require('../common.js'); +const dgram = require('dgram'); +const assert = require('assert'); + +const bench = common.createBenchmark(main, { + n: [5e6], + method: ['size', 'count'], +}, { + flags: ['--test-udp-no-try-send'], +}); + +function main({ n, method }) { + const server = dgram.createSocket('udp4'); + const client = dgram.createSocket('udp4'); + + server.bind(0, () => { + client.connect(server.address().port, () => { + // warm-up: keep packets unsent using --test-udp-no-try-send flag + for (let i = 0; i < 999; i++) client.send('Hello'); + + let size = 0; + let count = 0; + + bench.start(); + + if (method === 'size') { + for (let i = 0; i < n; ++i) size += client.getSendQueueSize(); + } else { + for (let i = 0; i < n; ++i) count += client.getSendQueueCount(); + } + + bench.end(n); + + client.close(); + server.close(); + + assert.ok(size >= 0); + assert.ok(count >= 0); + }); + }); +} diff --git a/src/udp_wrap.cc b/src/udp_wrap.cc index 0821d07b5cde7c..89cd499673f2ec 100644 --- a/src/udp_wrap.cc +++ b/src/udp_wrap.cc @@ -29,6 +29,7 @@ #include "permission/permission.h" #include "req_wrap-inl.h" #include "util-inl.h" +#include "v8-fast-api-calls.h" namespace node { @@ -38,6 +39,7 @@ using v8::ArrayBuffer; using v8::BackingStore; using v8::BackingStoreInitializationMode; using v8::Boolean; +using v8::CFunction; using v8::Context; using v8::DontDelete; using v8::FunctionCallbackInfo; @@ -48,6 +50,7 @@ using v8::Isolate; using v8::Local; using v8::MaybeLocal; using v8::Object; +using v8::ObjectTemplate; using v8::PropertyAttribute; using v8::ReadOnly; using v8::Signature; @@ -74,6 +77,11 @@ void SetLibuvInt32(const FunctionCallbackInfo& args) { } } // namespace +static CFunction fast_get_send_queue_size_( + CFunction::Make(&UDPWrap::FastGetSendQueueSize)); +static CFunction fast_get_send_queue_count_( + CFunction::Make(&UDPWrap::FastGetSendQueueCount)); + class SendWrap : public ReqWrap { public: SendWrap(Environment* env, Local req_wrap_obj, bool have_callback); @@ -215,9 +223,20 @@ void UDPWrap::Initialize(Local target, isolate, t, "setBroadcast", SetLibuvInt32); SetProtoMethod(isolate, t, "setTTL", SetLibuvInt32); SetProtoMethod(isolate, t, "bufferSize", BufferSize); - SetProtoMethodNoSideEffect(isolate, t, "getSendQueueSize", GetSendQueueSize); - SetProtoMethodNoSideEffect( - isolate, t, "getSendQueueCount", GetSendQueueCount); + + Local instance = t->InstanceTemplate(); + + SetFastMethodNoSideEffect(isolate, + instance, + "getSendQueueSize", + GetSendQueueSize, + &fast_get_send_queue_size_); + + SetFastMethodNoSideEffect(isolate, + instance, + "getSendQueueCount", + GetSendQueueCount, + &fast_get_send_queue_count_); t->Inherit(HandleWrap::GetConstructorTemplate(env)); @@ -266,6 +285,8 @@ void UDPWrap::RegisterExternalReferences(ExternalReferenceRegistry* registry) { registry->Register(BufferSize); registry->Register(GetSendQueueSize); registry->Register(GetSendQueueCount); + registry->Register(fast_get_send_queue_size_); + registry->Register(fast_get_send_queue_count_); } void UDPWrap::New(const FunctionCallbackInfo& args) { @@ -668,6 +689,19 @@ ReqWrap* UDPWrap::CreateSendWrap(size_t msg_size) { return req_wrap; } +double UDPWrap::FastGetSendQueueSize(Local receiver) { + UDPWrap* wrap = BaseObject::Unwrap(receiver.As()); + if (wrap == nullptr) return static_cast(UV_EBADF); + return static_cast( + uv_udp_get_send_queue_size(wrap->GetLibuvHandle())); +} + +double UDPWrap::FastGetSendQueueCount(Local receiver) { + UDPWrap* wrap = BaseObject::Unwrap(receiver.As()); + if (wrap == nullptr) return static_cast(UV_EBADF); + return static_cast( + uv_udp_get_send_queue_count(wrap->GetLibuvHandle())); +} void UDPWrap::Send(const FunctionCallbackInfo& args) { DoSend(args, AF_INET); diff --git a/src/udp_wrap.h b/src/udp_wrap.h index c0914dbf3a7f3f..a85f4034231842 100644 --- a/src/udp_wrap.h +++ b/src/udp_wrap.h @@ -152,6 +152,9 @@ class UDPWrap final : public HandleWrap, static void GetSendQueueCount( const v8::FunctionCallbackInfo& args); + static double FastGetSendQueueSize(v8::Local receiver); + static double FastGetSendQueueCount(v8::Local receiver); + // UDPListener implementation uv_buf_t OnAlloc(size_t suggested_size) override; void OnRecv(ssize_t nread,