@@ -612,4 +612,135 @@ IntervalHistogram::CloneForMessaging() const {
612612 return std::make_unique<HistogramBase::HistogramTransferData>(histogram ());
613613}
614614
615+ CFunction ELDNativeHistogram::fast_start_ (
616+ CFunction::Make (&ELDNativeHistogram::FastStart));
617+ CFunction ELDNativeHistogram::fast_stop_ (
618+ CFunction::Make (&ELDNativeHistogram::FastStop));
619+
620+ Local<FunctionTemplate> ELDNativeHistogram::GetConstructorTemplate (
621+ Environment* env) {
622+ Local<FunctionTemplate> tmpl =
623+ env->eld_native_histogram_constructor_template ();
624+ if (tmpl.IsEmpty ()) {
625+ Isolate* isolate = env->isolate ();
626+ tmpl = NewFunctionTemplate (isolate, nullptr );
627+ tmpl->Inherit (HandleWrap::GetConstructorTemplate (env));
628+ tmpl->SetClassName (FIXED_ONE_BYTE_STRING (isolate, " Histogram" ));
629+ auto instance = tmpl->InstanceTemplate ();
630+ instance->SetInternalFieldCount (ELDNativeHistogram::kInternalFieldCount );
631+ HistogramImpl::AddMethods (isolate, tmpl);
632+ SetFastMethod (isolate, instance, " start" , Start, &fast_start_);
633+ SetFastMethod (isolate, instance, " stop" , Stop, &fast_stop_);
634+ env->set_eld_native_histogram_constructor_template (tmpl);
635+ }
636+ return tmpl;
637+ }
638+
639+ void ELDNativeHistogram::RegisterExternalReferences (
640+ ExternalReferenceRegistry* registry) {
641+ registry->Register (Start);
642+ registry->Register (Stop);
643+ registry->Register (fast_start_);
644+ registry->Register (fast_stop_);
645+ HistogramImpl::RegisterExternalReferences (registry);
646+ }
647+
648+ ELDNativeHistogram::ELDNativeHistogram (Environment* env, Local<Object> wrap)
649+ : HandleWrap(
650+ env,
651+ wrap,
652+ reinterpret_cast <uv_handle_t *>(&check_),
653+ AsyncWrap::PROVIDER_ELDNATIVEHISTOGRAM),
654+ HistogramImpl() {
655+ MakeWeak ();
656+ wrap->SetAlignedPointerInInternalField (
657+ HistogramImpl::InternalFields::kImplField ,
658+ static_cast <HistogramImpl*>(this ),
659+ EmbedderDataTag::kDefault );
660+ uv_check_init (env->event_loop (), &check_);
661+ }
662+
663+ BaseObjectPtr<ELDNativeHistogram> ELDNativeHistogram::Create (
664+ Environment* env) {
665+ Local<Object> obj;
666+ if (!GetConstructorTemplate (env)
667+ ->InstanceTemplate ()
668+ ->NewInstance (env->context ())
669+ .ToLocal (&obj)) {
670+ return nullptr ;
671+ }
672+ return MakeBaseObject<ELDNativeHistogram>(env, obj);
673+ }
674+
675+ void ELDNativeHistogram::CheckCB (uv_check_t * handle) {
676+ ELDNativeHistogram* histogram =
677+ ContainerOf (&ELDNativeHistogram::check_, handle);
678+
679+ uint64_t now = uv_hrtime ();
680+ uint64_t idle_now = uv_metrics_idle_time (histogram->env ()->event_loop ());
681+
682+ if (histogram->prev_hrtime_ > 0 ) {
683+ uint64_t total = now - histogram->prev_hrtime_ ;
684+ uint64_t idle = idle_now - histogram->prev_idle_time_ ;
685+ if (idle > total) idle = total;
686+ int64_t busy = static_cast <int64_t >(total - idle);
687+ if (busy > 0 )
688+ histogram->histogram ()->Record (busy);
689+ }
690+
691+ histogram->prev_hrtime_ = now;
692+ histogram->prev_idle_time_ = idle_now;
693+ }
694+
695+ void ELDNativeHistogram::MemoryInfo (MemoryTracker* tracker) const {
696+ tracker->TrackField (" histogram" , histogram ());
697+ }
698+
699+ void ELDNativeHistogram::OnStart (bool reset) {
700+ if (enabled_ || IsHandleClosing ()) return ;
701+ enabled_ = true ;
702+ if (reset) histogram ()->Reset ();
703+ prev_hrtime_ = 0 ;
704+ prev_idle_time_ = 0 ;
705+ uv_check_start (&check_, CheckCB);
706+ uv_unref (reinterpret_cast <uv_handle_t *>(&check_));
707+ }
708+
709+ void ELDNativeHistogram::OnStop () {
710+ if (!enabled_ || IsHandleClosing ()) return ;
711+ enabled_ = false ;
712+ uv_check_stop (&check_);
713+ }
714+
715+ void ELDNativeHistogram::Start (const FunctionCallbackInfo<Value>& args) {
716+ ELDNativeHistogram* histogram;
717+ ASSIGN_OR_RETURN_UNWRAP (&histogram, args.This ());
718+ histogram->OnStart (args[0 ]->IsTrue ());
719+ }
720+
721+ void ELDNativeHistogram::FastStart (Local<Value> receiver, bool reset) {
722+ TRACK_V8_FAST_API_CALL (" histogram.start" );
723+ ELDNativeHistogram* histogram;
724+ ASSIGN_OR_RETURN_UNWRAP (&histogram, receiver);
725+ histogram->OnStart (reset);
726+ }
727+
728+ void ELDNativeHistogram::Stop (const FunctionCallbackInfo<Value>& args) {
729+ ELDNativeHistogram* histogram;
730+ ASSIGN_OR_RETURN_UNWRAP (&histogram, args.This ());
731+ histogram->OnStop ();
732+ }
733+
734+ void ELDNativeHistogram::FastStop (Local<Value> receiver) {
735+ TRACK_V8_FAST_API_CALL (" histogram.stop" );
736+ ELDNativeHistogram* histogram;
737+ ASSIGN_OR_RETURN_UNWRAP (&histogram, receiver);
738+ histogram->OnStop ();
739+ }
740+
741+ std::unique_ptr<worker::TransferData>
742+ ELDNativeHistogram::CloneForMessaging () const {
743+ return std::make_unique<HistogramBase::HistogramTransferData>(histogram ());
744+ }
745+
615746} // namespace node
0 commit comments