Merge pull request #133 from arutk/ajrutkow_async_counters

Extended reference counting
This commit is contained in:
Robert Bałdyga
2019-05-08 14:23:50 +02:00
committed by GitHub
25 changed files with 905 additions and 297 deletions

View File

@@ -302,7 +302,7 @@ class Cache:
@classmethod
def start_on_device(cls, device, **kwargs):
c = cls(locked=True, owner=device.owner, **kwargs)
c = cls(owner=device.owner, **kwargs)
c.start_cache()
try:
@@ -482,7 +482,6 @@ class Cache:
[("cache", c_void_p), ("priv", c_void_p), ("error", c_int)]
)
self.owner.lib.ocf_cache_wait_for_io_finish(self.cache_handle)
self.owner.lib.ocf_mngt_cache_stop(self.cache_handle, c, None)
c.wait()
@@ -495,7 +494,6 @@ class Cache:
self.started = False
self.put_and_write_unlock()
self.put()
self.owner.caches.remove(self)

View File

@@ -188,7 +188,7 @@ void __wrap__ocf_mngt_attach_post_init(
{
}
void __wrap_ocf_mngt_cache_stop_wait_io(
void __wrap_ocf_mngt_cache_stop_wait_metadata_io(
ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg)
{
}
@@ -213,6 +213,17 @@ void __wrap_ocf_mngt_cache_detach_flush(
{
}
void ocf_mngt_cache_detach_stop_cache_io(ocf_pipeline_t pipeline,
void *priv, ocf_pipeline_arg_t arg)
{
}
void ocf_mngt_cache_detach_stop_cleaner_io(ocf_pipeline_t pipeline,
void *priv, ocf_pipeline_arg_t arg)
{
}
void __wrap_ocf_mngt_cache_detach_wait_pending(
ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg)
{

View File

@@ -145,7 +145,7 @@ void __wrap__ocf_mngt_attach_post_init(
{
}
void __wrap_ocf_mngt_cache_stop_wait_io(
void __wrap_ocf_mngt_cache_stop_wait_metadata_io(
ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg)
{
}
@@ -170,6 +170,16 @@ void __wrap_ocf_mngt_cache_detach_flush(
{
}
void __wrap_ocf_mngt_cache_detach_stop_cache_io(ocf_pipeline_t pipeline,
void *priv, ocf_pipeline_arg_t arg)
{
}
void ocf_mngt_cache_detach_stop_cleaner_io(ocf_pipeline_t pipeline,
void *priv, ocf_pipeline_arg_t arg)
{
}
void __wrap_ocf_mngt_cache_detach_wait_pending(
ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg)
{

View File

@@ -0,0 +1,62 @@
/*
* <tested_file_path>src/utils/utils_refcnt.c</tested_file_path>
* <tested_function>ocf_refcnt_dec</tested_function>
* <functions_to_leave>
* ocf_refcnt_init
* ocf_refcnt_inc
* </functions_to_leave>
*/
#undef static
#undef inline
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include "print_desc.h"
#include "../utils/utils_refcnt.h"
static void ocf_refcnt_dec_test01(void **state)
{
struct ocf_refcnt rc;
int val, val2;
print_test_description("Decrement subtracts 1 and returns proper value");
ocf_refcnt_init(&rc);
ocf_refcnt_inc(&rc);
ocf_refcnt_inc(&rc);
ocf_refcnt_inc(&rc);
val = ocf_refcnt_dec(&rc);
assert_int_equal(2, val);
val2 = env_atomic_read(&rc.counter);
assert_int_equal(2, val2);
val = ocf_refcnt_dec(&rc);
assert_int_equal(1, val);
val2 = env_atomic_read(&rc.counter);
assert_int_equal(1, val2);
val = ocf_refcnt_dec(&rc);
assert_int_equal(0, val);
val2 = env_atomic_read(&rc.counter);
assert_int_equal(0, val2);
}
int main(void)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test(ocf_refcnt_dec_test01)
};
print_message("Unit test of src/utils/utils_refcnt.c");
return cmocka_run_group_tests(tests, NULL, NULL);
}

View File

@@ -0,0 +1,116 @@
/*
* <tested_file_path>src/utils/utils_refcnt.c</tested_file_path>
* <tested_function>ocf_refcnt_freeze</tested_function>
* <functions_to_leave>
* ocf_refcnt_init
* ocf_refcnt_inc
* ocf_refcnt_dec
* </functions_to_leave>
*/
#undef static
#undef inline
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include "print_desc.h"
#include "../utils/utils_refcnt.h"
static void ocf_refcnt_freeze_test01(void **state)
{
struct ocf_refcnt rc;
int val;
print_test_description("Freeze increments freeze counter");
ocf_refcnt_init(&rc);
ocf_refcnt_freeze(&rc);
assert_int_equal(1, env_atomic_read(&rc.freeze));
ocf_refcnt_freeze(&rc);
assert_int_equal(2, env_atomic_read(&rc.freeze));
}
static void ocf_refcnt_freeze_test02(void **state)
{
struct ocf_refcnt rc;
int val;
print_test_description("Increment returns 0 for frozen counter");
ocf_refcnt_init(&rc);
ocf_refcnt_inc(&rc);
ocf_refcnt_inc(&rc);
ocf_refcnt_inc(&rc);
ocf_refcnt_freeze(&rc);
val = ocf_refcnt_inc(&rc);
assert_int_equal(0, val);
}
static void ocf_refcnt_freeze_test03(void **state)
{
struct ocf_refcnt rc;
int val, val2;
print_test_description("Freeze bocks increment");
ocf_refcnt_init(&rc);
val = ocf_refcnt_inc(&rc);
val = ocf_refcnt_inc(&rc);
val = ocf_refcnt_inc(&rc);
ocf_refcnt_freeze(&rc);
ocf_refcnt_inc(&rc);
val2 = env_atomic_read(&rc.counter);
assert_int_equal(val, val2);
}
static void ocf_refcnt_freeze_test04(void **state)
{
struct ocf_refcnt rc;
int val, val2;
print_test_description("Freeze allows decrement");
ocf_refcnt_init(&rc);
val = ocf_refcnt_inc(&rc);
val = ocf_refcnt_inc(&rc);
val = ocf_refcnt_inc(&rc);
ocf_refcnt_freeze(&rc);
val2 = ocf_refcnt_dec(&rc);
assert_int_equal(val2, val - 1);
val2 = ocf_refcnt_dec(&rc);
assert_int_equal(val2, val - 2);
}
int main(void)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test(ocf_refcnt_freeze_test01),
cmocka_unit_test(ocf_refcnt_freeze_test02),
cmocka_unit_test(ocf_refcnt_freeze_test03),
cmocka_unit_test(ocf_refcnt_freeze_test04),
};
print_message("Unit test of src/utils/utils_refcnt.c");
return cmocka_run_group_tests(tests, NULL, NULL);
}

View File

@@ -0,0 +1,51 @@
/*
* <tested_file_path>src/utils/utils_refcnt.c</tested_file_path>
* <tested_function>ocf_refcnt_inc</tested_function>
* <functions_to_leave>
* ocf_refcnt_init
* ocf_refcnt_dec
* </functions_to_leave>
*/
#undef static
#undef inline
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include "print_desc.h"
#include "../utils/utils_refcnt.h"
static void ocf_refcnt_inc_test(void **state)
{
struct ocf_refcnt rc;
int val;
print_test_description("Increment adds 1 and returns proper value");
ocf_refcnt_init(&rc);
val = ocf_refcnt_inc(&rc);
assert_int_equal(1, val);
assert_int_equal(1, env_atomic_read(&rc.counter));
val = ocf_refcnt_inc(&rc);
assert_int_equal(2, val);
assert_int_equal(2, env_atomic_read(&rc.counter));
}
int main(void)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test(ocf_refcnt_inc_test)
};
print_message("Unit test of src/utils/utils_refcnt.c");
return cmocka_run_group_tests(tests, NULL, NULL);
}

View File

@@ -0,0 +1,50 @@
/*
* <tested_file_path>src/utils/utils_refcnt.c</tested_file_path>
* <tested_function>ocf_refcnt_init</tested_function>
* <functions_to_leave>
* INSERT HERE LIST OF FUNCTIONS YOU WANT TO LEAVE
* ONE FUNCTION PER LINE
* </functions_to_leave>
*/
#undef static
#undef inline
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include "print_desc.h"
#include "../utils/utils_refcnt.h"
static void ocf_refcnt_init_test(void **state)
{
struct ocf_refcnt rc;
print_test_description("Reference counter is properly initialized");
env_atomic_set(&rc.counter, 1);
env_atomic_set(&rc.freeze, 1);
env_atomic_set(&rc.callback, 1);
ocf_refcnt_init(&rc);
assert_int_equal(0, env_atomic_read(&rc.counter));
assert_int_equal(0, env_atomic_read(&rc.freeze));
assert_int_equal(0, env_atomic_read(&rc.cb));
}
int main(void)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test(ocf_refcnt_init_test)
};
print_message("Unit test of src/utils/utils_refcnt.c");
return cmocka_run_group_tests(tests, NULL, NULL);
}

