зеркало из https://github.com/Azure/c-pal.git
Merge branch 'master' into file_win32
This commit is contained in:
Коммит
877e3eefda
|
@ -19,3 +19,6 @@
|
|||
[submodule "cmake/deps/azure-c-logging"]
|
||||
path = cmake/deps/azure-c-logging
|
||||
url = https://github.com/azure/azure-c-logging
|
||||
[submodule "deps/mimalloc"]
|
||||
path = deps/mimalloc
|
||||
url = https://github.com/microsoft/mimalloc
|
||||
|
|
|
@ -16,20 +16,40 @@ option(run_int_tests "set run_int_tests to ON to integration tests (default is O
|
|||
option(use_cppunittest "set use_cppunittest to ON to build CppUnitTest tests on Windows (default is ON)" ON)
|
||||
option(run_traceability "run traceability tool (default is ON)" ON)
|
||||
|
||||
#canon way of limiting an option to a predefined set of values
|
||||
set(GBALLOC_LL_TYPE_VALUES PASSTHROUGH WIN32HEAP MIMALLOC) #the list of values which are allowed
|
||||
set(GBALLOC_LL_TYPE PASSTHROUGH CACHE STRING "Value of GBALLOC_LL_TYPE") #setting the property's default value in case none is taken from the command line
|
||||
set_property(CACHE GBALLOC_LL_TYPE PROPERTY STRINGS ${GBALLOC_LL_TYPE_VALUES}) #build a property that can have only the allowed values
|
||||
|
||||
|
||||
list(FIND GBALLOC_LL_TYPE_VALUES ${GBALLOC_LL_TYPE} index) #check that the received value (either the default or the one from command line) matches one of the allowed values.
|
||||
if(index EQUAL -1)
|
||||
message(FATAL_ERROR "GBALLOC_LL_TYPE must be one of '${GBALLOC_LL_TYPE_VALUES}'. It was actually '${GBALLOC_LL_TYPE}'")
|
||||
endif()
|
||||
|
||||
#canon way of limiting an option to a predefined set of values
|
||||
set(GBALLOC_HL_TYPE_VALUES PASSTHROUGH METRICS) #the list of values which are allowed
|
||||
set(GBALLOC_HL_TYPE PASSTHROUGH CACHE STRING "Value of GBALLOC_HL_TYPE") #build a property that can have only the allowed values
|
||||
set_property(CACHE GBALLOC_HL_TYPE PROPERTY STRINGS ${GBALLOC_HL_TYPE_VALUES}) #setting the property's default value in case none is taken from the command line
|
||||
|
||||
list(FIND GBALLOC_HL_TYPE_VALUES ${GBALLOC_HL_TYPE} index) #check that the received value (either the default or the one from command line) matches one of the allowed values.
|
||||
if(index EQUAL -1)
|
||||
message(FATAL_ERROR "GBALLOC_HL_TYPE must be one of '${GBALLOC_HL_TYPE_VALUES}'. It was actually '${GBALLOC_HL_TYPE}'")
|
||||
endif()
|
||||
|
||||
|
||||
set(original_run_e2e_tests ${run_e2e_tests})
|
||||
set(original_run_unittests ${run_unittests})
|
||||
set(original_run_int_tests ${run_int_tests})
|
||||
set(original_run_traceability ${run_traceability})
|
||||
set(original_run_perf_tests ${run_perf_tests})
|
||||
|
||||
|
||||
set(run_e2e_tests OFF)
|
||||
set(run_unittests OFF)
|
||||
set(run_int_tests OFF)
|
||||
set(run_traceability OFF)
|
||||
set(run_perf_tests OFF)
|
||||
|
||||
|
||||
if ((NOT TARGET azure_c_build_tools) AND (EXISTS ${CMAKE_CURRENT_LIST_DIR}/deps/azure-c-build-tools/CMakeLists.txt))
|
||||
add_subdirectory(deps/azure-c-build-tools)
|
||||
endif()
|
||||
|
@ -68,6 +88,30 @@ if ((NOT TARGET umock_c) AND (EXISTS ${CMAKE_CURRENT_LIST_DIR}/deps/umock-c/CMak
|
|||
include_directories(deps/umock-c/inc)
|
||||
endif()
|
||||
|
||||
if (
|
||||
(NOT TARGET mimalloc) AND
|
||||
(EXISTS ${CMAKE_CURRENT_LIST_DIR}/deps/mimalloc/CMakeLists.txt) AND
|
||||
(${ARCHITECTURE} STREQUAL "x86_64")
|
||||
)
|
||||
set(MI_BUILD_TESTS OFF)
|
||||
#for mimalloc disable this warning: Warning C4459: declaration of 'os_page_size' hides global declaration
|
||||
#for mimalloc disable this warning: Warning C4100: 'try_alignment': unreferenced formal parameter
|
||||
#for mimalloc disable this warning: warning C4505: 'mi_os_get_aligned_hint': unreferenced local function has been removed
|
||||
|
||||
set(PREV_CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
|
||||
set(PREV_CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
|
||||
if(WIN32)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4459 /wd4100 /wd4505")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4459 /wd4100 /wd4505")
|
||||
endif()
|
||||
|
||||
add_subdirectory(deps/mimalloc)
|
||||
include_directories(deps/mimalloc/include)
|
||||
|
||||
set(CMAKE_C_FLAGS ${PREV_CMAKE_C_FLAGS})
|
||||
set(CMAKE_CXX_FLAGS ${PREV_CMAKE_CXX_FLAGS})
|
||||
endif()
|
||||
|
||||
set(run_e2e_tests ${original_run_e2e_tests})
|
||||
set(run_unittests ${original_run_unittests})
|
||||
set(run_int_tests ${original_run_int_tests})
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
gballoc design
|
||||
=====
|
||||
|
||||
`gballoc` is a layer that abstracts memory allocators. The need to have and be able to compare multiple memory allocators stems from performance requirements. Not all memory allocators have the same performance and for the sake of being able to compare them gballoc exists.
|
||||
|
||||
`gballoc` is dvided in 2 layers (`ll` stand for `lower layer`, `hl` stands for `higher layer`):
|
||||
a) `gballoc_ll` - contains software wrappers over the memory allocation as provided by other components. For example, `gballoc_malloc/free` will redirect to `HeapAlloc/Free` when Windows APIs are directly used.
|
||||
b) `gballoc_hl` - contains performance measurements for `gballoc_ll` and it is build on top of `gballoc_ll`.
|
||||
|
||||
|
||||
`gballoc_ll` consists of a header file (`gballoc_ll.h`) and several possible implementation of its functions (i.e.: `gballoc_ll_crt.c`, `gballoc_ll_win.c`, `gballoc_ll_mimalloc.c` etc).
|
||||
|
||||
`gballoc_hl` consists of a header file (`gballoc_hl.h`) and several possible implementation of the performance functions(i.e. `gballoc_hl_passthrough.c`, `gballoc_hl_buckets.c` etc)
|
||||
|
||||
Both `gballoc_ll` and `gballoc_hl` have their own set of orthogonal configurations in CMake. That is - it is possible to use any combination of `gballoc_ll` implementation with any other implementation of `gballoc_ll`.
|
||||
|
||||
As far as Windows is concerned there are several CMake options.
|
||||
|
||||
1. `USE_SEGMENTED_HEAP` - this is a process wide option that replaces all the "regular" heaps with segmented heaps (https://docs.microsoft.com/en-us/windows/win32/sbscs/application-manifests#heaptype)
|
||||
|
||||
2. Once a heap type is used, there are other several CMakeLists switches that further influence the SW behavior.
|
||||
|
||||
a) `gballoc_ll` implementation is switched between its implementations by the CMake option `GBALLOC_LL_TYPE` (of type string) which can be either
|
||||
|
||||
i. "PASSTHROUGH" - `gballoc_ll` shall route its calls directly to C's routines.
|
||||
|
||||
ii. "WIN32HEAP" - `gballoc_ll` shall route its calls directly to Windows routines
|
||||
(`HeapAlloc`, `HeapReAlloc`, `HeapFree`)
|
||||
|
||||
iii. "MIMALLOC" - `gballoc_ll` shall route its calls directly to `mimalloc` APIs.
|
||||
|
||||
b) `gballoc_hl` implementation is governed by `GBALLOC_HL_TYPE` (of type string) which can be either:
|
||||
|
||||
i. "PASSTHROUGH" - `gballoc_hl` shall route all its APIs directly to `gballoc_ll`.
|
||||
|
||||
ii. "METRICS" - `gballoc_hl` shall construct timing metrics that can be grabbed later.
|
||||
|
||||
Linux is not a concern at this moment.
|
||||
|
||||
Both `gballoc_ll` and `gballoc_hl` shall have init/deinit functions.
|
|
@ -0,0 +1,90 @@
|
|||
# gballoc_ll_mimalloc requirements
|
||||
================
|
||||
|
||||
## Overview
|
||||
|
||||
gballoc_ll_mimalloc is a module that delegates all call of its APIs to the ones from mimalloc.
|
||||
|
||||
## References
|
||||
[mimalloc](https://github.com/microsoft/mimalloc)
|
||||
|
||||
|
||||
## Exposed API
|
||||
|
||||
```c
|
||||
MOCKABLE_FUNCTION(, int, gballoc_ll_init, void*, params);
|
||||
MOCKABLE_FUNCTION(, void, gballoc_ll_deinit);
|
||||
|
||||
MOCKABLE_FUNCTION(, void*, gballoc_ll_malloc, size_t, size);
|
||||
MOCKABLE_FUNCTION(, void, gballoc_ll_free, void*, ptr);
|
||||
MOCKABLE_FUNCTION(, void*, gballoc_ll_calloc, size_t, nmemb, size_t, size);
|
||||
MOCKABLE_FUNCTION(, void*, gballoc_ll_realloc, void*, ptr, size_t, size);
|
||||
```
|
||||
|
||||
### gballoc_ll_init
|
||||
```c
|
||||
MOCKABLE_FUNCTION(, int, gballoc_ll_init, void*, params);
|
||||
```
|
||||
|
||||
`gballoc_ll_init` returns. `params` exists as a placeholder and is ignored.
|
||||
|
||||
**SRS_GBALLOC_LL_MIMALLOC_02_001: [** `gballoc_ll_init` shall return 0. **]**
|
||||
|
||||
|
||||
### gballoc_ll_deinit
|
||||
```c
|
||||
MOCKABLE_FUNCTION(, void, gballoc_ll_deinit);
|
||||
```
|
||||
|
||||
`gballoc_ll_deinit` returns.
|
||||
|
||||
**SRS_GBALLOC_LL_MIMALLOC_02_002: [** `gballoc_ll_deinit` shall return. **]**
|
||||
|
||||
### gballoc_ll_malloc
|
||||
```c
|
||||
MOCKABLE_FUNCTION(, void*, gballoc_ll_malloc, size_t, size);
|
||||
```
|
||||
|
||||
`gballoc_ll_malloc` calls `mi_malloc` and return a memory area of `size` bytes.
|
||||
|
||||
|
||||
**SRS_GBALLOC_LL_MIMALLOC_02_003: [** `gballoc_ll_malloc` shall call `mi_malloc` and returns what `mi_malloc` returned. **]**
|
||||
|
||||
### gballoc_ll_free
|
||||
```c
|
||||
MOCKABLE_FUNCTION(, void, gballoc_ll_free, void*, ptr);
|
||||
```
|
||||
|
||||
`gballoc_ll_free` frees `ptr`.
|
||||
|
||||
**SRS_GBALLOC_LL_MIMALLOC_02_004: [** `gballoc_ll_free` shall call `mi_free(ptr)`. **]**
|
||||
|
||||
|
||||
### gballoc_ll_calloc
|
||||
```c
|
||||
MOCKABLE_FUNCTION(, void*, gballoc_ll_calloc, size_t, nmemb, size_t, size);
|
||||
```
|
||||
|
||||
`gballoc_ll_calloc` returns a memory area of `nmemb*size` bytes initialized to 0.
|
||||
|
||||
**SRS_GBALLOC_LL_MIMALLOC_02_005: [** `gballoc_ll_calloc` shall call `mi_calloc(nmemb, size)` and return what `mi_calloc` returned. **]**
|
||||
|
||||
|
||||
### gballoc_ll_realloc
|
||||
```c
|
||||
MOCKABLE_FUNCTION(, void*, gballoc_ll_realloc, void*, ptr, size_t, size);
|
||||
```
|
||||
|
||||
`gballoc_ll_realloc` reallocates `ptr` to have size `size`.
|
||||
|
||||
**SRS_GBALLOC_LL_MIMALLOC_02_006: [** `gballoc_ll_realloc` calls `mi_realloc(ptr, size)` and returns what `mi_realloc` returned. **]**
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
# gballoc_ll_passthrough requirements
|
||||
================
|
||||
|
||||
## Overview
|
||||
|
||||
gballoc_ll_passthrough is a module that delegates all call of its APIs to the ones from C standard lib.
|
||||
|
||||
## References
|
||||
|
||||
|
||||
## Exposed API
|
||||
|
||||
```c
|
||||
MOCKABLE_FUNCTION(, int, gballoc_ll_init, void*, params);
|
||||
MOCKABLE_FUNCTION(, void, gballoc_ll_deinit);
|
||||
|
||||
MOCKABLE_FUNCTION(, void*, gballoc_ll_malloc, size_t, size);
|
||||
MOCKABLE_FUNCTION(, void, gballoc_ll_free, void*, ptr);
|
||||
MOCKABLE_FUNCTION(, void*, gballoc_ll_calloc, size_t, nmemb, size_t, size);
|
||||
MOCKABLE_FUNCTION(, void*, gballoc_ll_realloc, void*, ptr, size_t, size);
|
||||
```
|
||||
|
||||
### gballoc_ll_init
|
||||
|
||||
```c
|
||||
MOCKABLE_FUNCTION(, int, gballoc_ll_init, void*, params);
|
||||
```
|
||||
|
||||
gballoc_ll_init return 0. `params` is ignored. Function exists merely as a placeholder.
|
||||
|
||||
**SRS_GBALLOC_LL_PASSTHROUGH_02_001: [** `gballoc_ll_init` shall return 0. **]**
|
||||
|
||||
### gballoc_ll_deinit
|
||||
```c
|
||||
MOCKABLE_FUNCTION(, void, gballoc_ll_deinit);
|
||||
```
|
||||
|
||||
`gballoc_ll_deinit` returns. Function exists merely as a placeholder.
|
||||
|
||||
**SRS_GBALLOC_LL_PASSTHROUGH_02_002: [** `gballoc_ll_deinit` shall return. **]**
|
||||
|
||||
### gballoc_ll_malloc
|
||||
```c
|
||||
MOCKABLE_FUNCTION(, void*, gballoc_ll_malloc, size_t, size);
|
||||
```
|
||||
|
||||
`gballoc_ll_malloc` returns what `malloc` from stdlib returns.
|
||||
|
||||
**SRS_GBALLOC_LL_PASSTHROUGH_02_003: [** `gballoc_ll_malloc` shall call `malloc(size)` and return what `malloc` returned. **]**
|
||||
|
||||
### gballoc_ll_free
|
||||
```c
|
||||
MOCKABLE_FUNCTION(, void, gballoc_ll_free, void*, ptr);
|
||||
```
|
||||
|
||||
`gballoc_ll_free` calls `free` from stdlib.
|
||||
|
||||
**SRS_GBALLOC_LL_PASSTHROUGH_02_004: [** `gballoc_ll_free` shall call `free(ptr)`. **]**
|
||||
|
||||
### gballoc_ll_calloc
|
||||
```c
|
||||
MOCKABLE_FUNCTION(, void*, gballoc_ll_calloc, size_t, nmemb, size_t, size);
|
||||
```
|
||||
|
||||
`gballoc_ll_calloc` calls `calloc` from stdlib.
|
||||
|
||||
**SRS_GBALLOC_LL_PASSTHROUGH_02_005: [** `gballoc_ll_calloc` shall call `calloc(nmemb, size)` and return what `calloc` returned. **]**
|
||||
|
||||
### gballoc_ll_realloc
|
||||
```c
|
||||
MOCKABLE_FUNCTION(, void*, gballoc_ll_realloc, void*, ptr, size_t, size);
|
||||
```
|
||||
|
||||
`gballoc_ll_realloc` calls `realloc` from stdlib.
|
||||
|
||||
**SRS_GBALLOC_LL_PASSTHROUGH_02_006: [** `gballoc_ll_realloc` shall call `realloc(nmemb, size)` and return what `realloc` returned. **]**
|
||||
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
# gballoc_ll_win32heap requirements
|
||||
================
|
||||
|
||||
## Overview
|
||||
|
||||
gballoc_ll_win32heap is a module that delegates all call of its APIs to the ones from windows heap functions.
|
||||
|
||||
## References
|
||||
[Heap Functions](https://docs.microsoft.com/en-us/windows/win32/memory/heap-functions)
|
||||
|
||||
|
||||
## Exposed API
|
||||
|
||||
```c
|
||||
MOCKABLE_FUNCTION(, int, gballoc_ll_init, void*, params);
|
||||
MOCKABLE_FUNCTION(, void, gballoc_ll_deinit);
|
||||
|
||||
MOCKABLE_FUNCTION(, void*, gballoc_ll_malloc, size_t, size);
|
||||
MOCKABLE_FUNCTION(, void, gballoc_ll_free, void*, ptr);
|
||||
MOCKABLE_FUNCTION(, void*, gballoc_ll_calloc, size_t, nmemb, size_t, size);
|
||||
MOCKABLE_FUNCTION(, void*, gballoc_ll_realloc, void*, ptr, size_t, size);
|
||||
```
|
||||
|
||||
### gballoc_ll_init
|
||||
```c
|
||||
MOCKABLE_FUNCTION(, int, gballoc_ll_init, void*, params);
|
||||
```
|
||||
|
||||
`gballoc_ll_init` initializes the module by storing a HANDLE to a heap in a global variable. `params` exists as a placeholder and is ignored.
|
||||
|
||||
**SRS_GBALLOC_LL_WIN32HEAP_02_001: [** `gballoc_ll_init` shall call `HeapCreate(0,0,0)` and store the returned heap handle in a global variable. **]**
|
||||
|
||||
**SRS_GBALLOC_LL_WIN32HEAP_02_002: [** `gballoc_ll_init` shall succeed and return 0. **]**
|
||||
|
||||
**SRS_GBALLOC_LL_WIN32HEAP_02_003: [** If `HeapCreate` fails then `gballoc_ll_init` shall fail and return a non-0 value. **]**
|
||||
|
||||
### gballoc_ll_deinit
|
||||
```c
|
||||
MOCKABLE_FUNCTION(, void, gballoc_ll_deinit);
|
||||
```
|
||||
|
||||
`gballoc_ll_deinit` deinitializes the global state and frees all the used resources.
|
||||
|
||||
**SRS_GBALLOC_LL_WIN32HEAP_02_016: [** If the global state is not initialized then `gballoc_ll_deinit` shall return. **]**
|
||||
|
||||
**SRS_GBALLOC_LL_WIN32HEAP_02_004: [** `gballoc_ll_deinit` shall call `HeapDestroy` on the handle stored by `gballoc_ll_init` in the global variable. **]**
|
||||
|
||||
|
||||
|
||||
### gballoc_ll_malloc
|
||||
```c
|
||||
MOCKABLE_FUNCTION(, void*, gballoc_ll_malloc, size_t, size);
|
||||
```
|
||||
|
||||
`gballoc_ll_malloc` calls `HeapAlloc` and return a memory area of `size` bytes.
|
||||
|
||||
**SRS_GBALLOC_LL_WIN32HEAP_02_005: [** If the global state is not initialized then `gballoc_ll_malloc` shall return `NULL`. **]**
|
||||
|
||||
**SRS_GBALLOC_LL_WIN32HEAP_02_006: [** `gballoc_ll_malloc` shall call `HeapAlloc`. **]**
|
||||
|
||||
**SRS_GBALLOC_LL_WIN32HEAP_02_007: [** `gballoc_ll_malloc` shall return what `HeapAlloc` returned. **]**
|
||||
|
||||
### gballoc_ll_free
|
||||
```c
|
||||
MOCKABLE_FUNCTION(, void, gballoc_ll_free, void*, ptr);
|
||||
```
|
||||
|
||||
`gballoc_ll_free` frees `ptr`.
|
||||
|
||||
**SRS_GBALLOC_LL_WIN32HEAP_02_008: [** If the global state is not initialized then `gballoc_ll_free` shall return. **]**
|
||||
|
||||
**SRS_GBALLOC_LL_WIN32HEAP_02_009: [** `gballoc_ll_free` shall call `HeapFree`. **]**
|
||||
|
||||
|
||||
### gballoc_ll_calloc
|
||||
```c
|
||||
MOCKABLE_FUNCTION(, void*, gballoc_ll_calloc, size_t, nmemb, size_t, size);
|
||||
```
|
||||
|
||||
`gballoc_ll_calloc` returns a memory area of `nmemb*size` bytes initialized to 0.
|
||||
|
||||
**SRS_GBALLOC_LL_WIN32HEAP_02_010: [** If the global state is not initialized then `gballoc_ll_calloc` shall return `NULL`. **]**
|
||||
|
||||
**SRS_GBALLOC_LL_WIN32HEAP_02_011: [** `gballoc_ll_calloc` shall call `HeapAlloc` with `flags` set to `HEAP_ZERO_MEMORY`. **]**
|
||||
|
||||
**SRS_GBALLOC_LL_WIN32HEAP_02_012: [** `gballoc_ll_calloc` shall return what `HeapAlloc` returns. **]**
|
||||
|
||||
### gballoc_ll_realloc
|
||||
```c
|
||||
MOCKABLE_FUNCTION(, void*, gballoc_ll_realloc, void*, ptr, size_t, size);
|
||||
```
|
||||
|
||||
`gballoc_ll_realloc` reallocates `ptr` to have size `size`.
|
||||
|
||||
**SRS_GBALLOC_LL_WIN32HEAP_02_013: [** If the global state is not initialized then `gballoc_ll_realloc` shall return `NULL`. **]**
|
||||
|
||||
**SRS_GBALLOC_LL_WIN32HEAP_02_014: [** If `ptr` is `NULL` then `gballoc_ll_realloc` shall call `HeapAlloc` and return what `HeapAlloc` returns. **]**
|
||||
|
||||
**SRS_GBALLOC_LL_WIN32HEAP_02_015: [** If `ptr` is not `NULL` then `gballoc_ll_realloc` shall call `HeapReAlloc` and return what `HeapReAlloc` returns. **]**
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#ifndef GBALLOC_HL_H
|
||||
#define GBALLOC_HL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <cstddef>
|
||||
#else
|
||||
#include <stddef.h>
|
||||
#endif
|
||||
|
||||
#include "umock_c/umock_c_prod.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
MOCKABLE_FUNCTION(, int, gballoc_hl_init, void*, gballoc_hl_init_params, void*, gballoc_ll_init_params);
|
||||
MOCKABLE_FUNCTION(, void, gballoc_hl_deinit);
|
||||
|
||||
MOCKABLE_FUNCTION(, void*, gballoc_hl_malloc, size_t, size);
|
||||
MOCKABLE_FUNCTION(, void, gballoc_hl_free, void*, ptr);
|
||||
MOCKABLE_FUNCTION(, void*, gballoc_hl_calloc, size_t, nmemb, size_t, size);
|
||||
MOCKABLE_FUNCTION(, void*, gballoc_hl_realloc, void*, ptr, size_t, size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GBALLOC_HL_H */
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#ifndef GBALLOC_LL_H
|
||||
#define GBALLOC_LL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <cstddef>
|
||||
#else
|
||||
#include <stddef.h>
|
||||
#endif
|
||||
|
||||
#include "umock_c/umock_c_prod.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_MOCKS
|
||||
#error
|
||||
#endif
|
||||
MOCKABLE_FUNCTION(, int, gballoc_ll_init, void*, params);
|
||||
MOCKABLE_FUNCTION(, void, gballoc_ll_deinit);
|
||||
|
||||
MOCKABLE_FUNCTION(, void*, gballoc_ll_malloc, size_t, size);
|
||||
MOCKABLE_FUNCTION(, void, gballoc_ll_free, void*, ptr);
|
||||
MOCKABLE_FUNCTION(, void*, gballoc_ll_calloc, size_t, nmemb, size_t, size);
|
||||
MOCKABLE_FUNCTION(, void*, gballoc_ll_realloc, void*, ptr, size_t, size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GBALLOC_LL_H */
|
|
@ -0,0 +1 @@
|
|||
int a;
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "azure_macro_utils/macro_utils.h"
|
||||
|
||||
#include "azure_c_pal/gballoc_ll.h"
|
||||
|
||||
#include "azure_c_pal/gballoc_hl.h"
|
||||
|
||||
int gballoc_hl_init(void* gballoc_hl_init_params, void* gballoc_ll_init_params)
|
||||
{
|
||||
(void)gballoc_hl_init_params; /*are ignored, this is "passthrough*/
|
||||
|
||||
return gballoc_ll_init(gballoc_ll_init_params);
|
||||
}
|
||||
|
||||
void gballoc_hl_deinit(void)
|
||||
{
|
||||
/*no work for this layer, it is passthough*/
|
||||
gballoc_ll_deinit();
|
||||
}
|
||||
|
||||
void* gballoc_hl_malloc(size_t size)
|
||||
{
|
||||
return gballoc_ll_malloc(size);
|
||||
}
|
||||
|
||||
void gballoc_hl_free(void* ptr)
|
||||
{
|
||||
gballoc_ll_free(ptr);
|
||||
}
|
||||
|
||||
|
||||
void* gballoc_hl_calloc(size_t nmemb, size_t size)
|
||||
{
|
||||
return gballoc_ll_calloc(nmemb, size);
|
||||
}
|
||||
|
||||
|
||||
void* gballoc_hl_realloc(void* ptr, size_t size)
|
||||
{
|
||||
return gballoc_ll_realloc(ptr, size);
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "azure_c_logging/xlogging.h"
|
||||
#include "azure_c_pal/gballoc_ll.h"
|
||||
|
||||
#include "mimalloc.h"
|
||||
|
||||
int gballoc_ll_init(void* params)
|
||||
{
|
||||
/*Codes_SRS_GBALLOC_LL_MIMALLOC_02_001: [ gballoc_ll_init shall return 0. ]*/
|
||||
(void)params;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void gballoc_ll_deinit(void)
|
||||
{
|
||||
|
||||
/*Codes_SRS_GBALLOC_LL_MIMALLOC_02_002: [ gballoc_ll_deinit shall return. ] */
|
||||
}
|
||||
|
||||
void* gballoc_ll_malloc(size_t size)
|
||||
{
|
||||
void* result;
|
||||
/*Codes_SRS_GBALLOC_LL_MIMALLOC_02_003: [ gballoc_ll_malloc shall call mi_malloc and returns what mi_malloc returned. ]*/
|
||||
if ((result = mi_malloc(size)) == NULL)
|
||||
{
|
||||
LogError("failure in mi_malloc(size=%zu)", size);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void gballoc_ll_free(void* ptr)
|
||||
{
|
||||
/*Codes_SRS_GBALLOC_LL_MIMALLOC_02_004: [ gballoc_ll_free shall call mi_free(ptr). ]*/
|
||||
mi_free(ptr);
|
||||
}
|
||||
|
||||
void* gballoc_ll_calloc(size_t nmemb, size_t size)
|
||||
{
|
||||
void* result;
|
||||
|
||||
/*Codes_SRS_GBALLOC_LL_MIMALLOC_02_005: [ gballoc_ll_calloc shall call mi_calloc(nmemb, size) and return what mi_calloc returned. ]*/
|
||||
if ((result = mi_calloc(nmemb, size)) == NULL)
|
||||
{
|
||||
LogError("failure in mi_calloc(nmemb=%zu, size=%zu)", nmemb, size);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void* gballoc_ll_realloc(void* ptr, size_t size)
|
||||
{
|
||||
void* result;
|
||||
/*Codes_SRS_GBALLOC_LL_MIMALLOC_02_006: [ gballoc_ll_realloc calls mi_realloc(ptr, size) and returns what mi_realloc returned. ]*/
|
||||
if ((result = mi_realloc(ptr, size)) == NULL)
|
||||
{
|
||||
LogError("failure in mi_realloc(ptr=%p, size=%zu)", ptr, size);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "azure_c_logging/xlogging.h"
|
||||
#include "azure_c_pal/gballoc_ll.h"
|
||||
|
||||
int gballoc_ll_init(void* params)
|
||||
{
|
||||
/*Codes_SRS_GBALLOC_LL_PASSTHROUGH_02_001: [ gballoc_ll_init shall return 0. ]*/
|
||||
(void)params;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void gballoc_ll_deinit(void)
|
||||
{
|
||||
/*Codes_SRS_GBALLOC_LL_PASSTHROUGH_02_002: [ gballoc_ll_deinit shall return. ]*/
|
||||
}
|
||||
|
||||
void* gballoc_ll_malloc(size_t size)
|
||||
{
|
||||
void* result;
|
||||
/*Codes_SRS_GBALLOC_LL_PASSTHROUGH_02_003: [ gballoc_ll_malloc shall call malloc(size) and return what malloc returned. ]*/
|
||||
|
||||
result = malloc(size);
|
||||
|
||||
if (result == NULL)
|
||||
{
|
||||
LogError("failure in malloc(size=%zu)", size);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void gballoc_ll_free(void* ptr)
|
||||
{
|
||||
/*Codes_SRS_GBALLOC_LL_PASSTHROUGH_02_004: [ gballoc_ll_free shall call free(ptr). ]*/
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
void* gballoc_ll_calloc(size_t nmemb, size_t size)
|
||||
{
|
||||
void* result;
|
||||
/*Codes_SRS_GBALLOC_LL_PASSTHROUGH_02_005: [ gballoc_ll_calloc shall call calloc(nmemb, size) and return what calloc returned. ]*/
|
||||
result = calloc(nmemb, size);
|
||||
|
||||
if (result == NULL)
|
||||
{
|
||||
LogError("failure in calloc(size=%zu)", size);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void* gballoc_ll_realloc(void* ptr, size_t size)
|
||||
{
|
||||
void* result;
|
||||
/*Codes_SRS_GBALLOC_LL_PASSTHROUGH_02_006: [ gballoc_ll_realloc shall call realloc(nmemb, size) and return what realloc returned. ]*/
|
||||
result = realloc(ptr, size);
|
||||
|
||||
if (result == NULL)
|
||||
{
|
||||
LogError("failure in realloc(ptr=%p, size=%zu)", ptr, size);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
|
@ -0,0 +1,153 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "windows.h"
|
||||
|
||||
#include "azure_c_logging/xlogging.h"
|
||||
#include "azure_c_pal/gballoc_ll.h"
|
||||
|
||||
static HANDLE the_heap = NULL;
|
||||
|
||||
/*not thread safe, only supports 1 call to init*/
|
||||
int gballoc_ll_init(void* params)
|
||||
{
|
||||
(void)params;
|
||||
int result;
|
||||
|
||||
/*Codes_SRS_GBALLOC_LL_WIN32HEAP_02_001: [ gballoc_ll_init shall call HeapCreate(0,0,0) and store the returned heap handle in a global variable. ]*/
|
||||
the_heap = HeapCreate(0, 0, 0);
|
||||
if (the_heap == NULL)
|
||||
{
|
||||
/*Codes_SRS_GBALLOC_LL_WIN32HEAP_02_003: [ If HeapCreate fails then gballoc_ll_init shall fail and return a non-0 value. ]*/
|
||||
LogLastError("HeapCreate(0,0,0) failed.");
|
||||
result = MU_FAILURE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*Codes_SRS_GBALLOC_LL_WIN32HEAP_02_002: [ gballoc_ll_init shall succeed and return 0. ]*/
|
||||
result = 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void gballoc_ll_deinit(void)
|
||||
{
|
||||
/*Codes_SRS_GBALLOC_LL_WIN32HEAP_02_016: [ If the global state is not initialized then gballoc_ll_deinit shall return. ]*/
|
||||
if (the_heap == NULL)
|
||||
{
|
||||
LogError("gballoc_ll_init was not called. the_heap was %p.", the_heap);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*Codes_SRS_GBALLOC_LL_WIN32HEAP_02_004: [ gballoc_ll_deinit shall call HeapDestroy on the handle stored by gballoc_ll_init in the global variable. ]*/
|
||||
if (!HeapDestroy(the_heap))
|
||||
{
|
||||
LogLastError("failure in HeapDestroy(the_heap=%p).", the_heap);
|
||||
}
|
||||
the_heap = NULL;
|
||||
}
|
||||
}
|
||||
MOCKABLE_FUNCTION(, void*, gballoc_ll_calloc, size_t, nmemb, size_t, size);
|
||||
|
||||
void* gballoc_ll_malloc(size_t size)
|
||||
{
|
||||
void* result;
|
||||
/*Codes_SRS_GBALLOC_LL_WIN32HEAP_02_005: [ If the global state is not initialized then gballoc_ll_malloc shall return NULL. ]*/
|
||||
if (the_heap == NULL)
|
||||
{
|
||||
LogError("gballoc_ll_init was not called. the_heap was %p.", the_heap);
|
||||
result = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*Codes_SRS_GBALLOC_LL_WIN32HEAP_02_006: [ gballoc_ll_malloc shall call HeapAlloc. ]*/
|
||||
/*Codes_SRS_GBALLOC_LL_WIN32HEAP_02_007: [ gballoc_ll_malloc shall return what HeapAlloc returned. ]*/
|
||||
result = HeapAlloc(the_heap, 0, size);
|
||||
|
||||
if (result == NULL)
|
||||
{
|
||||
LogError("failure in HeapAlloc(the_heap=%p, 0, size=%zu)", the_heap, size);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void gballoc_ll_free(void* ptr)
|
||||
{
|
||||
/*Codes_SRS_GBALLOC_LL_WIN32HEAP_02_008: [ If the global state is not initialized then gballoc_ll_free shall return. ]*/
|
||||
if (the_heap == NULL)
|
||||
{
|
||||
LogError("gballoc_ll_init was not called. the_heap was %p.", the_heap);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*Codes_SRS_GBALLOC_LL_WIN32HEAP_02_009: [ gballoc_ll_free shall call HeapFree. ]*/
|
||||
if (!HeapFree(the_heap, 0, ptr))
|
||||
{
|
||||
LogLastError("failure in HeapFree(custom_heap=%p, 0, ptr=%p)", the_heap, ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void* gballoc_ll_calloc(size_t nmemb, size_t size)
|
||||
{
|
||||
void* result;
|
||||
/*Codes_SRS_GBALLOC_LL_WIN32HEAP_02_010: [ If the global state is not initialized then gballoc_ll_calloc shall return NULL. ]*/
|
||||
if (the_heap == NULL)
|
||||
{
|
||||
LogError("gballoc_ll_init was not called. the_heap was %p.", the_heap);
|
||||
result = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*Codes_SRS_GBALLOC_LL_WIN32HEAP_02_011: [ gballoc_ll_calloc shall call HeapAlloc with flags set to HEAP_ZERO_MEMORY. ]*/
|
||||
/*Codes_SRS_GBALLOC_LL_WIN32HEAP_02_012: [ gballoc_ll_calloc shall return what HeapAlloc returns. ]*/
|
||||
result = HeapAlloc(the_heap, HEAP_ZERO_MEMORY, nmemb * size);
|
||||
/*return as is*/
|
||||
|
||||
if (result == NULL)
|
||||
{
|
||||
LogError("failure in HeapAlloc(the_heap=%p, HEAP_ZERO_MEMORY, nmemb=%zu * size=%zu)", the_heap, nmemb, size);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void* gballoc_ll_realloc(void* ptr, size_t size)
|
||||
{
|
||||
void* result;
|
||||
/*Codes_SRS_GBALLOC_LL_WIN32HEAP_02_013: [ If the global state is not initialized then gballoc_ll_realloc shall return NULL. ]*/
|
||||
if (the_heap == NULL)
|
||||
{
|
||||
LogError("gballoc_ll_init was not called. the_heap was %p.", the_heap);
|
||||
result = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*Codes_SRS_GBALLOC_LL_WIN32HEAP_02_014: [ If ptr is NULL then gballoc_ll_realloc shall call HeapAlloc and return what HeapAlloc returns. ]*/
|
||||
if (ptr == NULL)
|
||||
{
|
||||
result = HeapAlloc(the_heap, 0, size);
|
||||
/*return as is*/
|
||||
|
||||
if (result == NULL)
|
||||
{
|
||||
LogError("Failure in HeapAlloc(the_heap=%p, 0, size=%zu)", the_heap, size);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*Codes_SRS_GBALLOC_LL_WIN32HEAP_02_015: [ If ptr is not NULL then gballoc_ll_realloc shall call HeapReAlloc and return what HeapReAlloc returns. ]*/
|
||||
result = HeapReAlloc(the_heap, 0, ptr, size);
|
||||
/*return as is*/
|
||||
|
||||
if (result == NULL)
|
||||
{
|
||||
LogError("Failure in HeapReAlloc(the_heap=%p, 0, ptr=%p, size=%zu)", the_heap, ptr, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
|
@ -11,7 +11,23 @@ if(${run_unittests})
|
|||
add_subdirectory(gballoc_ut)
|
||||
add_subdirectory(gballoc_without_init_ut)
|
||||
add_subdirectory(refcount_ut)
|
||||
if(
|
||||
(${PAL_OS} STREQUAL "pal_win32") AND
|
||||
(${ARCHITECTURE} STREQUAL "x86_64")
|
||||
)
|
||||
build_test_folder(gballoc_ll_passthrough_ut)
|
||||
build_test_folder(gballoc_ll_win32heap_ut)
|
||||
build_test_folder(gballoc_ll_mimalloc_ut)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(${run_int_tests})
|
||||
if(
|
||||
(${PAL_OS} STREQUAL "pal_win32") AND
|
||||
(${ARCHITECTURE} STREQUAL "x86_64")
|
||||
)
|
||||
build_test_folder(gballoc_ll_mimalloc_int)
|
||||
build_test_folder(gballoc_ll_win32heap_int)
|
||||
build_test_folder(gballoc_ll_passthrough_int)
|
||||
endif()
|
||||
endif()
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
#Copyright (c) Microsoft. All rights reserved.
|
||||
#Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.11)
|
||||
|
||||
set(theseTestsName gballoc_ll_mimalloc_int)
|
||||
|
||||
set(${theseTestsName}_test_files
|
||||
${theseTestsName}.c
|
||||
)
|
||||
|
||||
set(${theseTestsName}_c_files
|
||||
../../src/gballoc_ll_mimalloc.c
|
||||
)
|
||||
|
||||
set(${theseTestsName}_h_files
|
||||
)
|
||||
|
||||
build_test_artifacts(${theseTestsName} ON "tests/azure_c_pal/common" ADDITIONAL_LIBS mimalloc-obj)
|
|
@ -0,0 +1,143 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#endif
|
||||
|
||||
#include "azure_macro_utils/macro_utils.h"
|
||||
#include "testrunnerswitcher.h"
|
||||
|
||||
static TEST_MUTEX_HANDLE g_testByTest;
|
||||
|
||||
#include "azure_c_pal/gballoc_ll.h"
|
||||
|
||||
BEGIN_TEST_SUITE(gballoc_ll_mimalloc_int)
|
||||
|
||||
TEST_SUITE_INITIALIZE(TestClassInitialize)
|
||||
{
|
||||
g_testByTest = TEST_MUTEX_CREATE();
|
||||
ASSERT_IS_NOT_NULL(g_testByTest);
|
||||
}
|
||||
|
||||
TEST_SUITE_CLEANUP(TestClassCleanup)
|
||||
{
|
||||
TEST_MUTEX_DESTROY(g_testByTest);
|
||||
}
|
||||
|
||||
TEST_FUNCTION_INITIALIZE(TestMethodInitialize)
|
||||
{
|
||||
if (TEST_MUTEX_ACQUIRE(g_testByTest))
|
||||
{
|
||||
ASSERT_FAIL("our mutex is ABANDONED. Failure in test framework");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_FUNCTION_CLEANUP(TestMethodCleanup)
|
||||
{
|
||||
TEST_MUTEX_RELEASE(g_testByTest);
|
||||
}
|
||||
|
||||
|
||||
TEST_FUNCTION(gballoc_ll_init_works)
|
||||
{
|
||||
///act
|
||||
gballoc_ll_init(NULL);
|
||||
|
||||
///assert - doesn't crash
|
||||
}
|
||||
|
||||
TEST_FUNCTION(gballoc_ll_deinit_works)
|
||||
{
|
||||
///act
|
||||
gballoc_ll_deinit();
|
||||
|
||||
///assert - doesn't crash
|
||||
}
|
||||
|
||||
TEST_FUNCTION(gballoc_ll_malloc_works)
|
||||
{
|
||||
///act (1)
|
||||
unsigned char* ptr = (unsigned char*)gballoc_ll_malloc(1);
|
||||
|
||||
///assert (1)
|
||||
ASSERT_IS_NOT_NULL(ptr);
|
||||
|
||||
///act(2)
|
||||
ptr[0] = '3'; /*can be written*/
|
||||
|
||||
///assert (2) - doesn't crash
|
||||
|
||||
///clean
|
||||
gballoc_ll_free(ptr);
|
||||
}
|
||||
|
||||
TEST_FUNCTION(gballoc_ll_malloc_1MB_works)
|
||||
{
|
||||
///act (1)
|
||||
unsigned char* ptr = (unsigned char*)gballoc_ll_malloc(1024*1024);
|
||||
|
||||
///assert (1)
|
||||
ASSERT_IS_NOT_NULL(ptr);
|
||||
|
||||
///act(2)
|
||||
ptr[0] = '3'; /*can be written*/
|
||||
|
||||
///assert (2) - doesn't crash
|
||||
|
||||
///clean
|
||||
gballoc_ll_free(ptr);
|
||||
}
|
||||
|
||||
TEST_FUNCTION(gballoc_ll_free_works)
|
||||
{
|
||||
///arrange
|
||||
unsigned char* ptr = (unsigned char*)gballoc_ll_malloc(1);
|
||||
ASSERT_IS_NOT_NULL(ptr);
|
||||
|
||||
///act
|
||||
gballoc_ll_free(ptr);
|
||||
|
||||
///assert - doesn't crash
|
||||
}
|
||||
|
||||
TEST_FUNCTION(gballoc_ll_realloc_works)
|
||||
{
|
||||
///arrange
|
||||
unsigned char* ptr1 = (unsigned char*)gballoc_ll_malloc(1);
|
||||
ASSERT_IS_NOT_NULL(ptr1);
|
||||
unsigned char* ptr2;
|
||||
|
||||
///act
|
||||
ptr2 = (unsigned char*)gballoc_ll_realloc(ptr1, 2);
|
||||
|
||||
///assert - doesn't crash
|
||||
ASSERT_IS_NOT_NULL(ptr2);
|
||||
|
||||
///clean
|
||||
gballoc_ll_free(ptr2);
|
||||
}
|
||||
|
||||
TEST_FUNCTION(gballoc_ll_calloc_works)
|
||||
{
|
||||
///arrange
|
||||
unsigned char* ptr;
|
||||
|
||||
///act
|
||||
ptr = (unsigned char*)gballoc_ll_calloc(1, 1);
|
||||
|
||||
///assert - doesn't crash
|
||||
ASSERT_IS_NOT_NULL(ptr);
|
||||
ASSERT_IS_TRUE(0 == ptr[0]);
|
||||
|
||||
///clean
|
||||
gballoc_ll_free(ptr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
END_TEST_SUITE(gballoc_ll_mimalloc_int)
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#include <stddef.h>
|
||||
#include "testrunnerswitcher.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
size_t failedTestCount = 0;
|
||||
RUN_TEST_SUITE(gballoc_ll_mimalloc_int, failedTestCount);
|
||||
return failedTestCount;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
#Copyright (c) Microsoft. All rights reserved.
|
||||
#Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.11)
|
||||
|
||||
set(theseTestsName gballoc_ll_mimalloc_ut)
|
||||
|
||||
set(${theseTestsName}_test_files
|
||||
${theseTestsName}.c
|
||||
)
|
||||
|
||||
set(${theseTestsName}_c_files
|
||||
gballoc_ll_mimalloc_mocked.c
|
||||
)
|
||||
|
||||
set(${theseTestsName}_h_files
|
||||
)
|
||||
|
||||
build_test_artifacts(${theseTestsName} ON "tests/azure_c_pal/common")
|
||||
|
||||
if("${building}" STREQUAL "exe")
|
||||
set_target_properties(${theseTestsName}_exe PROPERTIES LINK_FLAGS "/ignore:4217")
|
||||
endif()
|
||||
|
||||
if("${building}" STREQUAL "dll")
|
||||
set_target_properties(${theseTestsName}_dll PROPERTIES LINK_FLAGS "/ignore:4217")
|
||||
endif()
|
|
@ -0,0 +1,9 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#define mi_malloc mock_mi_malloc
|
||||
#define mi_free mock_mi_free
|
||||
#define mi_calloc mock_mi_calloc
|
||||
#define mi_realloc mock_mi_realloc
|
||||
|
||||
#include "../../src/gballoc_ll_mimalloc.c"
|
|
@ -0,0 +1,202 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#endif
|
||||
|
||||
#include "azure_macro_utils/macro_utils.h"
|
||||
#include "testrunnerswitcher.h"
|
||||
|
||||
static TEST_MUTEX_HANDLE g_testByTest;
|
||||
|
||||
static void* TEST_MALLOC_RESULT = (void*)0x1;
|
||||
static void* TEST_CALLOC_RESULT = (void*)0x2;
|
||||
static void* TEST_REALLOC_RESULT = (void*)0x3;
|
||||
|
||||
#include "umock_c/umock_c.h"
|
||||
|
||||
#define ENABLE_MOCKS
|
||||
#include "umock_c/umock_c_prod.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
MOCKABLE_FUNCTION(, void*, mock_mi_malloc, size_t, size);
|
||||
MOCKABLE_FUNCTION(, void*, mock_mi_calloc, size_t, nmemb, size_t, size);
|
||||
MOCKABLE_FUNCTION(, void*, mock_mi_realloc, void*, ptr, size_t, size);
|
||||
MOCKABLE_FUNCTION(, void, mock_mi_free, void*, ptr);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#undef ENABLE_MOCKS
|
||||
|
||||
MU_DEFINE_ENUM_STRINGS(UMOCK_C_ERROR_CODE, UMOCK_C_ERROR_CODE_VALUES)
|
||||
|
||||
#include "azure_c_pal/gballoc_ll.h"
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
BEGIN_TEST_SUITE(gballoc_ll_mimalloc_ut)
|
||||
|
||||
TEST_SUITE_INITIALIZE(TestClassInitialize)
|
||||
{
|
||||
g_testByTest = TEST_MUTEX_CREATE();
|
||||
ASSERT_IS_NOT_NULL(g_testByTest);
|
||||
|
||||
umock_c_init(on_umock_c_error);
|
||||
|
||||
REGISTER_GLOBAL_MOCK_RETURN(mock_mi_malloc, TEST_MALLOC_RESULT);
|
||||
REGISTER_GLOBAL_MOCK_RETURN(mock_mi_calloc, TEST_CALLOC_RESULT);
|
||||
REGISTER_GLOBAL_MOCK_RETURN(mock_mi_realloc, TEST_REALLOC_RESULT);
|
||||
}
|
||||
|
||||
TEST_SUITE_CLEANUP(TestClassCleanup)
|
||||
{
|
||||
umock_c_deinit();
|
||||
|
||||
TEST_MUTEX_DESTROY(g_testByTest);
|
||||
}
|
||||
|
||||
TEST_FUNCTION_INITIALIZE(TestMethodInitialize)
|
||||
{
|
||||
if (TEST_MUTEX_ACQUIRE(g_testByTest))
|
||||
{
|
||||
ASSERT_FAIL("our mutex is ABANDONED. Failure in test framework");
|
||||
}
|
||||
|
||||
umock_c_reset_all_calls();
|
||||
}
|
||||
|
||||
TEST_FUNCTION_CLEANUP(TestMethodCleanup)
|
||||
{
|
||||
TEST_MUTEX_RELEASE(g_testByTest);
|
||||
}
|
||||
|
||||
/*Tests_SRS_GBALLOC_LL_MIMALLOC_02_001: [ gballoc_ll_init shall return 0. ]*/
|
||||
TEST_FUNCTION(gballoc_ll_init_returns_0)
|
||||
{
|
||||
///arrange
|
||||
int result;
|
||||
|
||||
///act
|
||||
result = gballoc_ll_init(NULL);
|
||||
|
||||
///assert
|
||||
ASSERT_ARE_EQUAL(int, 0, result);
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
|
||||
///clean
|
||||
}
|
||||
|
||||
/*Tests_SRS_GBALLOC_LL_MIMALLOC_02_001: [ gballoc_ll_init shall return 0. ]*/
|
||||
TEST_FUNCTION(gballoc_ll_init_with_non_NULL_pointer_returns_0)
|
||||
{
|
||||
///arrange
|
||||
int result;
|
||||
|
||||
///act
|
||||
result = gballoc_ll_init((void*)0x24);
|
||||
|
||||
///assert
|
||||
ASSERT_ARE_EQUAL(int, 0, result);
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
|
||||
///clean
|
||||
}
|
||||
|
||||
/*Tests_SRS_GBALLOC_LL_MIMALLOC_02_002: [ gballoc_ll_deinit shall return. ]*/
|
||||
TEST_FUNCTION(gballoc_ll_deinit_returns)
|
||||
{
|
||||
///arrange
|
||||
|
||||
///act
|
||||
gballoc_ll_deinit();
|
||||
|
||||
///assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
|
||||
///clean
|
||||
}
|
||||
|
||||
/*Tests_SRS_GBALLOC_LL_MIMALLOC_02_003: [ gballoc_ll_malloc shall call mi_malloc and returns what mi_malloc returned. ]*/
|
||||
TEST_FUNCTION(gballoc_ll_malloc_calls_mimalloc)
|
||||
{
|
||||
///arrange
|
||||
|
||||
STRICT_EXPECTED_CALL(mock_mi_malloc(1));
|
||||
|
||||
///act
|
||||
void* ptr = gballoc_ll_malloc(1);
|
||||
|
||||
///assert
|
||||
ASSERT_ARE_EQUAL(void_ptr, ptr, TEST_MALLOC_RESULT);
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
|
||||
///clean
|
||||
gballoc_ll_free(ptr);
|
||||
}
|
||||
|
||||
/*Tests_SRS_GBALLOC_LL_MIMALLOC_02_004: [ gballoc_ll_free shall call mi_free(ptr). ]*/
|
||||
TEST_FUNCTION(gballoc_ll_free_calls_mi_free)
|
||||
{
|
||||
///arrange
|
||||
|
||||
STRICT_EXPECTED_CALL(mock_mi_free(TEST_MALLOC_RESULT));
|
||||
|
||||
///act
|
||||
gballoc_ll_free(TEST_MALLOC_RESULT);
|
||||
|
||||
///assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
|
||||
///clean
|
||||
}
|
||||
|
||||
/*Tests_SRS_GBALLOC_LL_MIMALLOC_02_005: [ gballoc_ll_calloc shall call mi_calloc(nmemb, size) and return what mi_calloc returned. ]*/
|
||||
TEST_FUNCTION(gballoc_ll_calloc_calls_mi_calloc)
|
||||
{
|
||||
///arrange
|
||||
|
||||
STRICT_EXPECTED_CALL(mock_mi_calloc(1, 2));
|
||||
|
||||
///act
|
||||
void* ptr = gballoc_ll_calloc(1, 2);
|
||||
|
||||
///assert
|
||||
ASSERT_ARE_EQUAL(void_ptr, ptr, TEST_CALLOC_RESULT);
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
|
||||
///clean
|
||||
gballoc_ll_free(ptr);
|
||||
}
|
||||
|
||||
/*Tests_SRS_GBALLOC_LL_MIMALLOC_02_006: [ gballoc_ll_realloc calls mi_realloc(ptr, size) and returns what mi_realloc returned. ]*/
|
||||
TEST_FUNCTION(gballoc_ll_realloc_calls_mi_realloc)
|
||||
{
|
||||
///arrange
|
||||
void* ptr1 = gballoc_ll_malloc(1);
|
||||
ASSERT_IS_NOT_NULL(ptr1);
|
||||
umock_c_reset_all_calls();
|
||||
|
||||
|
||||
STRICT_EXPECTED_CALL(mock_mi_realloc(TEST_MALLOC_RESULT, 2));
|
||||
|
||||
///act
|
||||
void* ptr2 = gballoc_ll_realloc(ptr1, 2);
|
||||
|
||||
///assert
|
||||
ASSERT_ARE_EQUAL(void_ptr, ptr2, TEST_REALLOC_RESULT);
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
|
||||
///clean
|
||||
gballoc_ll_free(ptr2);
|
||||
}
|
||||
|
||||
END_TEST_SUITE(gballoc_ll_mimalloc_ut)
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#include <stddef.h>
|
||||
#include "testrunnerswitcher.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
size_t failedTestCount = 0;
|
||||
RUN_TEST_SUITE(gballoc_ll_mimalloc_ut, failedTestCount);
|
||||
return failedTestCount;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
#Copyright (c) Microsoft. All rights reserved.
|
||||
#Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.11)
|
||||
|
||||
set(theseTestsName gballoc_ll_passthrough_int)
|
||||
|
||||
set(${theseTestsName}_test_files
|
||||
${theseTestsName}.c
|
||||
)
|
||||
|
||||
set(${theseTestsName}_c_files
|
||||
../../src/gballoc_ll_passthrough.c
|
||||
)
|
||||
|
||||
set(${theseTestsName}_h_files
|
||||
)
|
||||
|
||||
build_test_artifacts(${theseTestsName} ON "tests/azure_c_pal/common")
|
|
@ -0,0 +1,145 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#endif
|
||||
|
||||
#include "azure_macro_utils/macro_utils.h"
|
||||
#include "testrunnerswitcher.h"
|
||||
|
||||
static TEST_MUTEX_HANDLE g_testByTest;
|
||||
|
||||
#include "azure_c_pal/gballoc_ll.h"
|
||||
|
||||
BEGIN_TEST_SUITE(gballoc_ll_passthrough_int)
|
||||
|
||||
TEST_SUITE_INITIALIZE(TestClassInitialize)
|
||||
{
|
||||
g_testByTest = TEST_MUTEX_CREATE();
|
||||
ASSERT_IS_NOT_NULL(g_testByTest);
|
||||
|
||||
ASSERT_ARE_EQUAL(int, 0, gballoc_ll_init(NULL));
|
||||
}
|
||||
|
||||
TEST_SUITE_CLEANUP(TestClassCleanup)
|
||||
{
|
||||
gballoc_ll_deinit();
|
||||
|
||||
TEST_MUTEX_DESTROY(g_testByTest);
|
||||
}
|
||||
|
||||
TEST_FUNCTION_INITIALIZE(TestMethodInitialize)
|
||||
{
|
||||
if (TEST_MUTEX_ACQUIRE(g_testByTest))
|
||||
{
|
||||
ASSERT_FAIL("our mutex is ABANDONED. Failure in test framework");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_FUNCTION_CLEANUP(TestMethodCleanup)
|
||||
{
|
||||
TEST_MUTEX_RELEASE(g_testByTest);
|
||||
}
|
||||
|
||||
|
||||
TEST_FUNCTION(gballoc_ll_init_works)
|
||||
{
|
||||
///act
|
||||
gballoc_ll_init(NULL);
|
||||
|
||||
///assert - doesn't crash
|
||||
}
|
||||
|
||||
TEST_FUNCTION(gballoc_ll_deinit_works)
|
||||
{
|
||||
///act
|
||||
gballoc_ll_deinit();
|
||||
|
||||
///assert - doesn't crash
|
||||
}
|
||||
|
||||
TEST_FUNCTION(gballoc_ll_malloc_works)
|
||||
{
|
||||
///act (1)
|
||||
unsigned char* ptr = (unsigned char*)gballoc_ll_malloc(1);
|
||||
|
||||
///assert (1)
|
||||
ASSERT_IS_NOT_NULL(ptr);
|
||||
|
||||
///act(2)
|
||||
ptr[0] = '3'; /*can be written*/
|
||||
|
||||
///assert (2) - doesn't crash
|
||||
|
||||
///clean
|
||||
gballoc_ll_free(ptr);
|
||||
}
|
||||
|
||||
TEST_FUNCTION(gballoc_ll_malloc_1MB_works)
|
||||
{
|
||||
///act (1)
|
||||
unsigned char* ptr = (unsigned char*)gballoc_ll_malloc(1024 * 1024);
|
||||
|
||||
///assert (1)
|
||||
ASSERT_IS_NOT_NULL(ptr);
|
||||
|
||||
///act(2)
|
||||
ptr[0] = '3'; /*can be written*/
|
||||
|
||||
///assert (2) - doesn't crash
|
||||
|
||||
///clean
|
||||
gballoc_ll_free(ptr);
|
||||
}
|
||||
|
||||
TEST_FUNCTION(gballoc_ll_free_works)
|
||||
{
|
||||
///arrange
|
||||
unsigned char* ptr = (unsigned char*)gballoc_ll_malloc(1);
|
||||
ASSERT_IS_NOT_NULL(ptr);
|
||||
|
||||
///act
|
||||
gballoc_ll_free(ptr);
|
||||
|
||||
///assert - doesn't crash
|
||||
}
|
||||
|
||||
TEST_FUNCTION(gballoc_ll_realloc_works)
|
||||
{
|
||||
///arrange
|
||||
unsigned char* ptr1 = (unsigned char*)gballoc_ll_malloc(1);
|
||||
ASSERT_IS_NOT_NULL(ptr1);
|
||||
unsigned char* ptr2;
|
||||
|
||||
///act
|
||||
ptr2 = (unsigned char*)gballoc_ll_realloc(ptr1, 2);
|
||||
|
||||
///assert - doesn't crash
|
||||
ASSERT_IS_NOT_NULL(ptr2);
|
||||
|
||||
///clean
|
||||
gballoc_ll_free(ptr2);
|
||||
}
|
||||
|
||||
TEST_FUNCTION(gballoc_ll_calloc_works)
|
||||
{
|
||||
///arrange
|
||||
unsigned char* ptr;
|
||||
|
||||
///act
|
||||
ptr = (unsigned char*)gballoc_ll_calloc(1, 1);
|
||||
|
||||
///assert - doesn't crash
|
||||
ASSERT_IS_NOT_NULL(ptr);
|
||||
ASSERT_IS_TRUE(0 == ptr[0]);
|
||||
|
||||
///clean
|
||||
gballoc_ll_free(ptr);
|
||||
}
|
||||
|
||||
END_TEST_SUITE(gballoc_ll_passthrough_int)
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#include <stddef.h>
|
||||
#include "testrunnerswitcher.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
size_t failedTestCount = 0;
|
||||
RUN_TEST_SUITE(gballoc_ll_passthrough_int, failedTestCount);
|
||||
return failedTestCount;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
#Copyright (c) Microsoft. All rights reserved.
|
||||
#Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.11)
|
||||
|
||||
set(theseTestsName gballoc_ll_passthrough_ut)
|
||||
|
||||
set(${theseTestsName}_test_files
|
||||
${theseTestsName}.c
|
||||
)
|
||||
|
||||
set(${theseTestsName}_c_files
|
||||
gballoc_ll_passthrough_mocked.c
|
||||
)
|
||||
|
||||
set(${theseTestsName}_h_files
|
||||
)
|
||||
|
||||
build_test_artifacts(${theseTestsName} ON "tests/azure_c_pal/common")
|
||||
|
||||
if("${building}" STREQUAL "exe")
|
||||
set_target_properties(${theseTestsName}_exe PROPERTIES LINK_FLAGS "/ignore:4217")
|
||||
endif()
|
||||
|
||||
if("${building}" STREQUAL "dll")
|
||||
set_target_properties(${theseTestsName}_dll PROPERTIES LINK_FLAGS "/ignore:4217")
|
||||
endif()
|
|
@ -0,0 +1,9 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#define malloc mock_malloc
|
||||
#define free mock_free
|
||||
#define realloc mock_realloc
|
||||
#define calloc mock_calloc
|
||||
|
||||
#include "../../src/gballoc_ll_passthrough.c"
|
|
@ -0,0 +1,197 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <cstdlib>
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#include "azure_macro_utils/macro_utils.h"
|
||||
#include "testrunnerswitcher.h"
|
||||
|
||||
static TEST_MUTEX_HANDLE g_testByTest;
|
||||
|
||||
static void* TEST_MALLOC_RESULT = (void*)0x1;
|
||||
static void* TEST_CALLOC_RESULT = (void*)0x2;
|
||||
static void* TEST_REALLOC_RESULT = (void*)0x3;
|
||||
|
||||
#include "umock_c/umock_c.h"
|
||||
|
||||
#define ENABLE_MOCKS
|
||||
#include "umock_c/umock_c_prod.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
MOCKABLE_FUNCTION(, void*, mock_malloc, size_t, size);
|
||||
MOCKABLE_FUNCTION(, void*, mock_calloc, size_t, nmemb, size_t, size);
|
||||
MOCKABLE_FUNCTION(, void*, mock_realloc, void*, ptr, size_t, size);
|
||||
MOCKABLE_FUNCTION(, void, mock_free, void*, ptr);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#undef ENABLE_MOCKS
|
||||
|
||||
MU_DEFINE_ENUM_STRINGS(UMOCK_C_ERROR_CODE, UMOCK_C_ERROR_CODE_VALUES)
|
||||
|
||||
#include "azure_c_pal/gballoc_ll.h"
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
BEGIN_TEST_SUITE(gballoc_ll_passthrough_ut)
|
||||
|
||||
TEST_SUITE_INITIALIZE(TestClassInitialize)
|
||||
{
|
||||
g_testByTest = TEST_MUTEX_CREATE();
|
||||
ASSERT_IS_NOT_NULL(g_testByTest);
|
||||
|
||||
umock_c_init(on_umock_c_error);
|
||||
|
||||
REGISTER_GLOBAL_MOCK_RETURN(mock_malloc, TEST_MALLOC_RESULT);
|
||||
REGISTER_GLOBAL_MOCK_RETURN(mock_realloc, TEST_REALLOC_RESULT);
|
||||
REGISTER_GLOBAL_MOCK_RETURN(mock_calloc, TEST_CALLOC_RESULT);
|
||||
}
|
||||
|
||||
TEST_SUITE_CLEANUP(TestClassCleanup)
|
||||
{
|
||||
umock_c_deinit();
|
||||
|
||||
TEST_MUTEX_DESTROY(g_testByTest);
|
||||
}
|
||||
|
||||
TEST_FUNCTION_INITIALIZE(TestMethodInitialize)
|
||||
{
|
||||
if (TEST_MUTEX_ACQUIRE(g_testByTest))
|
||||
{
|
||||
ASSERT_FAIL("our mutex is ABANDONED. Failure in test framework");
|
||||
}
|
||||
|
||||
umock_c_reset_all_calls();
|
||||
}
|
||||
|
||||
TEST_FUNCTION_CLEANUP(TestMethodCleanup)
|
||||
{
|
||||
TEST_MUTEX_RELEASE(g_testByTest);
|
||||
}
|
||||
|
||||
/*Tests_SRS_GBALLOC_LL_PASSTHROUGH_02_001: [ gballoc_ll_init shall return 0. ]*/
|
||||
TEST_FUNCTION(gballoc_ll_init_returns_0)
|
||||
{
|
||||
int result;
|
||||
|
||||
///act
|
||||
result = gballoc_ll_init(NULL);
|
||||
|
||||
///assert
|
||||
ASSERT_ARE_EQUAL(int, 0, result);
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
|
||||
///clean
|
||||
gballoc_ll_deinit();
|
||||
}
|
||||
|
||||
/*Tests_SRS_GBALLOC_LL_PASSTHROUGH_02_001: [ gballoc_ll_init shall return 0. ]*/
|
||||
TEST_FUNCTION(gballoc_ll_init_with_non_NULL_pointer_returns_0)
|
||||
{
|
||||
///arrange
|
||||
int result;
|
||||
|
||||
///act
|
||||
result = gballoc_ll_init((void*)0x24);
|
||||
|
||||
///assert
|
||||
ASSERT_ARE_EQUAL(int, 0, result);
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
|
||||
///clean
|
||||
}
|
||||
|
||||
/*Tests_SRS_GBALLOC_LL_PASSTHROUGH_02_002: [ gballoc_ll_deinit shall return. ]*/
|
||||
TEST_FUNCTION(gballoc_ll_deinit_returns)
|
||||
{
|
||||
///arrange
|
||||
|
||||
///act
|
||||
gballoc_ll_deinit();
|
||||
|
||||
///assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
|
||||
///clean
|
||||
}
|
||||
|
||||
/*Tests_SRS_GBALLOC_LL_PASSTHROUGH_02_003: [ gballoc_ll_malloc shall call malloc(size) and return what malloc returned. ]*/
|
||||
TEST_FUNCTION(gballoc_ll_malloc_returns_what_malloc_returns)
|
||||
{
|
||||
///arrange
|
||||
void* ptr;
|
||||
|
||||
STRICT_EXPECTED_CALL(mock_malloc(1));
|
||||
|
||||
///act
|
||||
ptr = gballoc_ll_malloc(1);
|
||||
|
||||
///assert
|
||||
ASSERT_ARE_EQUAL(void_ptr, TEST_MALLOC_RESULT, ptr);
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
|
||||
///clean
|
||||
gballoc_ll_free(ptr);
|
||||
}
|
||||
|
||||
/*Tests_SRS_GBALLOC_LL_PASSTHROUGH_02_004: [ gballoc_ll_free shall call free(ptr). ]*/
|
||||
TEST_FUNCTION(gballoc_ll_free_calls_free)
|
||||
{
|
||||
///arrange
|
||||
|
||||
STRICT_EXPECTED_CALL(mock_free((void*)0x22));
|
||||
|
||||
///act
|
||||
gballoc_ll_free((void*)0x22);
|
||||
|
||||
///assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
|
||||
///clean
|
||||
}
|
||||
|
||||
/*Tests_SRS_GBALLOC_LL_PASSTHROUGH_02_005: [ gballoc_ll_calloc shall call calloc(nmemb, size) and return what calloc returned. ]*/
|
||||
TEST_FUNCTION(gballoc_ll_calloc_calls_calloc)
|
||||
{
|
||||
///arrange
|
||||
void* ptr;
|
||||
STRICT_EXPECTED_CALL(mock_calloc(1, 2));
|
||||
|
||||
///act
|
||||
ptr = gballoc_ll_calloc(1, 2);
|
||||
|
||||
///assert
|
||||
ASSERT_ARE_EQUAL(void_ptr, TEST_CALLOC_RESULT, ptr);
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
|
||||
///clean
|
||||
gballoc_ll_free(ptr);
|
||||
}
|
||||
|
||||
/*Tests_SRS_GBALLOC_LL_PASSTHROUGH_02_006: [ gballoc_ll_realloc shall call realloc(nmemb, size) and return what realloc returned. ]*/
|
||||
TEST_FUNCTION(gballoc_ll_realloc_calls_realloc)
|
||||
{
|
||||
///arrange
|
||||
void* ptr;
|
||||
STRICT_EXPECTED_CALL(mock_realloc(TEST_MALLOC_RESULT, 2));
|
||||
|
||||
///act
|
||||
ptr = gballoc_ll_realloc(TEST_MALLOC_RESULT, 2);
|
||||
|
||||
///assert
|
||||
ASSERT_ARE_EQUAL(void_ptr, TEST_REALLOC_RESULT, ptr);
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
|
||||
///clean
|
||||
gballoc_ll_free(ptr);
|
||||
}
|
||||
|
||||
END_TEST_SUITE(gballoc_ll_passthrough_ut)
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#include <stddef.h>
|
||||
#include "testrunnerswitcher.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
size_t failedTestCount = 0;
|
||||
RUN_TEST_SUITE(gballoc_ll_passthrough_ut, failedTestCount);
|
||||
return failedTestCount;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
#Copyright (c) Microsoft. All rights reserved.
|
||||
#Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.11)
|
||||
|
||||
set(theseTestsName gballoc_ll_win32heap_int)
|
||||
|
||||
set(${theseTestsName}_test_files
|
||||
${theseTestsName}.c
|
||||
)
|
||||
|
||||
set(${theseTestsName}_c_files
|
||||
../../src/gballoc_ll_win32heap.c
|
||||
)
|
||||
|
||||
set(${theseTestsName}_h_files
|
||||
)
|
||||
|
||||
build_test_artifacts(${theseTestsName} ON "tests/azure_c_pal/common")
|
|
@ -0,0 +1,153 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#endif
|
||||
|
||||
#include "azure_macro_utils/macro_utils.h"
|
||||
#include "testrunnerswitcher.h"
|
||||
|
||||
static TEST_MUTEX_HANDLE g_testByTest;
|
||||
|
||||
#include "azure_c_pal/gballoc_ll.h"
|
||||
|
||||
BEGIN_TEST_SUITE(gballoc_ll_win32heap_int)
|
||||
|
||||
TEST_SUITE_INITIALIZE(TestClassInitialize)
|
||||
{
|
||||
g_testByTest = TEST_MUTEX_CREATE();
|
||||
ASSERT_IS_NOT_NULL(g_testByTest);
|
||||
|
||||
ASSERT_ARE_EQUAL(int, 0, gballoc_ll_init(NULL));
|
||||
}
|
||||
|
||||
TEST_SUITE_CLEANUP(TestClassCleanup)
|
||||
{
|
||||
gballoc_ll_deinit();
|
||||
|
||||
TEST_MUTEX_DESTROY(g_testByTest);
|
||||
}
|
||||
|
||||
TEST_FUNCTION_INITIALIZE(TestMethodInitialize)
|
||||
{
|
||||
if (TEST_MUTEX_ACQUIRE(g_testByTest))
|
||||
{
|
||||
ASSERT_FAIL("our mutex is ABANDONED. Failure in test framework");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_FUNCTION_CLEANUP(TestMethodCleanup)
|
||||
{
|
||||
TEST_MUTEX_RELEASE(g_testByTest);
|
||||
}
|
||||
|
||||
|
||||
TEST_FUNCTION(gballoc_ll_init_works)
|
||||
{
|
||||
///arrange
|
||||
gballoc_ll_deinit();
|
||||
|
||||
///act
|
||||
gballoc_ll_init(NULL);
|
||||
|
||||
///assert - doesn't crash
|
||||
}
|
||||
|
||||
TEST_FUNCTION(gballoc_ll_deinit_works)
|
||||
{
|
||||
///arrange
|
||||
|
||||
///act
|
||||
gballoc_ll_deinit();
|
||||
|
||||
///assert - doesn't crash
|
||||
|
||||
///clean
|
||||
(void)gballoc_ll_init(NULL); /*leave it as found - that is in "init state"*/
|
||||
}
|
||||
|
||||
TEST_FUNCTION(gballoc_ll_malloc_works)
|
||||
{
|
||||
///act (1)
|
||||
unsigned char* ptr = (unsigned char*)gballoc_ll_malloc(1);
|
||||
|
||||
///assert (1)
|
||||
ASSERT_IS_NOT_NULL(ptr);
|
||||
|
||||
///act(2)
|
||||
ptr[0] = '3'; /*can be written*/
|
||||
|
||||
///assert (2) - doesn't crash
|
||||
|
||||
///clean
|
||||
gballoc_ll_free(ptr);
|
||||
}
|
||||
|
||||
TEST_FUNCTION(gballoc_ll_malloc_1MB_works)
|
||||
{
|
||||
///act (1)
|
||||
unsigned char* ptr = (unsigned char*)gballoc_ll_malloc(1024 * 1024);
|
||||
|
||||
///assert (1)
|
||||
ASSERT_IS_NOT_NULL(ptr);
|
||||
|
||||
///act(2)
|
||||
ptr[0] = '3'; /*can be written*/
|
||||
|
||||
///assert (2) - doesn't crash
|
||||
|
||||
///clean
|
||||
gballoc_ll_free(ptr);
|
||||
}
|
||||
|
||||
TEST_FUNCTION(gballoc_ll_free_works)
|
||||
{
|
||||
///arrange
|
||||
unsigned char* ptr = (unsigned char*)gballoc_ll_malloc(1);
|
||||
ASSERT_IS_NOT_NULL(ptr);
|
||||
|
||||
///act
|
||||
gballoc_ll_free(ptr);
|
||||
|
||||
///assert - doesn't crash
|
||||
}
|
||||
|
||||
TEST_FUNCTION(gballoc_ll_realloc_works)
|
||||
{
|
||||
///arrange
|
||||
unsigned char* ptr1 = (unsigned char*)gballoc_ll_malloc(1);
|
||||
ASSERT_IS_NOT_NULL(ptr1);
|
||||
unsigned char* ptr2;
|
||||
|
||||
///act
|
||||
ptr2 = (unsigned char*)gballoc_ll_realloc(ptr1, 2);
|
||||
|
||||
///assert - doesn't crash
|
||||
ASSERT_IS_NOT_NULL(ptr2);
|
||||
|
||||
///clean
|
||||
gballoc_ll_free(ptr2);
|
||||
}
|
||||
|
||||
TEST_FUNCTION(gballoc_ll_calloc_works)
|
||||
{
|
||||
///arrange
|
||||
unsigned char* ptr;
|
||||
|
||||
///act
|
||||
ptr = (unsigned char*)gballoc_ll_calloc(1, 1);
|
||||
|
||||
///assert - doesn't crash
|
||||
ASSERT_IS_NOT_NULL(ptr);
|
||||
ASSERT_IS_TRUE(0 == ptr[0]);
|
||||
|
||||
///clean
|
||||
gballoc_ll_free(ptr);
|
||||
}
|
||||
|
||||
END_TEST_SUITE(gballoc_ll_win32heap_int)
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#include <stddef.h>
|
||||
#include "testrunnerswitcher.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
size_t failedTestCount = 0;
|
||||
RUN_TEST_SUITE(gballoc_ll_win32heap_int, failedTestCount);
|
||||
return failedTestCount;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
#Copyright (c) Microsoft. All rights reserved.
|
||||
#Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.11)
|
||||
|
||||
set(theseTestsName gballoc_ll_win32heap_ut)
|
||||
|
||||
set(${theseTestsName}_test_files
|
||||
${theseTestsName}.c
|
||||
)
|
||||
|
||||
set(${theseTestsName}_c_files
|
||||
gballoc_ll_win32heap_mocked.c
|
||||
)
|
||||
|
||||
set(${theseTestsName}_h_files
|
||||
)
|
||||
|
||||
build_test_artifacts(${theseTestsName} ON "tests/azure_c_pal/common")
|
||||
|
||||
if("${building}" STREQUAL "exe")
|
||||
set_target_properties(${theseTestsName}_exe PROPERTIES LINK_FLAGS "/ignore:4217")
|
||||
endif()
|
||||
|
||||
if("${building}" STREQUAL "dll")
|
||||
set_target_properties(${theseTestsName}_dll PROPERTIES LINK_FLAGS "/ignore:4217")
|
||||
endif()
|
|
@ -0,0 +1,10 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#define HeapCreate mock_HeapCreate
|
||||
#define HeapDestroy mock_HeapDestroy
|
||||
#define HeapAlloc mock_HeapAlloc
|
||||
#define HeapFree mock_HeapFree
|
||||
#define HeapReAlloc mock_HeapReAlloc
|
||||
|
||||
#include "../../src/gballoc_ll_win32heap.c"
|
|
@ -0,0 +1,344 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <cstdlib>
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#include "azure_macro_utils/macro_utils.h"
|
||||
#include "testrunnerswitcher.h"
|
||||
|
||||
#include "windows.h"
|
||||
|
||||
static TEST_MUTEX_HANDLE g_testByTest;
|
||||
|
||||
static void* TEST_MALLOC_RESULT = (void*)0x1;
|
||||
static void* TEST_REALLOC_RESULT = (void*)0x3;
|
||||
static HANDLE TEST_HEAP = (HANDLE)0x4;
|
||||
|
||||
#include "umock_c/umock_c.h"
|
||||
#include "umock_c/umocktypes_windows.h"
|
||||
|
||||
#define ENABLE_MOCKS
|
||||
#include "umock_c/umock_c_prod.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
MOCKABLE_FUNCTION(, void*, mock_HeapCreate, DWORD, flOptions, SIZE_T, dwInitialSize, SIZE_T, dwMaximumSize);
|
||||
MOCKABLE_FUNCTION(, void*, mock_HeapDestroy, HANDLE, hHeap);
|
||||
MOCKABLE_FUNCTION(, void*, mock_HeapAlloc, HANDLE, hHeap, DWORD, dwFlags, SIZE_T, dwBytes);
|
||||
MOCKABLE_FUNCTION(, void*, mock_HeapFree, HANDLE, hHeap, DWORD, dwFlags, LPVOID, lpMem);
|
||||
MOCKABLE_FUNCTION(, void*, mock_HeapReAlloc, HANDLE, hHeap, DWORD, dwFlags, LPVOID, lpMem, SIZE_T, dwBytes);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#undef ENABLE_MOCKS
|
||||
|
||||
MU_DEFINE_ENUM_STRINGS(UMOCK_C_ERROR_CODE, UMOCK_C_ERROR_CODE_VALUES)
|
||||
|
||||
#include "azure_c_pal/gballoc_ll.h"
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
BEGIN_TEST_SUITE(gballoc_ll_win32heap_ut)
|
||||
|
||||
TEST_SUITE_INITIALIZE(TestClassInitialize)
|
||||
{
|
||||
g_testByTest = TEST_MUTEX_CREATE();
|
||||
ASSERT_IS_NOT_NULL(g_testByTest);
|
||||
|
||||
umock_c_init(on_umock_c_error);
|
||||
|
||||
ASSERT_ARE_EQUAL(int, 0, umocktypes_windows_register_types());
|
||||
|
||||
REGISTER_GLOBAL_MOCK_RETURN(mock_HeapCreate, TEST_HEAP);
|
||||
REGISTER_GLOBAL_MOCK_RETURN(mock_HeapAlloc, TEST_MALLOC_RESULT);
|
||||
REGISTER_GLOBAL_MOCK_RETURN(mock_HeapReAlloc, TEST_REALLOC_RESULT);
|
||||
|
||||
REGISTER_UMOCK_ALIAS_TYPE(SIZE_T, size_t);
|
||||
|
||||
}
|
||||
|
||||
TEST_SUITE_CLEANUP(TestClassCleanup)
|
||||
{
|
||||
umock_c_deinit();
|
||||
|
||||
TEST_MUTEX_DESTROY(g_testByTest);
|
||||
}
|
||||
|
||||
TEST_FUNCTION_INITIALIZE(TestMethodInitialize)
|
||||
{
|
||||
if (TEST_MUTEX_ACQUIRE(g_testByTest))
|
||||
{
|
||||
ASSERT_FAIL("our mutex is ABANDONED. Failure in test framework");
|
||||
}
|
||||
|
||||
umock_c_reset_all_calls();
|
||||
}
|
||||
|
||||
TEST_FUNCTION_CLEANUP(TestMethodCleanup)
|
||||
{
|
||||
TEST_MUTEX_RELEASE(g_testByTest);
|
||||
}
|
||||
|
||||
/*Tests_SRS_GBALLOC_LL_WIN32HEAP_02_001: [ gballoc_ll_init shall call HeapCreate(0,0,0) and store the returned heap handle in a global variable. ]*/
|
||||
/*Tests_SRS_GBALLOC_LL_WIN32HEAP_02_002: [ gballoc_ll_init shall succeed and return 0. ]*/
|
||||
TEST_FUNCTION(gballoc_ll_init_succeeds)
|
||||
{
|
||||
///arrange
|
||||
STRICT_EXPECTED_CALL(mock_HeapCreate(0, 0, 0));
|
||||
|
||||
///act
|
||||
int result = gballoc_ll_init(NULL);
|
||||
|
||||
///assert
|
||||
ASSERT_ARE_EQUAL(int, 0, result);
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
|
||||
///clean
|
||||
gballoc_ll_deinit();
|
||||
}
|
||||
|
||||
/*Tests_SRS_GBALLOC_LL_WIN32HEAP_02_001: [ gballoc_ll_init shall call HeapCreate(0,0,0) and store the returned heap handle in a global variable. ]*/
|
||||
/*Tests_SRS_GBALLOC_LL_WIN32HEAP_02_002: [ gballoc_ll_init shall succeed and return 0. ]*/
|
||||
TEST_FUNCTION(gballoc_ll_init_with_non_NULL_pointer_returns_0)
|
||||
{
|
||||
///arrange
|
||||
int result;
|
||||
|
||||
STRICT_EXPECTED_CALL(mock_HeapCreate(0, 0, 0));
|
||||
|
||||
///act
|
||||
result = gballoc_ll_init((void*)0x24);
|
||||
|
||||
///assert
|
||||
ASSERT_ARE_EQUAL(int, 0, result);
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
|
||||
///clean
|
||||
}
|
||||
|
||||
/*Tests_SRS_GBALLOC_LL_WIN32HEAP_02_003: [ If HeapCreate fails then gballoc_ll_init shall fail and return a non-0 value. ]*/
|
||||
TEST_FUNCTION(gballoc_ll_init_unhappy)
|
||||
{
|
||||
///arrange
|
||||
STRICT_EXPECTED_CALL(mock_HeapCreate(0, 0, 0))
|
||||
.SetReturn(NULL);
|
||||
|
||||
///act
|
||||
int result = gballoc_ll_init(NULL);
|
||||
|
||||
///assert
|
||||
ASSERT_ARE_NOT_EQUAL(int, 0, result);
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
|
||||
///clean
|
||||
}
|
||||
|
||||
/*Tests_SRS_GBALLOC_LL_WIN32HEAP_02_016: [ If the global state is not initialized then gballoc_ll_deinit shall return. ]*/
|
||||
TEST_FUNCTION(gballoc_ll_deinit_without_init)
|
||||
{
|
||||
///arrange
|
||||
|
||||
///act
|
||||
gballoc_ll_deinit();
|
||||
|
||||
///assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
|
||||
///clean
|
||||
}
|
||||
|
||||
/*Tests_SRS_GBALLOC_LL_WIN32HEAP_02_004: [ gballoc_ll_deinit shall call HeapDestroy on the handle stored by gballoc_ll_init in the global variable. ]*/
|
||||
TEST_FUNCTION(gballoc_ll_deinit_success)
|
||||
{
|
||||
///arrange
|
||||
int result = gballoc_ll_init(NULL);
|
||||
ASSERT_ARE_EQUAL(int, 0, result);
|
||||
umock_c_reset_all_calls();
|
||||
|
||||
STRICT_EXPECTED_CALL(mock_HeapDestroy(TEST_HEAP));
|
||||
|
||||
///act
|
||||
gballoc_ll_deinit();
|
||||
|
||||
///assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
|
||||
///clean
|
||||
}
|
||||
|
||||
/*Tests_SRS_GBALLOC_LL_WIN32HEAP_02_005: [ If the global state is not initialized then gballoc_ll_malloc shall return NULL. ]*/
|
||||
TEST_FUNCTION(gballoc_ll_malloc_without_init_fails)
|
||||
{
|
||||
///arrange
|
||||
|
||||
///act
|
||||
void* result = gballoc_ll_malloc(1);
|
||||
|
||||
///assert
|
||||
ASSERT_IS_NULL(result);
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
|
||||
///clean
|
||||
}
|
||||
|
||||
/*Tests_SRS_GBALLOC_LL_WIN32HEAP_02_006: [ gballoc_ll_malloc shall call HeapAlloc. ]*/
|
||||
/*Tests_SRS_GBALLOC_LL_WIN32HEAP_02_007: [ gballoc_ll_malloc shall return what HeapAlloc returned. ]*/
|
||||
TEST_FUNCTION(gballoc_ll_malloc_succeeds)
|
||||
{
|
||||
///arrange
|
||||
int result = gballoc_ll_init(NULL);
|
||||
ASSERT_ARE_EQUAL(int, 0, result);
|
||||
umock_c_reset_all_calls();
|
||||
|
||||
STRICT_EXPECTED_CALL(mock_HeapAlloc(TEST_HEAP, 0, 1));
|
||||
|
||||
///act
|
||||
void* malloc_result = gballoc_ll_malloc(1);
|
||||
|
||||
///assert
|
||||
ASSERT_ARE_EQUAL(void_ptr, TEST_MALLOC_RESULT, malloc_result);
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
|
||||
///clean
|
||||
gballoc_ll_deinit();
|
||||
}
|
||||
|
||||
/*Tests_SRS_GBALLOC_LL_WIN32HEAP_02_008: [ If the global state is not initialized then gballoc_ll_free shall return. ]*/
|
||||
TEST_FUNCTION(gballoc_ll_free_without_init_returns)
|
||||
{
|
||||
///arrange
|
||||
|
||||
///act
|
||||
gballoc_ll_free(TEST_MALLOC_RESULT);
|
||||
|
||||
///assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
|
||||
///clean
|
||||
}
|
||||
|
||||
/*Tests_SRS_GBALLOC_LL_WIN32HEAP_02_009: [ gballoc_ll_free shall call HeapFree. ]*/
|
||||
TEST_FUNCTION(gballoc_ll_free_success)
|
||||
{
|
||||
///arrange
|
||||
int result = gballoc_ll_init(NULL);
|
||||
ASSERT_ARE_EQUAL(int, 0, result);
|
||||
umock_c_reset_all_calls();
|
||||
void* what = gballoc_ll_malloc(1);
|
||||
ASSERT_IS_NOT_NULL(what);
|
||||
umock_c_reset_all_calls();
|
||||
|
||||
STRICT_EXPECTED_CALL(mock_HeapFree(TEST_HEAP, 0, what));
|
||||
|
||||
///act
|
||||
gballoc_ll_free(what);
|
||||
|
||||
///assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
|
||||
///clean
|
||||
gballoc_ll_deinit();
|
||||
}
|
||||
|
||||
/*Tests_SRS_GBALLOC_LL_WIN32HEAP_02_010: [ If the global state is not initialized then gballoc_ll_calloc shall return NULL. ]*/
|
||||
TEST_FUNCTION(gballoc_ll_calloc_without_init_returns_NULL)
|
||||
{
|
||||
///arrange
|
||||
|
||||
///act
|
||||
void* ptr = gballoc_ll_calloc(1, 1);
|
||||
|
||||
///assert
|
||||
ASSERT_IS_NULL(ptr);
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
|
||||
///clean
|
||||
}
|
||||
|
||||
/*Tests_SRS_GBALLOC_LL_WIN32HEAP_02_011: [ gballoc_ll_calloc shall call HeapAlloc with flags set to HEAP_ZERO_MEMORY. ]*/
|
||||
/*Tests_SRS_GBALLOC_LL_WIN32HEAP_02_012: [ gballoc_ll_calloc shall return what HeapAlloc returns. ]*/
|
||||
TEST_FUNCTION(gballoc_ll_calloc_succeeds)
|
||||
{
|
||||
///arrange
|
||||
int result = gballoc_ll_init(NULL);
|
||||
ASSERT_ARE_EQUAL(int, 0, result);
|
||||
umock_c_reset_all_calls();
|
||||
|
||||
STRICT_EXPECTED_CALL(mock_HeapAlloc(TEST_HEAP, HEAP_ZERO_MEMORY, 2));
|
||||
|
||||
///act
|
||||
void* malloc_result = gballoc_ll_calloc(1, 2);
|
||||
|
||||
///assert
|
||||
ASSERT_ARE_EQUAL(void_ptr, TEST_MALLOC_RESULT, malloc_result);
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
|
||||
///clean
|
||||
gballoc_ll_deinit();
|
||||
}
|
||||
|
||||
/*Tests_SRS_GBALLOC_LL_WIN32HEAP_02_013: [ If the global state is not initialized then gballoc_ll_realloc shall return NULL. ]*/
|
||||
TEST_FUNCTION(gballoc_ll_realloc_without_init_returns_NULL)
|
||||
{
|
||||
///arrange
|
||||
|
||||
///act
|
||||
void* ptr = gballoc_ll_realloc((void*)3, 1);
|
||||
|
||||
///assert
|
||||
ASSERT_IS_NULL(ptr);
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
|
||||
///clean
|
||||
}
|
||||
|
||||
/*Tests_SRS_GBALLOC_LL_WIN32HEAP_02_014: [ If ptr is NULL then gballoc_ll_realloc shall call HeapAlloc and return what HeapAlloc returns. ]*/
|
||||
TEST_FUNCTION(gballoc_ll_realloc_with_ptr_NULL)
|
||||
{
|
||||
///arrange
|
||||
int result = gballoc_ll_init(NULL);
|
||||
ASSERT_ARE_EQUAL(int, 0, result);
|
||||
umock_c_reset_all_calls();
|
||||
|
||||
STRICT_EXPECTED_CALL(mock_HeapAlloc(TEST_HEAP, 0, 1));
|
||||
|
||||
///act
|
||||
void* ptr = gballoc_ll_realloc(NULL, 1);
|
||||
|
||||
///assert
|
||||
ASSERT_ARE_EQUAL(void_ptr, TEST_MALLOC_RESULT, ptr);
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
|
||||
///clean
|
||||
gballoc_ll_deinit();
|
||||
}
|
||||
|
||||
/*Tests_SRS_GBALLOC_LL_WIN32HEAP_02_015: [ If ptr is not NULL then gballoc_ll_realloc shall call HeapReAlloc and return what HeapReAlloc returns. ]*/
|
||||
TEST_FUNCTION(gballoc_ll_realloc_with_ptr_non_NULL)
|
||||
{
|
||||
///arrange
|
||||
int result = gballoc_ll_init(NULL);
|
||||
ASSERT_ARE_EQUAL(int, 0, result);
|
||||
umock_c_reset_all_calls();
|
||||
|
||||
STRICT_EXPECTED_CALL(mock_HeapReAlloc(TEST_HEAP, 0, TEST_MALLOC_RESULT, 1));
|
||||
|
||||
///act
|
||||
void* ptr = gballoc_ll_realloc(TEST_MALLOC_RESULT, 1);
|
||||
|
||||
///assert
|
||||
ASSERT_ARE_EQUAL(void_ptr, TEST_REALLOC_RESULT, ptr);
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
|
||||
///clean
|
||||
gballoc_ll_deinit();
|
||||
}
|
||||
|
||||
END_TEST_SUITE(gballoc_ll_win32heap_ut)
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#include <stddef.h>
|
||||
#include "testrunnerswitcher.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
size_t failedTestCount = 0;
|
||||
RUN_TEST_SUITE(gballoc_ll_win32heap_ut, failedTestCount);
|
||||
return failedTestCount;
|
||||
}
|
|
@ -1 +1 @@
|
|||
Subproject commit 9322b35a4084a4cdb71d3d71188686c18aa986ad
|
||||
Subproject commit 2c7678ec5378555553a7dd9f290940e60dff62b4
|
|
@ -1 +1 @@
|
|||
Subproject commit 2bb8cb159e56042b30d71b2433c2cbf81be9c4cc
|
||||
Subproject commit f4d81da81c297429698047796f29ff689e2fa47d
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 07c6e60a5a3bd7de09e4a170cd97bafba59cfafd
|
|
@ -2,10 +2,24 @@
|
|||
|
||||
set(pal_common_h_files
|
||||
../common/inc/azure_c_pal/gballoc.h
|
||||
../common/inc/azure_c_pal/gballoc_ll.h
|
||||
../common/inc/azure_c_pal/gballoc_hl.h
|
||||
|
||||
)
|
||||
|
||||
#determining which one of the GBALLOC_LL implementations to use. By convention the file is called "gballoc_ll_" followed by "type".
|
||||
string(TOLOWER "${GBALLOC_LL_TYPE}" gballoc_ll_type_lower)
|
||||
set(gballoc_ll_c gballoc_ll_${gballoc_ll_type_lower}.c)
|
||||
|
||||
#determining which one of the GBALLOC_LL implementations to use. By convention the file is called "gballoc_hl_" followed by "type".
|
||||
string(TOLOWER "${GBALLOC_HL_TYPE}" gballoc_hl_type_lower)
|
||||
set(gballoc_hl_c gballoc_hl_${gballoc_hl_type_lower}.c)
|
||||
|
||||
|
||||
set(pal_common_c_files
|
||||
../common/src/gballoc.c
|
||||
../common/src/${gballoc_ll_c}
|
||||
../common/src/${gballoc_hl_c}
|
||||
)
|
||||
|
||||
set(pal_win32_h_files
|
||||
|
@ -40,7 +54,13 @@ include_directories(${CMAKE_CURRENT_LIST_DIR}/inc)
|
|||
include_directories(../common/inc)
|
||||
|
||||
add_library(pal_win32 ${pal_win32_h_files} ${pal_win32_c_files} ${pal_win32_md_files} ${pal_common_md_files})
|
||||
|
||||
target_link_libraries(pal_win32 pal_interfaces ws2_32 synchronization rpcrt4 azure_c_logging)
|
||||
if(${GBALLOC_LL_TYPE} STREQUAL GBALLOC_LL_MIMALLOC)
|
||||
target_link_libraries(pal_win32 mimalloc-obj)
|
||||
endif()
|
||||
|
||||
|
||||
target_include_directories(pal_win32 PUBLIC ${CMAKE_CURRENT_LIST_DIR}/inc)
|
||||
|
||||
add_subdirectory(tests)
|
||||
|
|
|
@ -0,0 +1,296 @@
|
|||
// Copyright(C) Microsoft Corporation.All rights reserved.
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <cstdlib>
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#include "azure_macro_utils/macro_utils.h"
|
||||
|
||||
static void* my_gballoc_malloc(size_t size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
static void my_gballoc_free(void* s)
|
||||
{
|
||||
free(s);
|
||||
}
|
||||
|
||||
#include "testrunnerswitcher.h"
|
||||
#include "windows.h"
|
||||
#include "umock_c/umock_c.h"
|
||||
#include "umock_c/umocktypes_stdint.h"
|
||||
#include "umock_c/umocktypes_charptr.h"
|
||||
#include "umock_c/umocktypes.h"
|
||||
#include "umock_c/umock_c_negative_tests.h"
|
||||
#include "umock_c/umocktypes_bool.h"
|
||||
#include "azure_c_pal/timer.h"
|
||||
|
||||
#define ENABLE_MOCKS
|
||||
#include "azure_c_pal/gballoc.h"
|
||||
#undef ENABLE_MOCKS
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
MOCKABLE_FUNCTION(, BOOLEAN, mocked_QueryPerformanceCounter, LARGE_INTEGER*, lpPerformanceCount)
|
||||
MOCKABLE_FUNCTION(, BOOLEAN, mocked_QueryPerformanceFrequency, LARGE_INTEGER*, lpFrequency)
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
static TEST_MUTEX_HANDLE test_serialize_mutex;
|
||||
|
||||
|
||||
MU_DEFINE_ENUM_STRINGS(UMOCK_C_ERROR_CODE, UMOCK_C_ERROR_CODE_VALUES)
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
BEGIN_TEST_SUITE(timer_unittests)
|
||||
|
||||
TEST_SUITE_INITIALIZE(suite_init)
|
||||
{
|
||||
int result;
|
||||
|
||||
test_serialize_mutex = TEST_MUTEX_CREATE();
|
||||
ASSERT_IS_NOT_NULL(test_serialize_mutex);
|
||||
|
||||
result = umock_c_init(on_umock_c_error);
|
||||
ASSERT_ARE_EQUAL(int, 0, result, "umock_c_init");
|
||||
|
||||
result = umocktypes_stdint_register_types();
|
||||
ASSERT_ARE_EQUAL(int, 0, result, "umocktypes_stdint_register_types failed");
|
||||
|
||||
result = umocktypes_charptr_register_types();
|
||||
ASSERT_ARE_EQUAL(int, 0, result, "umocktypes_charptr_register_types failed");
|
||||
|
||||
result = umocktypes_bool_register_types();
|
||||
ASSERT_ARE_EQUAL(int, 0, result, "umocktypes_bool_register_types failed");
|
||||
|
||||
REGISTER_GLOBAL_MOCK_HOOK(gballoc_malloc, my_gballoc_malloc);
|
||||
REGISTER_GLOBAL_MOCK_HOOK(gballoc_free, my_gballoc_free);
|
||||
}
|
||||
|
||||
TEST_SUITE_CLEANUP(suite_cleanup)
|
||||
{
|
||||
umock_c_deinit();
|
||||
umock_c_negative_tests_deinit();
|
||||
TEST_MUTEX_DESTROY(test_serialize_mutex);
|
||||
}
|
||||
|
||||
TEST_FUNCTION_INITIALIZE(init)
|
||||
{
|
||||
if (TEST_MUTEX_ACQUIRE(test_serialize_mutex))
|
||||
{
|
||||
ASSERT_FAIL("Could not acquire test serialization mutex.");
|
||||
}
|
||||
|
||||
umock_c_reset_all_calls();
|
||||
}
|
||||
|
||||
/* timer_create */
|
||||
TEST_FUNCTION(timer_create_malloc_fails)
|
||||
{
|
||||
//arrange
|
||||
STRICT_EXPECTED_CALL(malloc(IGNORED_ARG))
|
||||
.SetReturn(NULL);
|
||||
|
||||
//act
|
||||
TIMER_HANDLE timer = timer_create();
|
||||
|
||||
//assert
|
||||
ASSERT_IS_NULL(timer, "timer_create failed.");
|
||||
}
|
||||
|
||||
static void test_timer_create_success_expectations(void)
|
||||
{
|
||||
LARGE_INTEGER frequency, start_time;
|
||||
frequency.QuadPart = 10;
|
||||
start_time.QuadPart = 1;
|
||||
STRICT_EXPECTED_CALL(malloc(IGNORED_ARG));
|
||||
STRICT_EXPECTED_CALL(mocked_QueryPerformanceFrequency(IGNORED_ARG))
|
||||
.CopyOutArgumentBuffer_lpFrequency(&frequency, sizeof(frequency));
|
||||
STRICT_EXPECTED_CALL(mocked_QueryPerformanceCounter(IGNORED_ARG))
|
||||
.CopyOutArgumentBuffer_lpPerformanceCount(&start_time, sizeof(start_time));
|
||||
}
|
||||
|
||||
TEST_FUNCTION(timer_create_succeeds)
|
||||
{
|
||||
//arrange
|
||||
test_timer_create_success_expectations();
|
||||
|
||||
//act
|
||||
TIMER_HANDLE timer = timer_create();
|
||||
|
||||
//assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
ASSERT_IS_NOT_NULL(timer, "timer_create failed.");
|
||||
|
||||
//cleanup
|
||||
timer_destroy(timer);
|
||||
}
|
||||
|
||||
/* timer_start*/
|
||||
TEST_FUNCTION(timer_start_returns_if_timer_is_null)
|
||||
{
|
||||
//arrange
|
||||
//act
|
||||
timer_start(NULL);
|
||||
|
||||
//assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
}
|
||||
|
||||
TEST_FUNCTION(timer_start_succeeds)
|
||||
{
|
||||
//arrange
|
||||
LARGE_INTEGER stop_time;
|
||||
stop_time.QuadPart = 100;
|
||||
test_timer_create_success_expectations();
|
||||
TIMER_HANDLE timer = timer_create();
|
||||
umock_c_reset_all_calls();
|
||||
STRICT_EXPECTED_CALL(mocked_QueryPerformanceCounter(IGNORED_ARG))
|
||||
.CopyOutArgumentBuffer_lpPerformanceCount(&stop_time, sizeof(stop_time));
|
||||
|
||||
//act
|
||||
timer_start(timer);
|
||||
|
||||
//assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
|
||||
//cleanup
|
||||
timer_destroy(timer);
|
||||
}
|
||||
|
||||
/*timer_get_elapsed*/
|
||||
TEST_FUNCTION(timer_get_elapsed_fails_if_timer_is_null)
|
||||
{
|
||||
//arrange
|
||||
//act
|
||||
double start = timer_get_elapsed(NULL);
|
||||
|
||||
//assert
|
||||
ASSERT_ARE_EQUAL(double, -1, start);
|
||||
}
|
||||
|
||||
TEST_FUNCTION(timer_get_elapsed_success)
|
||||
{
|
||||
//arrange
|
||||
LARGE_INTEGER stop_time;
|
||||
stop_time.QuadPart = 100;
|
||||
test_timer_create_success_expectations();
|
||||
TIMER_HANDLE timer = timer_create();
|
||||
umock_c_reset_all_calls();
|
||||
STRICT_EXPECTED_CALL(mocked_QueryPerformanceCounter(IGNORED_ARG))
|
||||
.CopyOutArgumentBuffer_lpPerformanceCount(&stop_time, sizeof(stop_time));
|
||||
|
||||
//act
|
||||
double elapsed_time = timer_get_elapsed(timer);
|
||||
|
||||
//assert
|
||||
ASSERT_ARE_EQUAL(double, 9.9, elapsed_time);
|
||||
|
||||
//cleanup
|
||||
timer_destroy(timer);
|
||||
}
|
||||
|
||||
/*timer_get_elapsed_ms*/
|
||||
TEST_FUNCTION(timer_get_elapsed_ms_fails_if_timer_is_null)
|
||||
{
|
||||
//arrange
|
||||
//act
|
||||
double elapsed_time_ms = timer_get_elapsed_ms(NULL);
|
||||
|
||||
//assert
|
||||
ASSERT_ARE_EQUAL(double, -1, elapsed_time_ms);
|
||||
}
|
||||
|
||||
TEST_FUNCTION(timer_get_elapsed_ms_success)
|
||||
{
|
||||
//arrange
|
||||
LARGE_INTEGER stop_time;
|
||||
stop_time.QuadPart = 100;
|
||||
test_timer_create_success_expectations();
|
||||
TIMER_HANDLE timer = timer_create();
|
||||
umock_c_reset_all_calls();
|
||||
STRICT_EXPECTED_CALL(mocked_QueryPerformanceCounter(IGNORED_ARG))
|
||||
.CopyOutArgumentBuffer_lpPerformanceCount(&stop_time, sizeof(stop_time));
|
||||
|
||||
//act
|
||||
double elapsed_time_ms = timer_get_elapsed_ms(timer);
|
||||
|
||||
//assert
|
||||
ASSERT_ARE_EQUAL(double, 9900, elapsed_time_ms);
|
||||
|
||||
//cleanup
|
||||
timer_destroy(timer);
|
||||
}
|
||||
|
||||
/*timer_destroy*/
|
||||
TEST_FUNCTION(timer_destroy_returns_if_timer_is_NULL)
|
||||
{
|
||||
//arrange
|
||||
//act
|
||||
timer_destroy(NULL);
|
||||
|
||||
//assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
}
|
||||
|
||||
TEST_FUNCTION(timer_destroy_frees_handle)
|
||||
{
|
||||
//arrange
|
||||
test_timer_create_success_expectations();
|
||||
TIMER_HANDLE timer = timer_create();
|
||||
umock_c_reset_all_calls();
|
||||
STRICT_EXPECTED_CALL(free(IGNORED_ARG));
|
||||
|
||||
//act
|
||||
timer_destroy(timer);
|
||||
|
||||
//assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
}
|
||||
|
||||
TEST_FUNCTION(g_timer_get_elapsed_in_ms_succeeds)
|
||||
{
|
||||
///arrange
|
||||
LARGE_INTEGER pretendFreq;
|
||||
pretendFreq.QuadPart = 1000;
|
||||
|
||||
STRICT_EXPECTED_CALL(mocked_QueryPerformanceFrequency(IGNORED_ARG))
|
||||
.CopyOutArgumentBuffer_lpFrequency(&pretendFreq, sizeof(pretendFreq));
|
||||
|
||||
LARGE_INTEGER pretendCounter1;
|
||||
pretendCounter1.QuadPart = 2000;
|
||||
STRICT_EXPECTED_CALL(mocked_QueryPerformanceCounter(IGNORED_ARG))
|
||||
.CopyOutArgumentBuffer_lpPerformanceCount(&pretendCounter1, sizeof(pretendCounter1));
|
||||
|
||||
/*note: missing second QueryPerformanceFrequency*/
|
||||
LARGE_INTEGER pretendCounter2;
|
||||
pretendCounter2.QuadPart = 5000;
|
||||
STRICT_EXPECTED_CALL(mocked_QueryPerformanceCounter(IGNORED_ARG))
|
||||
.CopyOutArgumentBuffer_lpPerformanceCount(&pretendCounter2, sizeof(pretendCounter2));
|
||||
|
||||
///act
|
||||
double elapsed1 = timer_global_get_elapsed_ms();
|
||||
double elapsed2 = timer_global_get_elapsed_ms();
|
||||
|
||||
ASSERT_IS_TRUE(elapsed1 == 2000.0); /* all integer number up to 2^31 are perfectly representable by double*/
|
||||
|
||||
ASSERT_IS_TRUE(elapsed2 == 5000.0); /* all integer number up to 2^31 are perfectly representable by double*/
|
||||
|
||||
//assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
}
|
||||
|
||||
TEST_FUNCTION_CLEANUP(cleanup)
|
||||
{
|
||||
TEST_MUTEX_RELEASE(test_serialize_mutex);
|
||||
}
|
||||
|
||||
END_TEST_SUITE(timer_unittests)
|
Загрузка…
Ссылка в новой задаче