Program Listing for File Inlet.hpp¶
↰ Return to documentation for file (include/uit/spouts/Inlet.hpp)
#pragma once
#ifndef UIT_SPOUTS_INLET_HPP_INCLUDE
#define UIT_SPOUTS_INLET_HPP_INCLUDE
#include <atomic>
#include <cassert>
#include <cstdint>
#include <iostream>
#include <memory>
#include <optional>
#include <stddef.h>
#include <utility>
#include "../../uitsl/debug/occupancy_audit.hpp"
#include "../../uitsl/nonce/CircularIndex.hpp"
#include "../../uitsl/utility/print_utils.hpp"
#include "../ducts/Duct.hpp"
namespace uit {
template<typename ImplSpec_>
class Inlet {
public:
using ImplSpec = ImplSpec_;
private:
using T = typename ImplSpec::T;
constexpr inline static size_t N{ ImplSpec::N };
using index_t = uitsl::CircularIndex<N>;
using duct_t = internal::Duct<ImplSpec>;
std::shared_ptr<duct_t> duct;
size_t blocking_put_count{};
size_t attempted_try_put_count{};
size_t puts_that_blocked_count{};
// How many TryPut calls have dropped?
size_t dropped_put_count{};
uitsl_occupancy_auditor;
bool DoTryPut(const T& val) { return duct->TryPut(val); }
template<typename P>
bool DoTryPut(P&& val) { return duct->TryPut(std::forward<P>(val)); }
public:
Inlet(
std::shared_ptr<duct_t> duct_
) : duct(duct_) { ; }
// potentially blocking
void Put(const T& val) {
uitsl_occupancy_audit(1);
++blocking_put_count;
bool was_blocked{ false };
while (!DoTryPut(val)) was_blocked = true;
puts_that_blocked_count += was_blocked;
}
// non-blocking
bool TryPut(const T& val) {
uitsl_occupancy_audit(1);
++attempted_try_put_count;
if ( DoTryPut(val) ) return true;
else { ++dropped_put_count; return false; }
}
// non-blocking
template<typename P>
bool TryPut(P&& val) {
uitsl_occupancy_audit(1);
++attempted_try_put_count;
if ( DoTryPut(std::forward<P>(val)) ) return true;
else { ++dropped_put_count; return false; }
}
bool TryFlush() { return duct->TryFlush(); }
void Flush() { while( !TryFlush() ); }
size_t GetNumPutsAttempted() const {
return attempted_try_put_count + blocking_put_count;
}
size_t GetNumTryPutsAttempted() const {
return attempted_try_put_count;
}
size_t GetNumBlockingPuts() const {
return blocking_put_count;
}
size_t GetNumTryPutsThatSucceeded() const {
assert( attempted_try_put_count >= dropped_put_count );
return attempted_try_put_count - dropped_put_count;
}
size_t GetNumPutsThatSucceededEventually() const {
return blocking_put_count + GetNumTryPutsThatSucceeded();
}
size_t GetNumBlockingPutsThatSucceededImmediately() const {
assert( blocking_put_count >= puts_that_blocked_count );
return blocking_put_count - puts_that_blocked_count;
}
size_t GetNumPutsThatSucceededImmediately() const {
return (
GetNumTryPutsThatSucceeded()
+ GetNumBlockingPutsThatSucceededImmediately()
);
}
size_t GetNumPutsThatBlocked() const { return puts_that_blocked_count; }
size_t GetNumDroppedPuts() const { return dropped_put_count; }
double GetFractionTryPutsDropped() const {
return dropped_put_count / static_cast<double>( attempted_try_put_count );
}
double GetFractionTryPutsThatSucceeded() const {
return 1.0 - GetFractionTryPutsDropped();
}
double GetFractionBlockingPutsThatBlocked() const {
return puts_that_blocked_count / static_cast<double>( blocking_put_count );
}
double GetFractionBlockingPutsThatSucceededImmediately() const {
return 1.0 - GetFractionBlockingPutsThatBlocked();
}
double GetFractionPutsThatSucceededEventually() const {
return (
GetNumPutsThatSucceededEventually()
/ static_cast<double>( GetNumPutsAttempted() )
);
}
double GetFractionPutsThatSucceededImmediately() const {
return (
GetNumPutsThatSucceededImmediately()
/ static_cast<double>( GetNumPutsAttempted() )
);
}
template <typename WhichDuct, typename... Args>
void EmplaceDuct(Args&&... args) {
duct->template EmplaceImpl<WhichDuct>(std::forward<Args>(args)...);
}
template <typename WhichDuct, typename... Args>
void SplitDuct(Args&&... args) {
duct = std::make_shared<duct_t>(
std::in_place_type_t<WhichDuct>{},
std::forward<Args>(args)...
);
}
typename duct_t::uid_t GetDuctUID() const { return duct->GetUID(); }
std::optional<bool> HoldsIntraImpl() const { return duct->HoldsIntraImpl(); }
std::optional<bool> HoldsThreadImpl() const {
return duct->HoldsThreadImpl();
}
std::optional<bool> HoldsProcImpl() const { return duct->HoldsProcImpl(); }
std::string WhichImplHeld() const { return duct->WhichImplHeld(); }
void RegisterInletProc(const uitsl::proc_id_t proc) const {
duct->RegisterInletProc(proc);
}
void RegisterInletThread(const uitsl::thread_id_t thread) const {
duct->RegisterInletThread(thread);
}
void RegisterOutletProc(const uitsl::proc_id_t proc) const {
duct->RegisterOutletProc(proc);
}
void RegisterOutletThread(const uitsl::thread_id_t thread) const {
duct->RegisterOutletThread(thread);
}
void RegisterEdgeID(const size_t edge_id) const {
duct->RegisterEdgeID(edge_id);
}
void RegisterInletNodeID(const size_t node_id) const {
duct->RegisterInletNodeID(node_id);
}
void RegisterOutletNodeID(const size_t node_id) const {
duct->RegisterOutletNodeID(node_id);
}
void RegisterMeshID(const size_t mesh_id) const {
duct->RegisterMeshID(mesh_id);
}
std::optional<uitsl::proc_id_t> LookupOutletProc() const {
return duct->LookupOutletProc();
}
std::optional<uitsl::thread_id_t> LookupOutletThread() const {
return duct->LookupOutletThread();
}
std::optional<uitsl::proc_id_t> LookupInletProc() const {
return duct->LookupInletProc();
}
std::optional<uitsl::thread_id_t> LookupInletThread() const {
return duct->LookupInletThread();
}
std::optional<size_t> LookupEdgeID() const {
return duct->LookupEdgeID();
}
std::optional<size_t> LookupInletNodeID() const {
return duct->LookupInletNodeID();
}
std::optional<size_t> LookupOutletNodeID() const {
return duct->LookupOutletNodeID();
}
std::optional<size_t> LookupMeshID() const { return duct->LookupMeshID(); }
std::string ToString() const {
std::stringstream ss;
ss << uitsl::format_member("duct_t duct", *duct) << '\n';
ss << uitsl::format_member(
"size_t attempted_try_put_count",
attempted_try_put_count
) << '\n';
ss << uitsl::format_member(
"size_t blocking_put_count",
blocking_put_count
) << '\n';
ss << uitsl::format_member(
"size_t dropped_put_count",
dropped_put_count
) << '\n';
ss << uitsl::format_member(
"size_t puts_that_blocked_count",
puts_that_blocked_count
);
return ss.str();
}
};
} // namespace uit
#endif // #ifndef UIT_SPOUTS_INLET_HPP_INCLUDE