View File

@@ -0,0 +1,100 @@
/*
* <tested_file_path>src/utils/utils_refcnt.c</tested_file_path>
* <tested_function>ocf_refcnt_register_zero_cb</tested_function>
* <functions_to_leave>
* ocf_refcnt_init
* ocf_refcnt_inc
* ocf_refcnt_dec
* ocf_refcnt_freeze
* </functions_to_leave>
*/
#undef static
#undef inline
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include "print_desc.h"
#include "../utils/utils_refcnt.h"
static void zero_cb(void *ctx)
{
function_called();
check_expected_ptr(ctx);
}
static void ocf_refcnt_register_zero_cb_test01(void **state)
{
struct ocf_refcnt rc;
int val;
void *ptr = 0x12345678;
print_test_description("Callback fires when counter drops to 0");
/* cnt = 2 */
ocf_refcnt_init(&rc);
ocf_refcnt_inc(&rc);
ocf_refcnt_inc(&rc);
/* freeze and register cb */
ocf_refcnt_freeze(&rc);
ocf_refcnt_register_zero_cb(&rc, zero_cb, ptr);
/* 2 -> 1 */
ocf_refcnt_dec(&rc);
val = env_atomic_read(&rc.callback);
assert_int_equal(1, val);
/* expect callback now */
expect_function_calls(zero_cb, 1);
expect_value(zero_cb, ctx, ptr);
/* 1 -> 0 */
ocf_refcnt_dec(&rc);
val = env_atomic_read(&rc.callback);
assert_int_equal(0, val);
}
static void ocf_refcnt_register_zero_cb_test02(void **state)
{
struct ocf_refcnt rc;
int val;
void *ptr = 0x12345678;
print_test_description("Callback fires when counter is already 0");
/* cnt = 0 */
ocf_refcnt_init(&rc);
/* freeze */
ocf_refcnt_freeze(&rc);
/* expect callback now */
expect_function_calls(zero_cb, 1);
expect_value(zero_cb, ctx, ptr);
/* regiser callback */
ocf_refcnt_register_zero_cb(&rc, zero_cb, ptr);
val = env_atomic_read(&rc.callback);
assert_int_equal(0, val);
}
int main(void)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test(ocf_refcnt_register_zero_cb_test01),
cmocka_unit_test(ocf_refcnt_register_zero_cb_test02),
};
print_message("Unit test of src/utils/utils_refcnt.c");
return cmocka_run_group_tests(tests, NULL, NULL);
}

