[UnitTest/Mem] revise memory allocator and add its unittests
authorDongju Chae <dongju.chae@samsung.com>
Thu, 16 Apr 2020 04:14:48 +0000 (13:14 +0900)
committer송욱/On-Device Lab(SR)/Staff Engineer/삼성전자 <wook16.song@samsung.com>
Thu, 16 Apr 2020 08:08:01 +0000 (17:08 +0900)
This patch revises memory allocator and add its unittests

Signed-off-by: Dongju Chae <dongju.chae@samsung.com>
src/core/ne-mem.cc
src/core/ne-mem.h
tests/unittests/meson.build
tests/unittests/ne_core_mem_test.cc [new file with mode: 0644]
tests/unittests/ne_core_mem_test.cpp [deleted file]

index d661260..65b5ef7 100644 (file)
@@ -33,8 +33,8 @@ class MemDefault : public MemAllocator {
       return hwmem;
     }
 
-    void deallocMemory (int dmabuf_fd) {
-      api_->dealloc (dmabuf_fd);
+    int deallocMemory (int dmabuf_fd) {
+      return api_->dealloc (dmabuf_fd);
     }
 
     /** For internal npu-engine components */
@@ -68,10 +68,12 @@ MemAllocator::createInstance (const DriverAPI *api)
 {
   std::unique_ptr<MemAllocator> mem;
 
-  if (Conf::getInstance().getResvMemSize() > 0)
-    mem.reset (new MemPool (api));
-  else
-    mem.reset (new MemDefault (api));
+  if (api != nullptr) {
+    if (Conf::getInstance().getResvMemSize() > 0)
+      mem.reset (new MemPool (api));
+    else
+      mem.reset (new MemDefault (api));
+  }
 
   return mem;
 }
index 596076a..9b69118 100644 (file)
@@ -41,7 +41,7 @@ class MemAllocator {
     virtual ~MemAllocator () {}
 
     virtual HWmem* allocMemory () { return nullptr; }
-    virtual void deallocMemory (int dmabuf) {};
+    virtual int deallocMemory (int dmabuf) { return -EINVAL; }
 
     virtual Model* allocModel () { return nullptr; }
     virtual Buffer * allocBuffer () { return nullptr; }
index 61094f0..5aff034 100644 (file)
@@ -42,15 +42,15 @@ if gtest_dep.found()
 #  )
 #  test('unittest_ne_core_handler', unittest_ne_core_handler)
 #
-#  unittest_ne_core_mem = executable('unittest_ne_core_mem',
-#    ['ne_core_mem_test.cpp'],
-#    dependencies: [gtest_dep, ne_core_dep],
-#    install : true,
-#    install_rpath : ne_libdir,
-#    install_dir : join_paths(ne_bindir, 'unittests')
-#  )
-#  test('unittest_ne_core_mem', unittest_ne_core_mem)
-#
+  unittest_ne_core_mem = executable('unittest_ne_core_mem',
+    ['ne_core_mem_test.cc'],
+    dependencies: [gtest_dep, ne_core_dep],
+    install : true,
+    install_rpath : ne_libdir,
+    install_dir : join_paths(ne_bindir, 'unittests')
+  )
+  test('unittest_ne_core_mem', unittest_ne_core_mem)
+
   unittest_ne_core_inf = executable('unittest_ne_core_inf',
     ['ne_core_inf_test.cc'],
     include_directories: ne_host_inc,
diff --git a/tests/unittests/ne_core_mem_test.cc b/tests/unittests/ne_core_mem_test.cc
new file mode 100644 (file)
index 0000000..aa7db8e
--- /dev/null
@@ -0,0 +1,107 @@
+/**
+ * Proprietary
+ * Copyright (C) 2019 Samsung Electronics
+ * Copyright (C) 2019 Dongju Chae <dongju.chae@samsung.com>
+ */
+/**
+ * @file ne_core_mem_test.cc
+ * @date 30 Jun 2019
+ * @brief UnitTests to test functions in memory allocator for NPU Engine
+ * @author Dongju Chae <dongju.chae@samsung.com>
+ * @bug No known bugs except for NYI items
+ */
+
+#include <ne-mem.h>
+#include <ne-conf.h>
+
+#include "ne_unittest_utils.h"
+
+#define K (1 << 10)
+#define M (1 << 20)
+
+/**
+ * @brief test primitives of memory allocator default (MemDefault)
+ */
+TEST (ne_core_mem_test, mem_default_primitives)
+{
+  std::unique_ptr<DriverAPI> api = DriverAPI::createDriverAPI (NPUCOND_TRIV_CONN_SOCIP, 0);
+  ASSERT_NE (api.get (), nullptr);
+
+  /**
+   * 'resv_mem_size' decides which memory allocator will be used.
+   * 'resv_mem_size' = 0: MemDefault.
+   */
+  ASSERT_EQ (setenv ("NE_RESV_MEM_SIZE", "0", 1), 0);
+  ASSERT_EQ (Conf::getInstance ().getResvMemSize (), 0);
+
+  std::unique_ptr<MemAllocator> mem = MemAllocator::createInstance (api.get ());
+  EXPECT_NE (mem.get (), nullptr);
+
+  HWmem * hwmem = mem->allocMemory ();
+  EXPECT_NE (hwmem, nullptr);
+  EXPECT_EQ (hwmem->alloc (4 * K), 0);
+  EXPECT_GE (hwmem->getDmabuf (), 0);
+  EXPECT_EQ (mem->deallocMemory (hwmem->getDmabuf ()), 0);
+  delete hwmem;
+
+  Model * model = mem->allocModel ();
+  EXPECT_NE (model, nullptr);
+  delete model;
+
+  Buffer * buffer = mem->allocBuffer ();
+  EXPECT_NE (buffer, nullptr);
+  delete buffer;
+}
+
+/**
+ * @brief test primitives of memory allocator (unimplemented)
+ */
+TEST (ne_core_mem_test, mem_pool_primitives_n)
+{
+  std::unique_ptr<DriverAPI> api = DriverAPI::createDriverAPI (NPUCOND_TRIV_CONN_SOCIP, 0);
+  ASSERT_NE (api.get (), nullptr);
+
+  /** 'resv_mem_size' > 0: MemPool (not implemented yet) */
+  ASSERT_EQ (setenv ("NE_RESV_MEM_SIZE", "2M", 1), 0);
+  ASSERT_EQ (Conf::getInstance ().getResvMemSize (), 2 * M);
+
+  std::unique_ptr<MemAllocator> mem = MemAllocator::createInstance (api.get ());
+  EXPECT_NE (mem.get (), nullptr);
+
+  EXPECT_EQ (mem->allocMemory (), nullptr);
+  EXPECT_NE (mem->deallocMemory (0), 0);
+  EXPECT_EQ (mem->allocModel (), nullptr);
+  EXPECT_EQ (mem->allocBuffer (), nullptr);
+}
+
+/**
+ * @brief test createInstance() with error handling
+ */
+TEST (ne_core_mem_test, create_instance_no_api_n)
+{
+  std::unique_ptr<MemAllocator> mem = MemAllocator::createInstance (nullptr);
+  EXPECT_EQ (mem.get (), nullptr);
+}
+
+/**
+ * @brief test deallocMemory () with error handling
+ */
+TEST (ne_core_mem_test, dealloc_memory_no_dmabuf_n)
+{
+  std::unique_ptr<DriverAPI> api = DriverAPI::createDriverAPI (NPUCOND_TRIV_CONN_SOCIP, 0);
+  ASSERT_NE (api.get (), nullptr);
+  std::unique_ptr<MemAllocator> mem = MemAllocator::createInstance (api.get ());
+  EXPECT_NE (mem.get (), nullptr);
+
+  EXPECT_NE (mem->deallocMemory (0), 0);
+  EXPECT_NE (mem->deallocMemory (1), 0);
+}
+
+/**
+ * @brief main function for unit test
+ */
+int
+main (int argc, char **argv)
+{
+  return start_gtest (argc, argv);
+}
diff --git a/tests/unittests/ne_core_mem_test.cpp b/tests/unittests/ne_core_mem_test.cpp
deleted file mode 100644 (file)
index 5694093..0000000
+++ /dev/null
@@ -1,633 +0,0 @@
-/**
- * Proprietary
- * Copyright (C) 2019 Samsung Electronics
- * Copyright (C) 2019 Dongju Chae <dongju.chae@samsung.com>
- */
-/**
- * @file ne_core_mem_test.cpp
- * @date 30 Jun 2019
- * @brief UnitTests to test functions in memory allocator for NPU Engine
- * @author Dongju Chae <dongju.chae@samsung.com>
- * @bug No known bugs except for NYI items
- */
-
-#include <unistd.h>
-#include <sys/mman.h>
-#include <gtest/gtest.h>
-#include <poll.h>
-
-/** below are internal C-headers */
-extern "C"
-{
-  #include <ne-mem.h>
-  #include <ne-conf.h>
-}
-
-#define K (1 << 10)
-#define M (1 << 20)
-
-/**
- * The below tests N7/8's behaviors in Activity Sequences
- * (suprem.sec.samsung.net/confluence/display/ODLC/ActSeq+Host-Input+Mode,+Normal+and+Easy)
- */
-
-/**
- * @brief register NPU model using internal memory pool
- * @detail The memory size of model and I/O buffer will be provided as arguments
- */
-TEST (ne_core_mem_test, register_model_internal)
-{
-  mem *mem = GET_MEM ();
-  hwmem *hwmem;
-  uint64_t slice_size;
-  uint64_t pool_size;
-
-  mem->cleanup();
-
-  ASSERT_EQ (mem->get_pool_size(), conf->reserved_mem_size);
-  ASSERT_EQ (mem->get_used_size(), 0);
-
-  mem->fini();
-  mem->init(10 * M, &pool_size); /* use INTERNAL */
-
-  slice_size = mem->get_pool_size() / 10;
-
-  /* check available memory size and allocate memory for the model */
-  ASSERT_NE (mem->alloc (slice_size * 11, &hwmem), 0);
-  ASSERT_EQ (mem->alloc (slice_size * 5, &hwmem), 0);
-  ASSERT_EQ (hwmem->size, slice_size * 5);
-  ASSERT_EQ (mem->get_used_size(), slice_size * 5);
-
-  /* check hwmem resize */
-  ASSERT_NE (mem->realloc (hwmem, slice_size * 11), 0);
-  ASSERT_EQ (mem->realloc (hwmem, slice_size * 7), 0);
-  ASSERT_EQ (hwmem->size, slice_size * 7);
-  ASSERT_EQ (mem->get_used_size(), slice_size * 7);
-
-#ifdef ENABLE_BUFFERING
-  /* config I/O buffer size (>= 3x size for triple buffering) */
-  ASSERT_EQ (mem->resize_buffers (slice_size), 0);
-  ASSERT_EQ (mem->get_used_size(), slice_size * 7 + slice_size * 3);
-  ASSERT_EQ (mem->resize_buffers (slice_size / 2), 0);
-  ASSERT_EQ (mem->get_used_size(), slice_size * 7 + (slice_size / 2) * 3);
-  ASSERT_NE (mem->resize_buffers (slice_size * 2), 0);
-  ASSERT_EQ (mem->resize_buffers (0), 0);
-  ASSERT_EQ (mem->get_used_size(), slice_size * 7);
-#endif
-
-  mem->dealloc (hwmem);
-  ASSERT_EQ (mem->get_used_size(), 0);
-
-  mem->fini();
-
-  /* rollback */
-  mem->init (conf->reserved_mem_size, &pool_size);
-}
-
-/**
- * @brief register NPU model using kernel cma allocator
- * @detail The memory size of model and I/O buffer will be provided as arguments
- */
-TEST (ne_core_mem_test, register_model_kernel_cma)
-{
-  mem *mem = GET_MEM ();
-  hwmem *hwmem;
-  uint64_t slice_size;
-  uint64_t pool_size;
-
-  mem->cleanup();
-
-  ASSERT_EQ (mem->get_pool_size(), conf->reserved_mem_size);
-  ASSERT_EQ (mem->get_used_size(), 0);
-
-  mem->fini();
-  mem->init(0, &pool_size); /* use KERNEL_CMA */
-
-  ASSERT_EQ (mem->get_pool_size(), 0);
-  ASSERT_EQ (mem->get_used_size(), 0);
-
-  slice_size = 1 * M;
-
-  /* check available memory size and allocate memory for the model */
-  ASSERT_EQ (mem->alloc (slice_size * 5, &hwmem), 0);
-  ASSERT_EQ (hwmem->size, slice_size * 5);
-  ASSERT_EQ (mem->get_used_size(), slice_size * 5);
-
-  /* check hwmem resize */
-  ASSERT_EQ (mem->realloc (hwmem, slice_size * 7), 0);
-  ASSERT_EQ (hwmem->size, slice_size * 7);
-  ASSERT_EQ (mem->get_used_size(), slice_size * 7);
-
-#ifdef ENABLE_BUFFERING
-  /* config I/O buffer size (>= 3x size for triple buffering) */
-  ASSERT_EQ (mem->resize_buffers (slice_size), 0);
-  ASSERT_EQ (mem->get_used_size(), slice_size * 7 + slice_size * 3);
-  ASSERT_EQ (mem->resize_buffers (slice_size / 2), 0);
-  ASSERT_EQ (mem->get_used_size(), slice_size * 7 + (slice_size / 2) * 3);
-  ASSERT_EQ (mem->resize_buffers (0), 0);
-  ASSERT_EQ (mem->get_used_size(), slice_size * 7);
-#endif
-
-  mem->dealloc (hwmem);
-  ASSERT_EQ (mem->get_used_size(), 0);
-
-  mem->fini();
-
-  /* rollback */
-  mem->init (conf->reserved_mem_size, &pool_size);
-}
-
-#ifdef ENABLE_BUFFERING
-/**
- * @brief prepare input buffer
- */
-TEST (ne_core_mem_test, prepare_input)
-{
-  mem *mem = GET_MEM ();
-  buffer *buffer;
-  hwmem *hwmem;
-  uint64_t buf_size = 1 * K;
-  uint64_t *ptr, i;
-  int err;
-
-  mem->cleanup();
-
-  ASSERT_EQ (mem->get_pool_size(), conf->reserved_mem_size);
-  ASSERT_EQ (mem->get_used_size(), 0);
-
-  ASSERT_EQ (mem->resize_buffers (buf_size), 0);
-
-  /* get an input buffer & write contents into there */
-  buffer = mem->get_next_buffer (NPUASYNC_WAIT, BUFFER_ROLE_INPUT, &err);
-  ASSERT_EQ (buffer_get_state(buffer), BUFFER_STATE_INPUT_WRITING);
-
-  ASSERT_EQ (buffer_get_hwmem (buffer, &hwmem), 0);
-  ASSERT_EQ (hwmem_get_data (hwmem, (void **) &ptr), 0);
-
-  for (i = 0; i < buffer->size; i += sizeof (uint64_t)) {
-    ptr[i / sizeof (uint64_t)] = i;
-  }
-
-  mem->return_buffer (buffer);
-
-  /* In this time, this buffer is ready for N4 and N4x */
-  buffer = mem->get_next_buffer (NPUASYNC_WAIT, BUFFER_ROLE_NPU, &err);
-
-  /* get another buffer for the next frame */
-  buffer = mem->get_next_buffer (NPUASYNC_WAIT, BUFFER_ROLE_INPUT, &err);
-
-  ASSERT_EQ (buffer_get_state(buffer), BUFFER_STATE_INPUT_WRITING);
-}
-
-/**
- * @brief when output is ready (in a syncronized manner)
- */
-TEST (ne_core_mem_test, output_ready)
-{
-  mem *mem = GET_MEM ();
-  buffer *buffer;
-  uint64_t buf_size = 1 * K;
-  int err;
-
-  mem->cleanup();
-
-  ASSERT_EQ (mem->get_pool_size(), conf->reserved_mem_size);
-
-  ASSERT_EQ (mem->resize_buffers (buf_size), 0);
-
-  /* frame 1 */
-  /* N1) feed input data into buffer */
-  buffer = mem->get_next_buffer (NPUASYNC_WAIT, BUFFER_ROLE_INPUT, &err);
-  ASSERT_EQ (buffer_get_state(buffer), BUFFER_STATE_INPUT_WRITING);
-
-  /* assume that input is being written */
-
-  /* ... */
-
-  /* it's now validated */
-  mem->return_buffer (buffer);
-
-  /* N4) input data is ready; and NPU can perform the processing */
-  buffer = mem->get_next_buffer (NPUASYNC_WAIT, BUFFER_ROLE_NPU, &err);
-  ASSERT_EQ (buffer_get_state(buffer), BUFFER_STATE_NPU_RUNNING);
-
-  /* the host will call runNPUasync() */
-
-  /* ... */
-
-  /**
-   * Then, let's assume the event from the kernel is delivered
-   * if post processing is required, validate the buffer after post processing
-   */
-
-  /* ... */
-
-  mem->return_buffer (buffer);
-
-  /* N1) it's time to return output data to the host */
-  buffer = mem->get_next_buffer (NPUASYNC_WAIT, BUFFER_ROLE_OUTPUT, &err);
-  ASSERT_EQ (buffer_get_state(buffer), BUFFER_STATE_OUTPUT_RETURN);
-
-  /* after transmitting the output to HOST, it's no longer used */
-
-  /* ... */
-
-  mem->return_buffer (buffer);
-
-  /* frame 2; same behaviors */
-  buffer = mem->get_next_buffer (NPUASYNC_WAIT, BUFFER_ROLE_INPUT, &err);
-  ASSERT_EQ (buffer_get_state(buffer), BUFFER_STATE_INPUT_WRITING);
-
-  /* ... */
-  mem->return_buffer (buffer);
-}
-
-/**
- * @brief input thread with input buffer
- */
-static void *
-input_thread (void* data)
-{
-  mem *mem = GET_MEM ();
-  buffer *buffer;
-  int i, num_frames = *(int *) data;
-  int err;
-
-  for (i = 0; i < num_frames; i++) {
-    buffer = mem->get_next_buffer (NPUASYNC_WAIT, BUFFER_ROLE_INPUT, &err);
-    if (buffer != NULL) {
-      EXPECT_EQ (buffer_get_state(buffer), BUFFER_STATE_INPUT_WRITING);
-
-      /* Input data will be written in the buffer */
-
-      /* ... */
-
-      mem->return_buffer (buffer);
-    }
-  }
-
-  return NULL;
-}
-
-/**
- * @brief npu thread with npu buffer
- */
-static void *
-npu_thread (void* data)
-{
-  mem *mem = GET_MEM ();
-  buffer *buffer;
-  int i, num_frames = *(int *) data;
-  int err;
-
-  for (i = 0; i < num_frames; i++) {
-
-    buffer = mem->get_next_buffer (NPUASYNC_WAIT, BUFFER_ROLE_NPU, &err);
-    if (buffer != NULL) {
-      EXPECT_EQ (buffer_get_state(buffer), BUFFER_STATE_NPU_RUNNING);
-
-      /* NPU will read/write data in the buffer */
-
-      /* ... */
-
-      mem->return_buffer (buffer);
-    }
-  }
-
-  return NULL;
-}
-
-/**
- * @brief output thread with output buffer
- */
-static void *
-output_thread (void* data)
-{
-  mem *mem = GET_MEM ();
-  buffer *buffer;
-  int i, num_frames = *(int *) data;
-  int err;
-
-  for (i = 0; i < num_frames; i++) {
-    buffer = mem->get_next_buffer (NPUASYNC_WAIT, BUFFER_ROLE_OUTPUT, &err);
-    if (buffer != NULL) {
-      EXPECT_EQ (buffer_get_state(buffer), BUFFER_STATE_OUTPUT_RETURN);
-
-      /* Output will be delivered to the host */
-
-      /* ... */
-
-      mem->return_buffer (buffer);
-    }
-  }
-
-  return NULL;
-}
-
-/**
- * @brief running in parallel with fork()
- */
-TEST (ne_core_mem_test, running_parallel)
-{
-  mem *mem = GET_MEM ();
-  uint64_t buf_size = 1 * K;
-  int status, num_frames = 10;
-  pthread_t thread[3];
-
-  mem->cleanup();
-
-  ASSERT_EQ (mem->get_pool_size(), conf->reserved_mem_size);
-  ASSERT_EQ (mem->get_used_size(), 0);
-
-  ASSERT_EQ (mem->resize_buffers (buf_size), 0);
-
-  pthread_create (&thread[0], NULL, input_thread, (void*) (&num_frames));
-  pthread_create (&thread[1], NULL, npu_thread, (void*) (&num_frames));
-  pthread_create (&thread[2], NULL, output_thread, (void*) (&num_frames));
-
-  pthread_join (thread[0], (void **)&status);
-  pthread_join (thread[1], (void **)&status);
-  pthread_join (thread[2], (void **)&status);
-}
-#endif
-
-/**
- * @brief test for memory compaction
- */
-TEST (ne_core_mem_test, memory_compaction)
-{
-  mem *mem = GET_MEM ();
-  hwmem *hwmem[6];
-  uint64_t slice_size, offset;
-
-  mem->cleanup();
-
-  ASSERT_EQ (mem->get_pool_size(), conf->reserved_mem_size);
-
-  /* it's only for INTERNAL compaction */
-  if (mem->get_pool_size() == 0)
-    return;
-
-  slice_size = mem->get_pool_size() / 10;
-
-  /**
-   * compaction scenario 1 (each star denotes 100K memory block)
-   * check whether compaction can move or shift it to free slots
-   *               BOTTOM           TOP
-   * original      : [*|**|*|***|**|*]
-   * after dealloc : [ |**| |***|  |*]
-   * after compact : [*|**|***|      ]
-   */
-
-  ASSERT_EQ (mem->alloc (slice_size * 1, &hwmem[0]), 0);
-  ASSERT_EQ (mem->alloc (slice_size * 2, &hwmem[1]), 0);
-  ASSERT_EQ (mem->alloc (slice_size * 1, &hwmem[2]), 0);
-  ASSERT_EQ (mem->alloc (slice_size * 3, &hwmem[3]), 0);
-  ASSERT_EQ (mem->alloc (slice_size * 2, &hwmem[4]), 0);
-  ASSERT_EQ (mem->alloc (slice_size * 1, &hwmem[5]), 0); /* full */
-
-  /* make some fragmentations */
-  mem->dealloc (hwmem[0]);
-  mem->dealloc (hwmem[2]);
-  mem->dealloc (hwmem[4]);
-
-  /* do compaction & allocate again */
-  ASSERT_EQ (mem->alloc (slice_size * 4, &hwmem[0]), 0);
-  ASSERT_EQ (hwmem_get_offset (hwmem[0], &offset), 0);
-  ASSERT_EQ (offset, slice_size * 6);
-
-  mem->dealloc (hwmem[0]);
-  mem->dealloc (hwmem[1]);
-  mem->dealloc (hwmem[3]);
-  mem->dealloc (hwmem[5]);
-
-  /**
-   * compaction scenario 2 (each star denotes 100K memory block)
-   * check it's merged with left/right chunks
-   *               BOTTOM           TOP
-   * original      : [*|**|***|*|*|**]
-   * after dealloc : [ |**|   |*|    ]
-   * after compact : [*|**|          ]
-   */
-
-  ASSERT_EQ (mem->alloc (slice_size * 1, &hwmem[0]), 0);
-  ASSERT_EQ (mem->alloc (slice_size * 2, &hwmem[1]), 0);
-  ASSERT_EQ (mem->alloc (slice_size * 3, &hwmem[2]), 0);
-  ASSERT_EQ (mem->alloc (slice_size * 1, &hwmem[3]), 0);
-  ASSERT_EQ (mem->alloc (slice_size * 1, &hwmem[4]), 0);
-  ASSERT_EQ (mem->alloc (slice_size * 2, &hwmem[5]), 0); /* full */
-
-  /* make some fragmentations */
-  mem->dealloc (hwmem[0]);
-  mem->dealloc (hwmem[2]);
-  mem->dealloc (hwmem[4]);
-  mem->dealloc (hwmem[5]);
-
-  /* do compaction & allocate again */
-  ASSERT_EQ (mem->alloc (slice_size * 7, &hwmem[0]), 0 );
-  ASSERT_EQ (hwmem_get_offset (hwmem[0], &offset), 0);
-  ASSERT_EQ (offset, slice_size * 3);
-
-  mem->dealloc (hwmem[0]);
-  mem->dealloc (hwmem[1]);
-  mem->dealloc (hwmem[3]);
-}
-
-#ifdef ENABLE_BUFFERING
-/**
- * @brief data struct to pass mode and sync primitive to helper thread */
-typedef struct {
-  pthread_mutex_t * mutex;    /**< synchronization primitive */
-  npu_async_mode mode;        /**< async mode for this thread to use */
-} thread_modes;
-
-/**
- * @brief helper thread for waiting for input processing
- */
-static void *
-get_buffer_wait_thread (void *data)
-{
-  mem *mem = GET_MEM ();
-  buffer *buffer;
-  int err;
-  thread_modes *mode;
-
-  mode = (thread_modes *) data;
-  pthread_mutex_lock (mode->mutex);
-
-  buffer = mem->get_next_buffer (mode->mode, BUFFER_ROLE_INPUT, &err);
-  EXPECT_EQ (buffer_get_state(buffer), BUFFER_STATE_INPUT_WRITING);
-
-  /** cleanup */
-
-  /* frame 1, return to INPUT_READY */
-  mem->return_buffer (buffer);
-  /* frame 1, return to NPU_RUNNING */
-  buffer = mem->get_next_buffer (NPUASYNC_WAIT, BUFFER_ROLE_NPU, &err);
-  EXPECT_EQ (buffer_get_state(buffer), BUFFER_STATE_NPU_RUNNING);
-  /* frame 1, return to OUPUT_READY*/
-  mem->return_buffer (buffer);
-  buffer = mem->get_next_buffer (NPUASYNC_WAIT, BUFFER_ROLE_OUTPUT, &err);
-  EXPECT_EQ (buffer_get_state(buffer), BUFFER_STATE_OUTPUT_RETURN);
-  /* frame 1, return to EMPTY */
-  mem->return_buffer (buffer);
-
-  pthread_mutex_unlock (mode->mutex);
-  return NULL;
-}
-
-/**
- * @brief test handling input priorities and synchronization for memory
- */
-TEST (ne_core_mem_test, get_next_buffer_modes)
-{
-  mem *mem = GET_MEM ();
-  buffer *buffer1, *buffer2;
-  uint64_t buf_size = 1 * K;
-  int err;
-  pthread_t thread;
-  pthread_mutex_t mutex1;
-  thread_modes th_mode;
-
-  mem->cleanup();
-
-  ASSERT_EQ (mem->get_pool_size(), conf->reserved_mem_size);
-  ASSERT_EQ (mem->get_used_size(), 0);
-
-  ASSERT_EQ (pthread_mutex_init (&mutex1, NULL), 0);
-
-  ASSERT_EQ (mem->resize_buffers (buf_size), 0);
-
-  /**
-   * After return_buffer(), we cannot ensure the buffer state because it no longer
-   * has the ownership of returned buffers. So, state checking after return_buffer()
-   * may provide unexpected values if there are co-running threads. Thus, we should
-   * check buffer states only after get_next_buffer().
-   */
-
-  /** WAIT */
-
-  /* frame 1 */
-  /* get input buffer, basic case */
-  buffer1 = mem->get_next_buffer (NPUASYNC_WAIT, BUFFER_ROLE_INPUT, &err);
-  EXPECT_EQ (buffer_get_state(buffer1), BUFFER_STATE_INPUT_WRITING);
-
-  /* frame 2 */
-  /**
-   * get input buffer, which is not available, so this will block till its
-   * available
-   */
-  th_mode.mutex = &mutex1;
-  th_mode.mode = NPUASYNC_WAIT;
-  pthread_create (&thread, NULL, get_buffer_wait_thread, (void *) &th_mode);
-
-  /** wait for a few seconds ensuring that other thread is still waiting */
-  sleep (2);
-  EXPECT_NE(pthread_mutex_trylock (&mutex1), 0);
-
-  /* frame 1, return to INPUT_READY */
-  mem->return_buffer (buffer1);
-  /* frame 1, return to NPU_RUNNING */
-  buffer1 = mem->get_next_buffer (NPUASYNC_WAIT, BUFFER_ROLE_NPU, &err);
-  EXPECT_EQ (buffer_get_state(buffer1), BUFFER_STATE_NPU_RUNNING);
-
-  /* frame 1, return to OUPUT_READY*/
-  mem->return_buffer (buffer1);
-  buffer1 = mem->get_next_buffer (NPUASYNC_WAIT, BUFFER_ROLE_OUTPUT, &err);
-  EXPECT_EQ (buffer_get_state(buffer1), BUFFER_STATE_OUTPUT_RETURN);
-  /* frame 1, return to EMPTY */
-  mem->return_buffer (buffer1);
-
-  /** input buffer is free now, so the other thread can proceed */
-  pthread_join (thread, nullptr);
-
-  /** DROP_OLD */
-
-  /* frame 1 */
-  /* get input buffer, basic case */
-  buffer1 = mem->get_next_buffer (NPUASYNC_WAIT, BUFFER_ROLE_INPUT, &err);
-  EXPECT_EQ (buffer_get_state(buffer1), BUFFER_STATE_INPUT_WRITING);
-
-  /* frame 2 */
-  /**
-   * get input buffer, which is not available, so this will block till its
-   * available
-   */
-  th_mode.mutex = &mutex1;
-  th_mode.mode = NPUASYNC_DROP_OLD;
-  pthread_create (&thread, NULL, get_buffer_wait_thread, (void *) &th_mode);
-
-  /** wait for a few seconds ensuring that other thread is still waiting */
-  sleep (2);
-  EXPECT_NE(pthread_mutex_trylock (&mutex1), 0);
-
-  /* frame 1, return to INPUT_READY */
-  mem->return_buffer (buffer1);
-
-  /** input buffer is free now, so the other thread can proceed */
-  pthread_join (thread, nullptr);
-
-  /** no cleanup required as this buffer has been dropped */
-
-  /** DROP_NEW */
-
-  /** WAIT */
-
-  /* frame 1 */
-  /* get input buffer, basic case */
-  buffer1 = mem->get_next_buffer (NPUASYNC_WAIT, BUFFER_ROLE_INPUT, &err);
-  EXPECT_EQ (buffer_get_state(buffer1), BUFFER_STATE_INPUT_WRITING);
-
-  /* frame 2 */
-  /* get input buffer, which is not available, so we drop new buffer */
-  buffer2 = mem->get_next_buffer (NPUASYNC_DROP_NEW, BUFFER_ROLE_INPUT, &err);
-  EXPECT_EQ (buffer2, nullptr);
-  EXPECT_EQ (buffer_get_state(buffer1), BUFFER_STATE_INPUT_WRITING);
-
-  /* frame 1, return to INPUT_READY */
-  mem->return_buffer (buffer1);
-
-  /* frame 2 */
-  /* get input buffer, which is not available, so we drop new buffer */
-  buffer2 = mem->get_next_buffer (NPUASYNC_DROP_NEW, BUFFER_ROLE_INPUT, &err);
-  EXPECT_EQ (buffer2, nullptr);
-
-  /* frame 1, return to NPU_RUNNING */
-  buffer1 = mem->get_next_buffer (NPUASYNC_WAIT, BUFFER_ROLE_NPU, &err);
-  EXPECT_EQ (buffer_get_state(buffer1), BUFFER_STATE_NPU_RUNNING);
-
-  /* frame 2 */
-  /* get input buffer, which is available, so no drop */
-  buffer2 = mem->get_next_buffer (NPUASYNC_DROP_NEW, BUFFER_ROLE_INPUT, &err);
-  EXPECT_EQ (buffer_get_state(buffer2), BUFFER_STATE_INPUT_WRITING);
-
-  /* frame 1, return to OUPUT_READY*/
-  mem->return_buffer (buffer1);
-  buffer1 = mem->get_next_buffer (NPUASYNC_WAIT, BUFFER_ROLE_OUTPUT, &err);
-  EXPECT_EQ (buffer_get_state(buffer1), BUFFER_STATE_OUTPUT_RETURN);
-  /* frame 1, return to EMPTY */
-  mem->return_buffer (buffer1);
-
-  /** cleanup frame 2 */
-  mem->return_buffer (buffer2);
-  buffer2 = mem->get_next_buffer (NPUASYNC_WAIT, BUFFER_ROLE_NPU, &err);
-  EXPECT_EQ (buffer_get_state(buffer2), BUFFER_STATE_NPU_RUNNING);
-  mem->return_buffer (buffer2);
-  buffer2 = mem->get_next_buffer (NPUASYNC_WAIT, BUFFER_ROLE_OUTPUT, &err);
-  EXPECT_EQ (buffer_get_state(buffer2), BUFFER_STATE_OUTPUT_RETURN);
-  mem->return_buffer (buffer2);
-
-  pthread_mutex_destroy (&mutex1);
-}
-#endif
-
-/**
- * @brief main function for unit test
- */
-int
-main (int argc, char **argv)
-{
-  testing::InitGoogleTest (&argc, argv);
-
-  return RUN_ALL_TESTS();
-}