Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 30 additions & 19 deletions src/rt/cpp/cown.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,11 +189,7 @@ namespace verona::cpp
};

private:
template<typename TT>
friend class Access;

template<typename TT>
friend class AccessBatch;
friend class When;

/**
* Internal Verona runtime cown for this type.
Expand All @@ -203,7 +199,7 @@ namespace verona::cpp
/**
* Accesses the internal Verona runtime cown for this handle.
*/
Cown* underlying_cown()
Cown* underlying_cown() const
{
return allocated_cown;
}
Expand Down Expand Up @@ -294,6 +290,11 @@ namespace verona::cpp
return allocated_cown == nullptr;
}

bool operator!=(std::nullptr_t)
{
return allocated_cown != nullptr;
}

/**
* Sets the cown_ptr to nullptr, and decrements the reference count
* if it was not already nullptr.
Expand Down Expand Up @@ -331,7 +332,6 @@ namespace verona::cpp
template<typename TT, typename... Args>
friend cown_ptr<TT> make_cown(Args&&...);

template<typename F, typename... Args2>
friend class When;
};

Expand Down Expand Up @@ -404,36 +404,39 @@ namespace verona::cpp
class acquired_cown
{
/// Needed to build one from inside a `When`
template<typename F, typename... Args2>
friend class When;

template<typename T2>
friend class AccessBatch;
template<typename TT>
friend struct acquired_cown_span;

private:
/// Underlying cown that has been acquired.
/// Runtime is actually holding this reference count.
ActualCown<std::remove_const_t<T>>& origin_cown;
Slot* wrapped_slot;

/// Constructor is private, as only `When` can construct one.
acquired_cown(ActualCown<std::remove_const_t<T>>& origin)
: origin_cown(origin)
{}
ActualCown<std::remove_const_t<T>>* raw_cown() const
{
return static_cast<ActualCown<std::remove_const_t<T>>*>(
wrapped_slot->cown());
}

public:
/// Constructor is private, as only `When` can construct one.
acquired_cown(Slot* slot) : wrapped_slot(slot) {}

/// Get a handle on the underlying cown.
cown_ptr<std::remove_const_t<T>> cown() const
{
verona::rt::Cown::acquire(&origin_cown);
return cown_ptr<T>(&origin_cown);
verona::rt::Cown::acquire(raw_cown());
return cown_ptr<std::remove_const_t<T>>(raw_cown());
}

T& get_ref() const
{
if constexpr (std::is_const<T>())
return const_cast<T&>(origin_cown.value);
return const_cast<T&>(raw_cown()->value);
else
return origin_cown.value;
return raw_cown()->value;
}

T& operator*()
Expand Down Expand Up @@ -463,4 +466,12 @@ namespace verona::cpp
acquired_cown& operator=(const acquired_cown&) = delete;
/// @}
};

template<typename T>
Logging::SysLog&
operator<<(Logging::SysLog& log, const verona::cpp::acquired_cown<T>& cown)
{
log << &cown.get_ref();
return log;
}
} // namespace verona::rt
56 changes: 38 additions & 18 deletions src/rt/cpp/cown_array.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,36 @@ namespace verona::cpp
*
* The destructor calls the destructor of each cown_ptr and frees the
* allocated array.
*
* The template argument owning is used to determine if the cown_array
* should own the cown_ptr array or not. If it is false, the cown_array
* will not allocate a new array and will not free it in the destructor.
*/
template<typename T>
template<typename T, bool owning = true>
struct cown_array
{
cown_ptr<T>* array;
size_t length;

void constr_helper(cown_ptr<T>* arr)
{
array = reinterpret_cast<cown_ptr<T>*>(
heap::alloc(length * sizeof(cown_ptr<T>*)));
if constexpr (owning)
{
array = reinterpret_cast<cown_ptr<T>*>(
heap::alloc(length * sizeof(cown_ptr<T>*)));

for (size_t i = 0; i < length; i++)
new (&array[i]) cown_ptr<T>(arr[i]);
for (size_t i = 0; i < length; i++)
new (&array[i]) cown_ptr<T>(arr[i]);
}
else
{
array = arr;
}
}

template<bool should_move = false>
cown_array(cown_ptr<T>* array_, size_t length_) : length(length_)
{
if constexpr (should_move == false)
{
constr_helper(array_);
}
constr_helper(array_);
}

cown_array(const cown_array& o)
Expand All @@ -49,12 +56,24 @@ namespace verona::cpp

~cown_array()
{
if (array)
if constexpr (owning)
{
for (size_t i = 0; i < length; i++)
array[i].~cown_ptr<T>();
if (array)
{
for (size_t i = 0; i < length; i++)
array[i].~cown_ptr<T>();

heap::dealloc(array);
}
}
}

void steal()
{
if constexpr (owning)
{
heap::dealloc(array);
array = nullptr;
}
}

Expand All @@ -72,15 +91,16 @@ namespace verona::cpp
* We use inheritance to allow us to construct a cown_array<const T> from a
* cown_array<T>.
*/
template<typename T>
class cown_array<const T> : public cown_array<T>
template<typename T, bool owning>
class cown_array<const T, owning> : public cown_array<T, owning>
{
public:
cown_array(const cown_array<T>& other) : cown_array<T>(other){};
cown_array(const cown_array<T, owning>& other)
: cown_array<T, owning>(other){};
};

template<typename T>
cown_array<const T> read(cown_array<T> cown)
template<typename T, bool owning>
cown_array<const T, owning> read(cown_array<T, owning> cown)
{
Logging::cout() << "Read returning const array ptr" << Logging::endl;
return cown;
Expand Down
6 changes: 0 additions & 6 deletions src/rt/cpp/lambdabehaviour.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,6 @@ namespace verona::rt
Behaviour::schedule<transfer>(count, cowns, std::forward<Be>(f));
}

template<typename Be>
static void schedule_lambda(size_t count, Request* requests, Be&& f)
{
Behaviour::schedule(count, requests, std::forward<Be>(f));
}

template<typename Be>
static void schedule_lambda(Be&& f)
{
Expand Down
Loading