View File

@@ -0,0 +1,100 @@
/*
* <tested_file_path>src/utils/utils_refcnt.c</tested_file_path>
* <tested_function>ocf_refcnt_unfreeze</tested_function>
* <functions_to_leave>
* ocf_refcnt_init
* ocf_refcnt_inc
* ocf_refcnt_dec
* ocf_refcnt_freeze
* </functions_to_leave>
*/
#undef static
#undef inline
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include "print_desc.h"
#include "../utils/utils_refcnt.h"
static void ocf_refcnt_unfreeze_test01(void **state)
{
struct ocf_refcnt rc;
int val, val2;
print_test_description("Unfreeze decrements freeze counter");
ocf_refcnt_init(&rc);
ocf_refcnt_freeze(&rc);
ocf_refcnt_freeze(&rc);
val = env_atomic_read(&rc.freeze);
ocf_refcnt_unfreeze(&rc);
val2 = env_atomic_read(&rc.freeze);
assert_int_equal(val2, val - 1);
ocf_refcnt_unfreeze(&rc);
val2 = env_atomic_read(&rc.freeze);
assert_int_equal(val2, val - 2);
}
static void ocf_refcnt_unfreeze_test02(void **state)
{
struct ocf_refcnt rc;
int val, val2;
print_test_description("Unfreezed counter can be incremented");
ocf_refcnt_init(&rc);
val = ocf_refcnt_inc(&rc);
ocf_refcnt_freeze(&rc);
ocf_refcnt_unfreeze(&rc);
val2 = ocf_refcnt_inc(&rc);
assert_int_equal(val2, val + 1);
}
static void ocf_refcnt_unfreeze_test03(void **state)
{
struct ocf_refcnt rc;
int val, val2;
print_test_description("Two freezes require two unfreezes");
ocf_refcnt_init(&rc);
val = ocf_refcnt_inc(&rc);
ocf_refcnt_freeze(&rc);
ocf_refcnt_freeze(&rc);
ocf_refcnt_unfreeze(&rc);
val2 = ocf_refcnt_inc(&rc);
assert_int_equal(0, val2);
ocf_refcnt_unfreeze(&rc);
val2 = ocf_refcnt_inc(&rc);
assert_int_equal(val2, val + 1);
}
int main(void)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test(ocf_refcnt_unfreeze_test01),
cmocka_unit_test(ocf_refcnt_unfreeze_test02),
cmocka_unit_test(ocf_refcnt_unfreeze_test03),
};
print_message("Unit test of src/utils/utils_refcnt.c");
return cmocka_run_group_tests(tests, NULL, NULL);
}