From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on gnuweeb.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=ALL_TRUSTED,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,NO_DNS_FOR_FROM,URIBL_BLOCKED autolearn=no autolearn_force=no version=3.4.6 Received: from localhost.localdomain (unknown [180.246.144.41]) by gnuweeb.org (Postfix) with ESMTPSA id AC89F8079D; Sun, 21 Aug 2022 11:25:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gnuweeb.org; s=default; t=1661081122; bh=sN0kYrOL43oef6abiQ4xD4Kn/9+3M/OeCaDuSLPIzq0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=fllITBkRzFQnJW6ZMXOQw58BL57ggZmNm/Lpv8k95iIUQqTPl9um/Pwtg/73gbRsl Xok3aX98XLkqzumSh9vTtMM4mOkGg5KvwRuw9g9e+AWxRmKLE58mQ2pCcGHkW5NZ7/ UmyAFQC/XC4+QtILb69p5JAZfwgiC1z+V8zf0gY/MVjoZESAfHNNKmZ+Sz2LnMJLYK G8rB1FDIv8Y0Nn3wJrrnqWx0AA3RUMGtS+05EdcSjx1hJk3iyrxq7C0Pe9mS/WW9RW ctuzK73kwynsExu4ylcEO2X7jtwWm6y9G8k8yjUclVY1pHOvBf6k5FcDkaYqIzyhQZ WCpFHHE9J/C4A== From: Ammar Faizi To: Alviro Iskandar Setiawan Cc: Ammar Faizi , Muhammad Rizki , Kanna Scarlet , GNU/Weeb Mailing List Subject: [PATCH v1 02/22] chnet: node: Add set_user_data support on SQE Date: Sun, 21 Aug 2022 18:24:33 +0700 Message-Id: <20220821112453.3026255-3-ammarfaizi2@gnuweeb.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220821112453.3026255-1-ammarfaizi2@gnuweeb.org> References: <20220821112453.3026255-1-ammarfaizi2@gnuweeb.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: Make it possible to track the corresponding SQE when we are iterating through the CQE. Signed-off-by: Ammar Faizi --- chnet/chnet_node.cc | 193 ++++++++++++++++++++++++++++++-------------- chnet/chnet_node.h | 6 -- 2 files changed, 131 insertions(+), 68 deletions(-) diff --git a/chnet/chnet_node.cc b/chnet/chnet_node.cc index 06f624e..7d0c6bc 100644 --- a/chnet/chnet_node.cc +++ b/chnet/chnet_node.cc @@ -1,16 +1,38 @@ #include "chnet_node.h" -#ifdef DEBUG_MODE -#define PR_DEBUG(...) \ -do { \ - printf("Debug: "); \ - printf(__VA_ARGS__); \ - putchar('\n'); \ -} while (0); -#else -#define PR_DEBUG(...) do { } while (0) -#endif +class NodeCHNetRing { +public: + inline NodeCHNetRing(uint32_t entry): + ring_(entry) + { + } + + CNRingCtx ring_; + Napi::ObjectReference ref_; +}; + +class NodeCNRingSQE { +public: + inline NodeCNRingSQE(NodeCHNetRing *ring, CNRingSQE *sqe) + { + sqe_ = sqe; + ring_ = ring; + } + + CNRingSQE *sqe_; + NodeCHNetRing *ring_; +}; + +struct NodeSQData { + uint32_t id_; + NodeCHNetRing *ring_; +}; + +class NodeCHNet { +public: + CHNet ch_; +}; static inline void throw_js_exception(Napi::Env &env, const char *err_msg) { @@ -24,18 +46,14 @@ static inline void obj_add_func(Napi::Env &env, Napi::Object &obj, obj[name] = Napi::Function::New(env, func, name, data); } -struct sqe_udata { - void *ptr; -}; - static void CHN_SQEPrepNop(const Napi::CallbackInfo &info) { - CNRingSQE *sqe = (CNRingSQE *)info.Data(); + NodeCNRingSQE *nsqe = (NodeCNRingSQE *)info.Data(); - sqe->PrepNop(); + nsqe->sqe_->PrepNop(); } -static CHNetNode *CHN_PrepGetCHObj(Napi::Env &env, const Napi::Value &arg) +static NodeCHNet *CHN_PrepGetCHObj(Napi::Env &env, const Napi::Value &arg) { Napi::Value ch_in_obj; Napi::Object obj; @@ -52,15 +70,15 @@ static CHNetNode *CHN_PrepGetCHObj(Napi::Env &env, const Napi::Value &arg) return nullptr; } - return (CHNetNode *)(uintptr_t) + return (NodeCHNet *)(uintptr_t) ch_in_obj.As().Int64Value(); } static void CHN_SQEPrepStart(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); - CNRingSQE *sqe; - CHNetNode *ch; + NodeCNRingSQE *nsqe; + NodeCHNet *ch; CHNet *chn; if (unlikely(info.Length() != 1 || !info[0].IsObject())) { @@ -73,16 +91,16 @@ static void CHN_SQEPrepStart(const Napi::CallbackInfo &info) return; chn = &ch->ch_; - sqe = (CNRingSQE *)info.Data(); - sqe->PrepStart(chn); + nsqe = (NodeCNRingSQE *)info.Data(); + nsqe->sqe_->PrepStart(chn); } static void CHN_SQEPrepRead(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); int32_t read_size; - CNRingSQE *sqe; - CHNetNode *ch; + NodeCNRingSQE *nsqe; + NodeCHNet *ch; CHNet *chn; if (unlikely(info.Length() != 2 || !info[0].IsObject() || @@ -97,69 +115,116 @@ static void CHN_SQEPrepRead(const Napi::CallbackInfo &info) read_size = info[1].As().Int32Value(); chn = &ch->ch_; - sqe = (CNRingSQE *)info.Data(); - sqe->PrepRead(chn, read_size); + nsqe = (NodeCNRingSQE *)info.Data(); + nsqe->sqe_->PrepRead(chn, read_size); } -static void CHN_SQESetUserData(const Napi::CallbackInfo &info) +static Napi::Value CHN_SQESetUserData(const Napi::CallbackInfo &info) { - (void)info; + static std::atomic count; + Napi::Env env = info.Env(); + struct NodeSQData *data; + NodeCNRingSQE *nsqe; + + if (unlikely(info.Length() != 1)) { + throw_js_exception(env, "sqe.set_user_data must be given exactly one argument"); + return env.Null(); + } + + nsqe = (NodeCNRingSQE *)info.Data(); + data = new struct NodeSQData; + data->ring_ = nsqe->ring_; + data->id_ = count++ & nsqe->ring_->ring_.cq_mask_; + nsqe->ring_->ref_.Get("__udata") + .As()[data->id_] = info[0]; + nsqe->sqe_->SetUserDataPtr(data); + return info[0]; } -static Napi::Object BuildSQEObject(Napi::Env &env, CNRingSQE *sqe) +static void CHN_SQEDestruct(Napi::Env env, NodeCNRingSQE *sqe) +{ + delete sqe; + (void)env; +} + +static Napi::Object BuildSQEObject(Napi::Env &env, NodeCHNetRing *ring, + CNRingSQE *sqe) { Napi::Object obj = Napi::Object::New(env); + NodeCNRingSQE *nsqe; - obj_add_func(env, obj, sqe, CHN_SQEPrepNop, "prep_nop"); - obj_add_func(env, obj, sqe, CHN_SQEPrepStart, "prep_start"); - obj_add_func(env, obj, sqe, CHN_SQEPrepRead, "prep_read"); - obj_add_func(env, obj, sqe, CHN_SQESetUserData, "set_user_data"); sqe->SetUserData(0); + nsqe = new NodeCNRingSQE(ring, sqe); + obj_add_func(env, obj, nsqe, CHN_SQEPrepNop, "prep_nop"); + obj_add_func(env, obj, nsqe, CHN_SQEPrepStart, "prep_start"); + obj_add_func(env, obj, nsqe, CHN_SQEPrepRead, "prep_read"); + obj_add_func(env, obj, nsqe, CHN_SQESetUserData, "set_user_data"); + obj.AddFinalizer(CHN_SQEDestruct, nsqe); return obj; } static Napi::Value CHN_RingGetSQE(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); - CNRingCtx *ring; + NodeCHNetRing *ring; CNRingSQE *sqe; - ring = (CNRingCtx *)info.Data(); - sqe = ring->GetSQE(); + ring = (NodeCHNetRing *)info.Data(); + sqe = ring->ring_.GetSQE(); if (unlikely(!sqe)) return env.Null(); - return BuildSQEObject(env, sqe); + return BuildSQEObject(env, ring, sqe); } static Napi::Value CHN_RingSubmitSQE(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); - CNRingCtx *ring; + NodeCHNetRing *ring; - ring = (CNRingCtx *)info.Data(); - return Napi::Number::New(env, ring->SubmitSQE()); + ring = (NodeCHNetRing *)info.Data(); + return Napi::Number::New(env, ring->ring_.SubmitSQE()); } static void CHN_RingWaitCQE(const Napi::CallbackInfo &info) { uint32_t to_wait; - CNRingCtx *ring; + NodeCHNetRing *ring; if (unlikely(info.Length() < 1 || !info[0].IsNumber())) to_wait = 1; else to_wait = info[0].ToNumber().Uint32Value(); - ring = (CNRingCtx *)info.Data(); - ring->WaitCQE(to_wait); + ring = (NodeCHNetRing *)info.Data(); + ring->ring_.WaitCQE(to_wait); +} + +static void CHN_CQEDestruct(Napi::Env env, NodeSQData *data) +{ + /* + * TODO(ammarfaizi2): Clean up user_data from the ring + * when it's no longer used. + */ + + // data->ring_->ref_.Get("__udata").As() + // .Delete(data->id_); + delete data; + (void)env; } static Napi::Object BuildCQEObject(Napi::Env &env, CNRingCQE *cqe) { Napi::Object obj = Napi::Object::New(env); + NodeSQData *data = (NodeSQData *) cqe->GetUserDataPtr(); obj["res"] = Napi::Number::New(env, cqe->res); + + if (data) { + obj["user_data"] = data->ring_->ref_.Get("__udata") + .As().Get(data->id_); + obj.AddFinalizer(CHN_CQEDestruct, data); + } return obj; } @@ -171,7 +236,7 @@ static Napi::Value CHN_RingForEachCQE(const Napi::CallbackInfo &info) Napi::Env env = info.Env(); Napi::Function callback; uint32_t head, i; - CNRingCtx *ring; + NodeCHNetRing *ring; CNRingCQE *cqe; if (unlikely(info.Length() != 1 || !info[0].IsFunction())) { @@ -182,8 +247,8 @@ static Napi::Value CHN_RingForEachCQE(const Napi::CallbackInfo &info) callback = info[0].As(); i = 0; - ring = (CNRingCtx *)info.Data(); - chnring_for_each_cqe(ring, head, cqe) { + ring = (NodeCHNetRing *)info.Data(); + chnring_for_each_cqe(&ring->ring_, head, cqe) { Napi::Object cqe_obj = BuildCQEObject(env, cqe); callback.Call({cqe_obj}); @@ -199,33 +264,35 @@ static void CHN_RingCQAdvance(const Napi::CallbackInfo &info) "ring.cq_advance must be given exactly an integer argument"; Napi::Env env = info.Env(); - CNRingCtx *ring; + NodeCHNetRing *ring; if (unlikely(info.Length() < 1 || !info[0].IsNumber())) { throw_js_exception(env, err_msg); return; } - ring = (CNRingCtx *)info.Data(); - ring->CQAdvance(info[0].ToNumber().Uint32Value()); + ring = (NodeCHNetRing *)info.Data(); + ring->ring_.CQAdvance(info[0].ToNumber().Uint32Value()); } -static void CHN_RingDestruct(Napi::Env env, CNRingCtx *ring) +static void CHN_RingDestruct(Napi::Env env, NodeCHNetRing *ring) { delete ring; (void)env; } -static inline Napi::Value _CHN_CreateRing(Napi::Env &env, CNRingCtx *ring) +static inline Napi::Value _CHN_CreateRing(Napi::Env &env, NodeCHNetRing *ring) { Napi::Object obj = Napi::Object::New(env); + obj["__udata"] = Napi::Object::New(env); obj_add_func(env, obj, ring, CHN_RingGetSQE, "get_sqe"); obj_add_func(env, obj, ring, CHN_RingSubmitSQE, "submit_sqe"); obj_add_func(env, obj, ring, CHN_RingWaitCQE, "wait_cqe"); obj_add_func(env, obj, ring, CHN_RingForEachCQE, "for_each_cqe"); obj_add_func(env, obj, ring, CHN_RingCQAdvance, "cq_advance"); obj.AddFinalizer(CHN_RingDestruct, ring); + ring->ref_ = Napi::Persistent(obj); return obj; } @@ -235,7 +302,7 @@ static Napi::Value CHN_CreateRing(const Napi::CallbackInfo &info) "chnet.create_ring must be given exactly a positive integer argument"; Napi::Env env = info.Env(); - CNRingCtx *ring; + NodeCHNetRing *ring; uint32_t entry; if (unlikely(info.Length() < 1 || !info[0].IsNumber())) { @@ -244,7 +311,7 @@ static Napi::Value CHN_CreateRing(const Napi::CallbackInfo &info) } entry = info[0].ToNumber().Uint32Value(); - ring = new CNRingCtx(entry); + ring = new NodeCHNetRing(entry); return _CHN_CreateRing(env, ring); } @@ -254,14 +321,14 @@ static void CHN_NetSetURL(const Napi::CallbackInfo &info) "chnet.set_url must be given exactly 1 string argument"; Napi::Env env = info.Env(); - CHNetNode *ch; + NodeCHNet *ch; if (unlikely(info.Length() != 1 || !info[0].IsString())) { throw_js_exception(env, err_msg); return; } - ch = (CHNetNode *)info.Data(); + ch = (NodeCHNet *)info.Data(); const std::string &url = info[0].ToString().Utf8Value(); ch->ch_.SetURL(url.c_str()); } @@ -269,10 +336,10 @@ static void CHN_NetSetURL(const Napi::CallbackInfo &info) static Napi::Value CHN_NetReadBuf(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); - CHNetNode *ch; + NodeCHNet *ch; int ret; - ch = (CHNetNode *)info.Data(); + ch = (NodeCHNet *)info.Data(); ret = ch->ch_.read_ret(); if (ret > 0) return Napi::String::New(env, ch->ch_.read_buf(), (size_t)ret); @@ -283,13 +350,13 @@ static Napi::Value CHN_NetReadBuf(const Napi::CallbackInfo &info) static Napi::Number CHN_NetReadRet(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); - CHNetNode *ch; + NodeCHNet *ch; - ch = (CHNetNode *)info.Data(); + ch = (NodeCHNet *)info.Data(); return Napi::Number::New(env, ch->ch_.read_ret()); } -static void CHN_NetDestruct(Napi::Env env, CHNetNode *ch) +static void CHN_NetDestruct(Napi::Env env, NodeCHNet *ch) { delete ch; (void)env; @@ -299,16 +366,18 @@ static Napi::Object CHN_CreateNet(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::Object obj = Napi::Object::New(env); - CHNetNode *ch = new CHNetNode; + NodeCHNet *ch = new NodeCHNet; int64_t ch_ptr; obj_add_func(env, obj, ch, CHN_NetSetURL, "set_url"); obj_add_func(env, obj, ch, CHN_NetReadRet, "read_ret"); obj_add_func(env, obj, ch, CHN_NetReadBuf, "read_buf"); - ch_ptr = (int64_t)ch; + ch_ptr = (int64_t) (intptr_t) ch; obj["__ch"] = Napi::Number::New(env, ch_ptr); obj.AddFinalizer(CHN_NetDestruct, ch); + obj.Seal(); + obj.Freeze(); return obj; } diff --git a/chnet/chnet_node.h b/chnet/chnet_node.h index 336a005..ea0ccb3 100644 --- a/chnet/chnet_node.h +++ b/chnet/chnet_node.h @@ -6,10 +6,4 @@ #include "chnet_ring.h" #include "../node-addon-api/napi.h" -class CHNetNode { -public: - CHNetNode(void) = default; - CHNet ch_; -}; - #endif /* #ifndef CHNET_NODE_H */ -- Ammar Faizi