From 304cd577afd0f7ac74baaa6408bd7693f9cb1607 Mon Sep 17 00:00:00 2001
From: Lizzzka007 <gashchuk2011@mail.ru>
Date: Fri, 25 Oct 2024 00:58:08 +0300
Subject: [PATCH] .

---
 CMakeLists.txt        |  14 ++++-
 Lib/CMakeLists.txt    |   8 ++-
 Lib/memory-faucet.cpp | 121 ++++++++++++++++++++++++++++--------------
 Lib/memory-faucet.h   |  23 ++++----
 main.cpp              |  48 +++++++++++++----
 5 files changed, 154 insertions(+), 60 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 04c70a5..c1f6789 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,11 +1,23 @@
 cmake_minimum_required(VERSION 3.19)
 
 option(INCLUDE_CUDA "GPU build in mode" OFF)
+option(ADRESS_SANITIZER "Enable address sanitizer" OFF)
+option(CXX23_STACKTRACE "Enable C++23 stacktrace" OFF)
+
+if(ADRESS_SANITIZER)
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -O1 -fno-omit-frame-pointer -g")
+endif(ADRESS_SANITIZER)
+
+# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++2b")
 
 project(memory-faucet-test)
 
 enable_language(CXX)
-set(CMAKE_CXX_STANDARD 11)
+if(CXX23_STACKTRACE)
+    set(CMAKE_CXX_STANDARD 23)
+else(CXX23_STACKTRACE)
+    set(CMAKE_CXX_STANDARD 11)
+endif(CXX23_STACKTRACE)
 
 if(INCLUDE_CUDA)
     if(NOT DEFINED CMAKE_CUDA_ARCHITECTURES)
diff --git a/Lib/CMakeLists.txt b/Lib/CMakeLists.txt
index 63b6ff8..2857b1a 100644
--- a/Lib/CMakeLists.txt
+++ b/Lib/CMakeLists.txt
@@ -1,11 +1,17 @@
 cmake_minimum_required(VERSION 3.19)
 
 option(INCLUDE_CUDA "GPU build in mode" OFF)
+option(CXX23_STACKTRACE "Enable C++23 stacktrace" OFF)
+# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++2b")
 
 project(memory-holder)
 
 enable_language(CXX)
