зеркало из https://github.com/Azure/c-pal.git
ref count type define supporting malloc/free being specified
This commit is contained in:
Родитель
e4fcca3d79
Коммит
e388bf105a
|
@ -13,14 +13,25 @@ It wraps the structure that needs to be ref counted into another structure that
|
|||
#define REFCOUNT_TYPE_CREATE_WITH_EXTRA_SIZE(type, size) MU_C2(REFCOUNT_SHORT_TYPE(type), _Create_With_Extra_Size)(size)
|
||||
#define REFCOUNT_TYPE_DESTROY(type, var) MU_C2(REFCOUNT_SHORT_TYPE(type), _Destroy)(var)
|
||||
|
||||
#define DEFINE_REFCOUNT_TYPE(type) \
|
||||
#define INC_REF(type, var) interlocked_increment(&((REFCOUNT_TYPE(type)*)((unsigned char*)var - offsetof(REFCOUNT_TYPE(type), counted)))->count)
|
||||
#define DEC_REF(type, var) interlocked_decrement(&((REFCOUNT_TYPE(type)*)((unsigned char*)var - offsetof(REFCOUNT_TYPE(type), counted)))->count)
|
||||
#define INIT_REF(type, var) interlocked_exchange(&((REFCOUNT_TYPE(type)*)((unsigned char*)var - offsetof(REFCOUNT_TYPE(type), counted)))->count, 1)
|
||||
|
||||
#define DEFINE_REFCOUNT_TYPE(type, malloc_func, free_func) \
|
||||
...
|
||||
```
|
||||
|
||||
### DEFINE_REFCOUNT_TYPE
|
||||
|
||||
```c
|
||||
#define DEFINE_REFCOUNT_TYPE(type, malloc_func, free_func) \
|
||||
...
|
||||
```
|
||||
|
||||
**SRS_REFCOUNT_01_001: [** `DEFINE_REFCOUNT_TYPE` shall define the create/create_with_Extra_size/destroy functions for the type `type`. **]**
|
||||
|
||||
**SRS_REFCOUNT_01_010: [** Memory allocation/free shall be performed by using the functions `malloc_func` and `free_func`. **]**
|
||||
|
||||
### REFCOUNT_TYPE_CREATE
|
||||
|
||||
```c
|
||||
|
|
|
@ -55,10 +55,11 @@ MU_C2(REFCOUNT_, type)
|
|||
/* Codes_SRS_REFCOUNT_01_005: [ REFCOUNT_TYPE_CREATE_WITH_EXTRA_SIZE shall allocate memory for the type that is ref counted (type) plus extra memory enough to hold size bytes. ]*/
|
||||
/* Codes_SRS_REFCOUNT_01_006: [ On success it shall return a non-NULL handle to the allocated ref counted type type. ]*/
|
||||
/* Codes_SRS_REFCOUNT_01_007: [ If any error occurs, REFCOUNT_TYPE_CREATE_WITH_EXTRA_SIZE shall return NULL. ]*/
|
||||
#define DEFINE_CREATE_WITH_EXTRA_SIZE(type) \
|
||||
#define DEFINE_CREATE_WITH_EXTRA_SIZE(type, malloc_func) \
|
||||
static type* REFCOUNT_TYPE_DECLARE_CREATE_WITH_EXTRA_SIZE(type)(size_t size) \
|
||||
{ \
|
||||
REFCOUNT_TYPE(type)* ref_counted = (REFCOUNT_TYPE(type)*)malloc(sizeof(REFCOUNT_TYPE(type)) + size); \
|
||||
/* Codes_SRS_REFCOUNT_01_010: [ Memory allocation/free shall be performed by using the functions malloc_func and free_func. ]*/ \
|
||||
REFCOUNT_TYPE(type)* ref_counted = (REFCOUNT_TYPE(type)*)malloc_func(sizeof(REFCOUNT_TYPE(type)) + size); \
|
||||
type* result; \
|
||||
if (ref_counted == NULL) \
|
||||
{ \
|
||||
|
@ -75,7 +76,7 @@ static type* REFCOUNT_TYPE_DECLARE_CREATE_WITH_EXTRA_SIZE(type)(size_t size) \
|
|||
/* Codes_SRS_REFCOUNT_01_002: [ REFCOUNT_TYPE_CREATE shall allocate memory for the type that is ref counted. ]*/
|
||||
/* Codes_SRS_REFCOUNT_01_003: [ On success it shall return a non-NULL handle to the allocated ref counted type type. ]*/
|
||||
/* Codes_SRS_REFCOUNT_01_004: [ If any error occurs, REFCOUNT_TYPE_CREATE shall return NULL. ]*/
|
||||
#define DEFINE_CREATE(type) \
|
||||
#define DEFINE_CREATE(type, malloc_func) \
|
||||
static type* REFCOUNT_TYPE_DECLARE_CREATE(type) (void) \
|
||||
{ \
|
||||
return REFCOUNT_TYPE_DECLARE_CREATE_WITH_EXTRA_SIZE(type)(0); \
|
||||
|
@ -83,23 +84,24 @@ static type* REFCOUNT_TYPE_DECLARE_CREATE(type) (void) \
|
|||
|
||||
/* Codes_SRS_REFCOUNT_01_008: [ REFCOUNT_TYPE_DESTROY shall free the memory allocated by REFCOUNT_TYPE_CREATE or REFCOUNT_TYPE_CREATE_WITH_EXTRA_SIZE. ]*/
|
||||
/* Codes_SRS_REFCOUNT_01_009: [ If counted_type is NULL, REFCOUNT_TYPE_DESTROY shall return. ]*/
|
||||
#define DEFINE_DESTROY(type) \
|
||||
#define DEFINE_DESTROY(type, free_func) \
|
||||
static void REFCOUNT_TYPE_DECLARE_DESTROY(type)(type* counted_type) \
|
||||
{ \
|
||||
void* ref_counted = (void*)((unsigned char*)counted_type - offsetof(REFCOUNT_TYPE(type), counted)); \
|
||||
free(ref_counted); \
|
||||
/* Codes_SRS_REFCOUNT_01_010: [ Memory allocation/free shall be performed by using the functions malloc_func and free_func. ]*/ \
|
||||
free_func(ref_counted); \
|
||||
}
|
||||
|
||||
/* Codes_SRS_REFCOUNT_01_001: [ DEFINE_REFCOUNT_TYPE shall define the create/create_with_Extra_size/destroy functions for the type type. ]*/
|
||||
#define DEFINE_REFCOUNT_TYPE(type) \
|
||||
#define DEFINE_REFCOUNT_TYPE(type, malloc_func, free_func) \
|
||||
REFCOUNT_TYPE(type) \
|
||||
{ \
|
||||
volatile_atomic int32_t count; \
|
||||
type counted; \
|
||||
}; \
|
||||
DEFINE_CREATE_WITH_EXTRA_SIZE(type) \
|
||||
DEFINE_CREATE(type) \
|
||||
DEFINE_DESTROY(type) \
|
||||
DEFINE_CREATE_WITH_EXTRA_SIZE(type, malloc_func) \
|
||||
DEFINE_CREATE(type, malloc_func) \
|
||||
DEFINE_DESTROY(type, free_func) \
|
||||
|
||||
/*assuming that CONSTBUFFER_ARRAY_HANDLE is a type introduced with DEFINE_REFCOUNT_TYPE(CONSTBUFFER_ARRAY_HANDLE_DATA);
|
||||
and "checkpointContent" is a variable of type CONSTBUFFER_ARRAY_HANDLE
|
||||
|
|
|
@ -32,6 +32,7 @@ void my_free(void* ptr)
|
|||
#include "azure_c_pal/interlocked.h"
|
||||
#include "azure_c_pal/gballoc_hl.h"
|
||||
#include "azure_c_pal/gballoc_hl_redirect.h"
|
||||
#include "azure_c_pal/refcount.h"
|
||||
#undef ENABLE_MOCKS
|
||||
|
||||
#include "real_gballoc_hl.h"
|
||||
|
@ -46,6 +47,19 @@ static void on_umock_c_error(UMOCK_C_ERROR_CODE error_code)
|
|||
ASSERT_FAIL("umock_c reported error :%" PRI_MU_ENUM "", MU_ENUM_VALUE(UMOCK_C_ERROR_CODE, error_code));
|
||||
}
|
||||
|
||||
typedef struct TEST_STRUCT_TAG
|
||||
{
|
||||
int dummy;
|
||||
} TEST_STRUCT;
|
||||
|
||||
MOCK_FUNCTION_WITH_CODE(, void*, test_malloc, size_t, size)
|
||||
MOCK_FUNCTION_END(my_malloc(size))
|
||||
MOCK_FUNCTION_WITH_CODE(, void, test_free, void*, ptr)
|
||||
my_free(ptr);
|
||||
MOCK_FUNCTION_END()
|
||||
|
||||
DEFINE_REFCOUNT_TYPE(TEST_STRUCT, test_malloc, test_free);
|
||||
|
||||
BEGIN_TEST_SUITE(refcount_unittests)
|
||||
|
||||
TEST_SUITE_INITIALIZE(TestClassInitialize)
|
||||
|
@ -240,4 +254,50 @@ BEGIN_TEST_SUITE(refcount_unittests)
|
|||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
}
|
||||
|
||||
/* Tests_SRS_REFCOUNT_01_010: [ Memory allocation/free shall be performed by using the functions malloc_func and free_func. ]*/ \
|
||||
TEST_FUNCTION(the_specified_malloc_function_from_the_define_is_used)
|
||||
{
|
||||
///arrange
|
||||
STRICT_EXPECTED_CALL(test_malloc(IGNORED_ARG));
|
||||
STRICT_EXPECTED_CALL(interlocked_exchange(IGNORED_ARG, 1));
|
||||
|
||||
///act
|
||||
TEST_STRUCT* result = REFCOUNT_TYPE_CREATE(TEST_STRUCT);
|
||||
|
||||
///assert
|
||||
ASSERT_IS_NOT_NULL(result);
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
}
|
||||
|
||||
/* Tests_SRS_REFCOUNT_01_010: [ Memory allocation/free shall be performed by using the functions malloc_func and free_func. ]*/ \
|
||||
TEST_FUNCTION(the_specified_malloc_function_from_the_define_is_used_by_create_with_extra_size)
|
||||
{
|
||||
///arrange
|
||||
STRICT_EXPECTED_CALL(test_malloc(IGNORED_ARG));
|
||||
STRICT_EXPECTED_CALL(interlocked_exchange(IGNORED_ARG, 1));
|
||||
|
||||
///act
|
||||
TEST_STRUCT* result = REFCOUNT_TYPE_CREATE_WITH_EXTRA_SIZE(TEST_STRUCT, 1);
|
||||
|
||||
///assert
|
||||
ASSERT_IS_NOT_NULL(result);
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
}
|
||||
|
||||
/* Tests_SRS_REFCOUNT_01_010: [ Memory allocation/free shall be performed by using the functions malloc_func and free_func. ]*/ \
|
||||
TEST_FUNCTION(the_specified_free_function_from_the_define_is_used)
|
||||
{
|
||||
///arrange
|
||||
TEST_STRUCT* result = REFCOUNT_TYPE_CREATE(TEST_STRUCT);
|
||||
umock_c_reset_all_calls();
|
||||
|
||||
STRICT_EXPECTED_CALL(test_free(IGNORED_ARG));
|
||||
|
||||
///act
|
||||
REFCOUNT_TYPE_DESTROY(TEST_STRUCT, result);
|
||||
|
||||
///assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
}
|
||||
|
||||
END_TEST_SUITE(refcount_unittests)
|
||||
|
|
|
@ -14,7 +14,8 @@ typedef struct pos_TAG
|
|||
} pos;
|
||||
|
||||
/* Tests_SRS_REFCOUNT_01_001: [ DEFINE_REFCOUNT_TYPE shall define the create/create_with_Extra_size/destroy functions for the type type. ]*/
|
||||
DEFINE_REFCOUNT_TYPE(pos);
|
||||
/* Tests_SRS_REFCOUNT_01_010: [ Memory allocation/free shall be performed by using the functions `malloc_func` and `free_func`. ]*/ \
|
||||
DEFINE_REFCOUNT_TYPE(pos, malloc, free);
|
||||
|
||||
POS_HANDLE Pos_Create(int x)
|
||||
{
|
||||
|
|
|
@ -14,7 +14,7 @@ typedef struct EXECUTION_ENGINE_TAG
|
|||
PTP_POOL ptp_pool;
|
||||
}EXECUTION_ENGINE;
|
||||
|
||||
DEFINE_REFCOUNT_TYPE(EXECUTION_ENGINE);
|
||||
DEFINE_REFCOUNT_TYPE(EXECUTION_ENGINE, malloc, free);
|
||||
|
||||
EXECUTION_ENGINE_HANDLE execution_engine_create(void* execution_engine_parameters)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче