Merge branch 'master' into file_win32

This commit is contained in:
Parth Aggarwal 2020-07-21 19:00:01 -04:00 коммит произвёл GitHub
Родитель 7ffcb37853 a98c9c69d4
Коммит 877e3eefda
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
40 изменённых файлов: 2522 добавлений и 4 удалений

3
.gitmodules поставляемый
Просмотреть файл

@ -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;
}

2
deps/azure-c-build-tools поставляемый

@ -1 +1 @@
Subproject commit 9322b35a4084a4cdb71d3d71188686c18aa986ad
Subproject commit 2c7678ec5378555553a7dd9f290940e60dff62b4

2
deps/azure-c-logging поставляемый

@ -1 +1 @@
Subproject commit 2bb8cb159e56042b30d71b2433c2cbf81be9c4cc
Subproject commit f4d81da81c297429698047796f29ff689e2fa47d

1
deps/mimalloc поставляемый Submodule

@ -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)