-set(CMAKE_CXX_STANDARD 11)
+if(CXX23_STACKTRACE)
+    set(CMAKE_CXX_STANDARD 23)
+else(CXX23_STACKTRACE)
+    set(CMAKE_CXX_STANDARD 11)
+endif(CXX23_STACKTRACE)
 
 include(FetchContent)
 FetchContent_Declare(
diff --git a/Lib/memory-faucet.cpp b/Lib/memory-faucet.cpp
index cec3b60..9f3d6c7 100644
--- a/Lib/memory-faucet.cpp
+++ b/Lib/memory-faucet.cpp
@@ -35,6 +35,7 @@ void buffer<mem>::reallocate(const size_t required_size)
 template< MemType mem >
 buffer<mem>::buffer(const size_t required_size)
 {
+    ptr = nullptr;
     allocated_size = 0;
     reallocate(required_size);
     scalar_size = 0;
@@ -97,8 +98,14 @@ void buffer<mem>::set_allocated_size(const size_t required_size)
 }
 
 template< MemType mem >
-buffer<mem>::buffer(const buffer<mem>& other)
+void buffer<mem>::set_null_pointer()
 {
+    ptr = nullptr;
+}
+
+template< MemType mem >
+buffer<mem>::buffer(const buffer<mem>& other)
+{    
     allocated_size = 0;
     reallocate(other.get_size());
     is_free = other.get_status();
@@ -106,17 +113,19 @@ buffer<mem>::buffer(const buffer<mem>& other)
 }
 
 template< MemType mem >
-buffer<mem>& buffer<mem>::operator=(buffer<mem>& other)
-{
-    if (this == &other)
-        return *this;
+buffer<mem>::buffer(buffer<mem>&& other) 
+{    
+    ptr = other.ptr;
+    allocated_size = other.allocated_size;
+    scalar_size = other.scalar_size;
+    is_free = other.is_free;
+    id = other.id;
 
-    std::swap(ptr, other.ptr);
-    allocated_size = other.get_size();
-    other.set_allocated_size(size_t(0));
-    is_free = other.get_status();
-    id = other.get_id();
-    return *this;
+    other.ptr = nullptr;
+    other.allocated_size = 0;
+    other.scalar_size = 0;
+    other.is_free = false;
+    other.id = -1;
 }
 
 template< MemType mem >
@@ -132,6 +141,28 @@ buffer<mem>& buffer<mem>::operator=(const buffer<mem>& other)
     return *this;
 }
 
+template< MemType mem >
+buffer<mem>& buffer<mem>::operator=(buffer<mem>&& other) 
+{
+    if (this != &other)
+    {
+        memproc::dealloc<mem>((void *&)ptr, allocated_size);
+        ptr = other.ptr;
+        allocated_size = other.allocated_size;
+        scalar_size = other.scalar_size;
+        is_free = other.is_free;
+        id = other.id;
+
+        other.ptr = nullptr;
+        other.allocated_size = 0;
+        other.scalar_size = 0;
+        other.is_free = false;
+        other.id = -1;
+    }
+
+    return *this;
+}
+
 template< MemType mem >
 void buffer<mem>::set_status(const bool status)
 {
@@ -165,8 +196,8 @@ memory_pipe_base::~memory_pipe_base()
     cpu_buff.clear();
 }
 
-template< MemType mem >
-std::vector<buffer<mem> >& memory_pipe_base::get_memtyped_vector()
+template< >
+std::vector<buffer<MemType::CPU> >& memory_pipe_base::get_memtyped_vector()
 {
     return cpu_buff;
 }
@@ -202,7 +233,7 @@ typename std::vector<buffer<mem>>::iterator get_lower_bound(typename std::vector
     {
         it = first;
         step = count / 2;
-        std::next(it, step);
+        it = std::next(it, step);
  
         if (comp(*it, value))
         {
@@ -235,7 +266,7 @@ typename std::vector<buffer<mem>>::iterator get_upper_bound(typename std::vector
     {
         it = first; 
         step = count / 2;
-        std::next(it, step);
+        it = std::next(it, step);
  
         if (!comp(value, *it))
         {
@@ -258,7 +289,7 @@ template typename std::vector<buffer<MemType::GPU>>::iterator get_upper_bound<Me
 
 template<buf_choose_policy choose_type>
 template< MemType mem >
-int memory_pipe<choose_type>::get_buffer(const size_t required_size, void *& ptr)
+int memory_pipe<choose_type>::get_buffer(const size_t required_size, void ** ptr)
 {
     std::vector<buffer<mem> >& buff_vec = get_memtyped_vector<mem>();
     const int allocated_buffer_n = buff_vec.size();
@@ -269,24 +300,31 @@ int memory_pipe<choose_type>::get_buffer(const size_t required_size, void *& ptr
 
         if(is_free == true && required_size <= avail_size)
         {
-            ptr = buff_vec[i].get_ptr();
+            (*ptr) = buff_vec[i].get_ptr();
+            buff_vec[i].set_status(false);
             return i;
         }
     }
 
     buff_vec.push_back(buffer<mem>(required_size));
-    ptr = buff_vec.back().get_ptr();
+    
+    (*ptr) = buff_vec.back().get_ptr();
     int id = buff_vec.size() - 1;
+
+    buff_vec.back().set_status(false);
+    buff_vec.back().set_id(id);
+    
     return id;
 }
 
-template int memory_pipe<buf_choose_policy::naiv>::get_buffer<MemType::CPU>(const size_t required_size, void *& ptr);
+template int memory_pipe<buf_choose_policy::naive>::get_buffer<MemType::CPU>(const size_t required_size, void ** ptr);
 #ifdef INCLUDE_CUDA
-template int memory_pipe<buf_choose_policy::naiv>::get_buffer<MemType::GPU>(const size_t required_size, void *& ptr);
+template int memory_pipe<buf_choose_policy::naive>::get_buffer<MemType::GPU>(const size_t required_size, void ** ptr);
 #endif
 
+// template< >
 template< MemType mem >
-int memory_pipe<buf_choose_policy::sorted_vec>::get_buffer(const size_t required_size, void *& ptr)
+int memory_pipe<buf_choose_policy::sorted_vec>::get_buffer(const size_t required_size, void ** ptr)
 {
     std::vector<buffer<mem> >& buff_vec = get_memtyped_vector<mem>();
     const int allocated_buffer_n = buff_vec.size();
@@ -297,7 +335,8 @@ int memory_pipe<buf_choose_policy::sorted_vec>::get_buffer(const size_t required
 
         if(is_free == true && required_size <= avail_size)
         {
-            ptr = buff_vec[i].get_ptr();
+            (*ptr) = buff_vec[i].get_ptr();
+            buff_vec[i].set_status(false);
             return i;
         }
     }
@@ -306,19 +345,20 @@ int memory_pipe<buf_choose_policy::sorted_vec>::get_buffer(const size_t required
     std::function<bool (const size_t, const buffer<mem>&) > comparator = size_comparator<mem>;
     buf_it = get_upper_bound<mem> (buff_vec.begin(), buff_vec.end(), required_size, comparator);
     buf_it = buff_vec.insert(buf_it, buffer<mem>(required_size));
-    ptr = buf_it->get_ptr();
+    (*ptr) = buf_it->get_ptr();
     int id = std::distance(buff_vec.begin(), buf_it);
-
+    buff_vec.back().set_id(id);
     return id;
 }
 
-template int memory_pipe<buf_choose_policy::sorted_vec>::get_buffer<MemType::CPU>(const size_t required_size, void *& ptr);
+template int memory_pipe<buf_choose_policy::sorted_vec>::get_buffer<MemType::CPU>(const size_t required_size, void ** ptr);
 #ifdef INCLUDE_CUDA
-template int memory_pipe<buf_choose_policy::sorted_vec>::get_buffer<MemType::GPU>(const size_t required_size, void *& ptr);
+template int memory_pipe<buf_choose_policy::sorted_vec>::get_buffer<MemType::GPU>(const size_t required_size, void ** ptr);
 #endif
 
+// template< >
 template< MemType mem >
-int memory_pipe<buf_choose_policy::find_best_unsorted>::get_buffer(const size_t required_size, void *& ptr)
+int memory_pipe<buf_choose_policy::find_best_unsorted>::get_buffer(const size_t required_size, void ** ptr)
 {
     std::vector<buffer<mem> >& buff_vec = get_memtyped_vector<mem>();
     typename std::vector<buffer<mem>>::iterator available_buf_it;
@@ -326,42 +366,44 @@ int memory_pipe<buf_choose_policy::find_best_unsorted>::get_buffer(const size_t
     available_buf_it = get_lower_bound<mem> (buff_vec.begin(), buff_vec.end(), required_size, comparator);
     if(available_buf_it != buff_vec.end())
     {    
-        ptr = available_buf_it->get_ptr();
+        (*ptr) = available_buf_it->get_ptr();
         int id = std::distance(buff_vec.begin(), available_buf_it);
+        buff_vec[id].set_status(false);
         return id;
     }
     else
     {
         buff_vec.push_back(buffer<mem>(required_size));
-        ptr = buff_vec.back().get_ptr();
+        (*ptr) = buff_vec.back().get_ptr();
         int id = buff_vec.size() - 1;
+        buff_vec.back().set_id(id);
         return id;
     }
 }
 
-template int memory_pipe<buf_choose_policy::find_best_unsorted>::get_buffer<MemType::CPU>(const size_t required_size, void *& ptr);
+template int memory_pipe<buf_choose_policy::find_best_unsorted>::get_buffer<MemType::CPU>(const size_t required_size, void ** ptr);
 #ifdef INCLUDE_CUDA
-template int memory_pipe<buf_choose_policy::find_best_unsorted>::get_buffer<MemType::GPU>(const size_t required_size, void *& ptr);
+template int memory_pipe<buf_choose_policy::find_best_unsorted>::get_buffer<MemType::GPU>(const size_t required_size, void ** ptr);
 #endif
 
 template< >
-memory_pipe<buf_choose_policy::naiv>& memory_faucet::get_faucet()
+memory_pipe<buf_choose_policy::naive>& memory_faucet::get_faucet()
 {
-    static memory_pipe<buf_choose_policy::naiv> mem_pipe_naiv;
-    return mem_pipe_naiv;
+    static memory_pipe<buf_choose_policy::naive> mem_pipe_naive = memory_pipe<buf_choose_policy::naive>();
+    return mem_pipe_naive;
 }
 
 template< >
 memory_pipe<buf_choose_policy::sorted_vec>& memory_faucet::get_faucet()
 {
-    static memory_pipe<buf_choose_policy::sorted_vec> mem_pipe_sorted;
+    static memory_pipe<buf_choose_policy::sorted_vec> mem_pipe_sorted = memory_pipe<buf_choose_policy::sorted_vec>();
     return mem_pipe_sorted;
 }
 
 template< >
 memory_pipe<buf_choose_policy::find_best_unsorted>& memory_faucet::get_faucet()
 {
-    static memory_pipe<buf_choose_policy::find_best_unsorted> mem_pipe_unsorted;
+    static memory_pipe<buf_choose_policy::find_best_unsorted> mem_pipe_unsorted = memory_pipe<buf_choose_policy::find_best_unsorted>();
     return mem_pipe_unsorted;
 }
 
@@ -370,7 +412,7 @@ template< MemType mem, buf_choose_policy choose_type >
 memBuf<mem, choose_type>::memBuf(const size_t required_size)
 {
     memory_pipe<choose_type>& mem_pipe = memory_faucet::get_faucet<choose_type>();
-    id = mem_pipe.template get_buffer<mem>(required_size, buf);
+    id = mem_pipe.template get_buffer<mem>(required_size, &buf);
     size = required_size;
 }
 
@@ -379,6 +421,7 @@ memBuf<mem, choose_type>::~memBuf()
 {
     memory_pipe<choose_type>& mem_pipe = memory_faucet::get_faucet<choose_type>();
     mem_pipe.template set_available<mem>(id);
+    buf = nullptr;
 }
 
 template< MemType mem, buf_choose_policy choose_type >
@@ -393,12 +436,12 @@ int memBuf<mem, choose_type>::get_size()
     return size;
 }
 
-template class memBuf<MemType::CPU, buf_choose_policy::naiv>;
+template class memBuf<MemType::CPU, buf_choose_policy::naive>;
 template class memBuf<MemType::CPU, buf_choose_policy::sorted_vec>;
 template class memBuf<MemType::CPU, buf_choose_policy::find_best_unsorted>;
 
 #ifdef INCLUDE_CUDA
-template class memBuf<MemType::GPU, buf_choose_policy::naiv>;
+template class memBuf<MemType::GPU, buf_choose_policy::naive>;
 template class memBuf<MemType::GPU, buf_choose_policy::sorted_vec>;
 template class memBuf<MemType::GPU, buf_choose_policy::find_best_unsorted>;
 #endif
diff --git a/Lib/memory-faucet.h b/Lib/memory-faucet.h
index a2d6c30..adb2111 100644
--- a/Lib/memory-faucet.h
+++ b/Lib/memory-faucet.h
@@ -7,7 +7,7 @@
 
 enum class buf_choose_policy
 {
-    naiv,
+    naive,
     sorted_vec,
     find_best_unsorted
 };
@@ -15,15 +15,15 @@ enum class buf_choose_policy
 template< MemType mem >
 class buffer
 {
-private:
+public:
     void *ptr;
     size_t allocated_size;
     size_t scalar_size;
     bool is_free;
     int id;
 
-public:
     buffer(const buffer<mem>& other);
+    buffer(buffer<mem>&& other);
     buffer();
     ~buffer();
     buffer(const size_t required_size);
@@ -33,12 +33,15 @@ public:
     bool get_status() const;
     size_t get_size() const;
     int get_id() const;
-    buffer<mem>& operator=(buffer<mem>& other);
+
     buffer<mem>& operator=(const buffer<mem>& other);
+    buffer<mem>& operator=(buffer<mem>&& other);
+
     void reallocate(const size_t required_size);
     void set_allocated_size(const size_t required_size);
     void set_status(const bool status);
     void set_id(const int id);
+    void set_null_pointer();
 };
 
 class memory_pipe_base
@@ -59,7 +62,7 @@ public:
     std::vector<buffer<mem> >& get_memtyped_vector();
 };
 
-template<buf_choose_policy choose_type = buf_choose_policy::naiv>
+template<buf_choose_policy choose_type = buf_choose_policy::naive>
 class memory_pipe: public memory_pipe_base 
 {
 public:
@@ -67,7 +70,7 @@ public:
     ~memory_pipe() = default;
 
     template< MemType mem >
-    int get_buffer(const size_t required_size, void *& ptr);
+    int get_buffer(const size_t required_size, void ** ptr);
 };
 
 template<>
@@ -78,7 +81,7 @@ public:
     ~memory_pipe() = default;
 
     template< MemType mem >
-    int get_buffer(const size_t required_size, void *& ptr);
+    int get_buffer(const size_t required_size, void ** ptr);
 };
 
 template<>
@@ -89,7 +92,7 @@ public:
     ~memory_pipe() = default;
 
     template< MemType mem >
-    int get_buffer(const size_t required_size, void *& ptr);
+    int get_buffer(const size_t required_size, void ** ptr);
 };
 
 class memory_faucet
@@ -101,11 +104,11 @@ private:
 
 public:
 
-    template<buf_choose_policy choose_type = buf_choose_policy::naiv>
+    template<buf_choose_policy choose_type = buf_choose_policy::naive>
     static memory_pipe<choose_type>& get_faucet();
 };
 
-template< MemType mem, buf_choose_policy choose_type = buf_choose_policy::naiv >
+template< MemType mem, buf_choose_policy choose_type = buf_choose_policy::naive >
 class memBuf
 {
 private:
diff --git a/main.cpp b/main.cpp
index 116fa71..6d8ab88 100644
--- a/main.cpp
+++ b/main.cpp
@@ -1,19 +1,49 @@
 #include "memory-faucet.h"
 #include <cstdio>
+
 int main(void)
 {
-    const size_t required_size = sizeof(float) * 100;
+    const size_t required_size1 = sizeof(float) * 100;
+    const size_t required_size2 = sizeof(float) * 1;
+    const size_t required_size3 = sizeof(float) * 10000;
+    const size_t required_size5 = sizeof(float) * 100000;
+    const size_t required_size6 = sizeof(float) * 100000000;
     // printf("required_size %ld\n", required_size);
-    memBuf<MemType::CPU> Buf1(required_size);
-    memBuf<MemType::CPU, buf_choose_policy::sorted_vec> Buf2(required_size);
-    memBuf<MemType::CPU, buf_choose_policy::find_best_unsorted> Buf3(required_size);
-    // memBuf<MemType::GPU> Buf_gpu(required_size);
+    
+    printf("Start Buf1\n");
+    memBuf<MemType::CPU> Buf1(required_size3);
+    // memBuf<MemType::CPU> Buf2(required_size3);
+    printf("Start Buf2\n");
+    memBuf<MemType::CPU> Buf2(required_size3);
+    // memBuf<MemType::CPU, buf_choose_policy::find_best_unsorted> Buf3(required_size3);
+    printf("Start Buf4\n");
+    memBuf<MemType::CPU> Buf4(required_size1);
+
+    printf("Start Buf5\n");
+    memBuf<MemType::CPU> Buf5(required_size5);
+
+    printf("Start Buf6\n");
+    memBuf<MemType::CPU> Buf6(required_size6);
 
-    float* ptr = static_cast<float*>(Buf1.ptr());
-    // float* ptr_gpu = static_cast<float*>(Buf_gpu.ptr());
+    printf("Start Buf7\n");
+    memBuf<MemType::GPU> Buf7(required_size6);
 
-    for (int i = 0; i < 100; i++)
+    float* ptr1 = static_cast<float*>(Buf1.ptr());
+    float* ptr2 = static_cast<float*>(Buf2.ptr());
+    float* ptr4 = static_cast<float*>(Buf4.ptr());
+    float* ptr6 = static_cast<float*>(Buf6.ptr());
+
+    printf("Address of Buf1 is %p\n", Buf1.ptr()); 
+    printf("Address of Buf2 is %p\n", Buf2.ptr());  
+    printf("Address of Buf4 is %p\n", Buf4.ptr());  
+
+    for (int i = 0; i < 10; i++)
     {
-        ptr[i] = float(i);
+        ptr1[i] = float(i);
+        ptr2[i] = float(i);
+        ptr4[i] = float(i);
+        ptr6[i] = float(i);
     }
+
+    return 0;
 }
\ No newline at end of file
-- 
GitLab