зеркало из https://github.com/Azure/c-pal.git
Initial checkin with specs (#362)
* Initial checkin with specs * Fixed Traceability * Fixed PVOID on Linux * Fixed PVOID in threadpool.h * Forgot to add threadpool.h into the commit, adding it now * Addressed comments by Matt * Addressed ALL comments by Matt
This commit is contained in:
Родитель
82c66b2da7
Коммит
8c1dd06fb3
|
@ -11,7 +11,7 @@ endif()
|
|||
#if ((NOT TARGET c_pal) AND (EXISTS ${CMAKE_CURRENT_LIST_DIR}/deps/c-pal/CMakeLists.txt))
|
||||
# add_subdirectory(deps/c-pal)
|
||||
# include_directories(${C_PAL_INC_FOLDER})
|
||||
#endif()
|
||||
#endif()
|
||||
|
||||
if (TARGET c_pal)
|
||||
RETURN()
|
||||
|
@ -93,7 +93,7 @@ set(run_reals_check OFF)
|
|||
if ((NOT TARGET c_build_tools) AND (EXISTS ${CMAKE_CURRENT_LIST_DIR}/deps/c-build-tools/CMakeLists.txt))
|
||||
add_subdirectory(deps/c-build-tools)
|
||||
set_default_build_options()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if ((WIN32) AND ("${GBALLOC_LL_TYPE}" STREQUAL "JEMALLOC"))
|
||||
# Bring in vcpkg
|
||||
|
@ -125,37 +125,37 @@ endif()
|
|||
if ((NOT TARGET macro_utils_c) AND (EXISTS ${CMAKE_CURRENT_LIST_DIR}/deps/macro-utils-c/CMakeLists.txt))
|
||||
add_subdirectory(deps/macro-utils-c)
|
||||
include_directories(${MACRO_UTILS_INC_FOLDER})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if ((NOT TARGET c_logging_v2) AND (EXISTS ${CMAKE_CURRENT_LIST_DIR}/deps/c-logging/CMakeLists.txt))
|
||||
add_subdirectory(deps/c-logging)
|
||||
include_directories(deps/c-logging/v2/inc)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if ((NOT TARGET ctest) AND (EXISTS ${CMAKE_CURRENT_LIST_DIR}/deps/ctest/CMakeLists.txt))
|
||||
add_subdirectory(deps/ctest)
|
||||
include_directories(${CTEST_INC_FOLDER})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if ((NOT TARGET testrunnerswitcher) AND (EXISTS ${CMAKE_CURRENT_LIST_DIR}/deps/c-testrunnerswitcher/CMakeLists.txt))
|
||||
add_subdirectory(deps/c-testrunnerswitcher)
|
||||
include_directories(${TESTRUNNERSWITCHER_INC_FOLDER})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if ((NOT TARGET umock_c) AND (EXISTS ${CMAKE_CURRENT_LIST_DIR}/deps/umock-c/CMakeLists.txt))
|
||||
add_subdirectory(deps/umock-c)
|
||||
include_directories(${UMOCK_C_INC_FOLDER})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Skip for Linux iwyu
|
||||
if (WIN32)
|
||||
if (
|
||||
(NOT TARGET mimalloc-obj) AND
|
||||
(NOT TARGET mimalloc-obj) AND
|
||||
(${GBALLOC_LL_TYPE} STREQUAL "MIMALLOC") AND
|
||||
(EXISTS ${CMAKE_CURRENT_LIST_DIR}/deps/mimalloc/CMakeLists.txt)
|
||||
)
|
||||
set(MI_BUILD_SHARED OFF CACHE BOOL "Build shared library" FORCE) #not building a dll allows building on 32 bit, otherwise there's some errors on init.c about not finding a imported symbol
|
||||
set(MI_BUILD_TESTS OFF CACHE BOOL "Build test executables" FORCE)
|
||||
set(MI_BUILD_TESTS OFF CACHE BOOL "Build test executables" FORCE)
|
||||
#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
|
||||
|
@ -169,7 +169,7 @@ if (WIN32)
|
|||
|
||||
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()
|
||||
|
@ -185,7 +185,7 @@ set(run_reals_check ${original_run_reals_check})
|
|||
include(CTest)
|
||||
enable_testing()
|
||||
|
||||
set(C_PAL_INC_FOLDER
|
||||
set(C_PAL_INC_FOLDER
|
||||
${CMAKE_CURRENT_LIST_DIR}/interfaces/inc
|
||||
${CMAKE_CURRENT_LIST_DIR}/common/inc
|
||||
${CMAKE_CURRENT_LIST_DIR}/c_pal_ll/interfaces/inc
|
||||
|
|
|
@ -21,7 +21,7 @@ The lifetime of the execution engine should supersede the lifetime of the `threa
|
|||
```c
|
||||
typedef struct THREADPOOL_TAG THREADPOOL;
|
||||
typedef struct TIMER_INSTANCE_TAG* TIMER_INSTANCE_HANDLE;
|
||||
|
||||
typedef struct THREADPOOL_WORK_ITEM_TAG* THREADPOOL_WORK_ITEM_HANDLE;
|
||||
typedef void (*THREADPOOL_WORK_FUNCTION)(void* context);
|
||||
|
||||
THANDLE_TYPE_DECLARE(THREADPOOL);
|
||||
|
@ -31,6 +31,12 @@ MOCKABLE_FUNCTION(, THANDLE(THREADPOOL), threadpool_create, EXECUTION_ENGINE_HAN
|
|||
MOCKABLE_FUNCTION(, int, threadpool_open, THANDLE(THREADPOOL), threadpool);
|
||||
MOCKABLE_FUNCTION(, void, threadpool_close, THANDLE(THREADPOOL), threadpool);
|
||||
|
||||
MOCKABLE_FUNCTION(, THREADPOOL_WORK_ITEM_HANDLE, threadpool_create_work_item, THANDLE(THREADPOOL), threadpool, THREADPOOL_WORK_FUNCTION, work_function, void*, work_function_context);
|
||||
|
||||
MOCKABLE_FUNCTION(, int, threadpool_schedule_work_item, THANDLE(THREADPOOL), threadpool, THREADPOOL_WORK_ITEM_HANDLE, work_item_context);
|
||||
|
||||
MOCKABLE_FUNCTION(, void, threadpool_destroy_work_item, THREADPOOL_WORK_ITEM_HANDLE, work_item_context);
|
||||
|
||||
MOCKABLE_FUNCTION(, int, threadpool_schedule_work, THANDLE(THREADPOOL), threadpool, THREADPOOL_WORK_FUNCTION, work_function, void*, work_function_context);
|
||||
|
||||
MOCKABLE_FUNCTION(, int, threadpool_timer_start, THANDLE(THREADPOOL), threadpool, uint32_t, start_delay_ms, uint32_t, timer_period_ms, THREADPOOL_WORK_FUNCTION, work_function, void*, work_function_context, TIMER_INSTANCE_HANDLE*, timer_handle);
|
||||
|
@ -104,6 +110,56 @@ MOCKABLE_FUNCTION(, void, threadpool_close, THREADPOOL_HANDLE, threadpool);
|
|||
|
||||
**NON_THREADPOOL_01_019: [** If `threadpool` is not OPEN, `threadpool_close` shall return. **]**
|
||||
|
||||
### threadpool_create_work_item
|
||||
|
||||
```c
|
||||
MOCKABLE_FUNCTION(, THREADPOOL_WORK_ITEM_HANDLE, threadpool_create_work_item, THANDLE(THREADPOOL), threadpool, THREADPOOL_WORK_FUNCTION, work_function, void*, work_function_context);
|
||||
```
|
||||
|
||||
`threadpool_create_work_item` creates a work item to be executed by the threadpool. This function separates the creation of the work item from scheduling it so that threadpool_schedule_work_item can be called later and cannot fail.
|
||||
|
||||
**NON_THREADPOOL_05_001: [** If `threadpool` is `NULL`, `threadpool_create_work_item` shall fail and return a `NULL` value. **]**
|
||||
|
||||
**NON_THREADPOOL_05_002: [** If `work_function` is `NULL`, `threadpool_create_work_item` shall fail and return a `NULL` value. **]**
|
||||
|
||||
**NON_THREADPOOL_05_003: [** Otherwise `threadpool_create_work_item` shall allocate a context of type `THREADPOOL_WORK_ITEM_HANDLE` to save threadpool related variables. **]**
|
||||
|
||||
**NON_THREADPOOL_05_004: [** If any error occurs, `threadpool_create_work_item` shall fail and return a `NULL` value. **]**
|
||||
|
||||
**NON_THREADPOOL_05_005: [** `threadpool_create_work_item` shall create an individual work item context of type `THREADPOOL_WORK_ITEM_HANDLE` **]**
|
||||
|
||||
**NON_THREADPOOL_05_006: [** If there are no errors then the work item of type `THREADPOOL_WORK_ITEM_HANDLE` is created and returned to the caller. **]**
|
||||
|
||||
**NON_THREADPOOL_05_007: [** If any error occurs, `threadpool_create_work_item` shall fail, free the newly created context and return a `NULL` value. **]**
|
||||
|
||||
### threadpool_schedule_work_item
|
||||
|
||||
```c
|
||||
MOCKABLE_FUNCTION(, int, threadpool_schedule_work_item, THANDLE(THREADPOOL), threadpool, THREADPOOL_WORK_ITEM_HANDLE, work_item_context);
|
||||
```
|
||||
|
||||
`threadpool_schedule_work_item` schedules a work item to be executed by the threadpool. This API is called multiple times on the same `THREADPOOL_WORK_ITEM_HANDLE` and fails only if the arguments are passed `NULL`.
|
||||
|
||||
**NON_THREADPOOL_05_008: [** If `threadpool` is NULL, `threadpool_schedule_work_item` shall fail and return a `non-zero` value. **]**
|
||||
|
||||
**NON_THREADPOOL_05_009: [** If `work_item_context` is NULL, `threadpool_schedule_work_item` shall fail and return a `non-zero` value. **]**
|
||||
|
||||
**NON_THREADPOOL_05_010: [** `threadpool_schedule_work_item` shall submit the threadpool work item for execution. **]**
|
||||
|
||||
### threadpool_destroy_work_item
|
||||
|
||||
```c
|
||||
MOCKABLE_FUNCTION(, void, threadpool_destroy_work_item, THREADPOOL_WORK_ITEM_HANDLE, work_item_context);
|
||||
```
|
||||
|
||||
`threadpool_destroy_work_item` closes and frees all the member variables in the context of type `THREADPOOL_WORK_ITEM_HANDLE` and then frees the context
|
||||
|
||||
**NON_THREADPOOL_05_011: [** If `work_item_context` is `NULL`, `threadpool_destroy_work_item` shall fail and not do anything before returning. **]**
|
||||
|
||||
**NON_THREADPOOL_05_012: [** `threadpool_destroy_work_item` shall close and free all the members of `THREADPOOL_WORK_ITEM_HANDLE`. **]**
|
||||
|
||||
**NON_THREADPOOL_05_013: [** `threadpool_destroy_work_item` shall free the `work_item_context` of type `THREADPOOL_WORK_ITEM_HANDLE`. **]**
|
||||
|
||||
### threadpool_schedule_work
|
||||
|
||||
```c
|
||||
|
|
|
@ -22,7 +22,7 @@ extern "C" {
|
|||
|
||||
typedef struct THREADPOOL_TAG THREADPOOL;
|
||||
typedef struct TIMER_INSTANCE_TAG* TIMER_INSTANCE_HANDLE;
|
||||
|
||||
typedef struct THREADPOOL_WORK_ITEM_TAG* THREADPOOL_WORK_ITEM_HANDLE;
|
||||
typedef void (*THREADPOOL_WORK_FUNCTION)(void* context);
|
||||
|
||||
THANDLE_TYPE_DECLARE(THREADPOOL);
|
||||
|
@ -32,6 +32,12 @@ MOCKABLE_FUNCTION(, THANDLE(THREADPOOL), threadpool_create, EXECUTION_ENGINE_HAN
|
|||
MOCKABLE_FUNCTION(, int, threadpool_open, THANDLE(THREADPOOL), threadpool);
|
||||
MOCKABLE_FUNCTION(, void, threadpool_close, THANDLE(THREADPOOL), threadpool);
|
||||
|
||||
MOCKABLE_FUNCTION(, THREADPOOL_WORK_ITEM_HANDLE, threadpool_create_work_item, THANDLE(THREADPOOL), threadpool, THREADPOOL_WORK_FUNCTION, work_function, void*, work_function_context);
|
||||
|
||||
MOCKABLE_FUNCTION(, int, threadpool_schedule_work_item, THANDLE(THREADPOOL), threadpool, THREADPOOL_WORK_ITEM_HANDLE, work_item_context);
|
||||
|
||||
MOCKABLE_FUNCTION(, void, threadpool_destroy_work_item, THREADPOOL_WORK_ITEM_HANDLE, work_item_context);
|
||||
|
||||
MOCKABLE_FUNCTION(, int, threadpool_schedule_work, THANDLE(THREADPOOL), threadpool, THREADPOOL_WORK_FUNCTION, work_function, void*, work_function_context);
|
||||
|
||||
MOCKABLE_FUNCTION(, int, threadpool_timer_start, THANDLE(THREADPOOL), threadpool, uint32_t, start_delay_ms, uint32_t, timer_period_ms, THREADPOOL_WORK_FUNCTION, work_function, void*, work_function_context, TIMER_INSTANCE_HANDLE*, timer_handle);
|
||||
|
|
|
@ -67,7 +67,7 @@ The guard prevents any work from happening, but the event callback can still be
|
|||
```C
|
||||
typedef struct THREADPOOL_TAG THREADPOOL;
|
||||
typedef struct TIMER_INSTANCE_TAG* TIMER_INSTANCE_HANDLE;
|
||||
|
||||
typedef struct THREADPOOL_WORK_ITEM_TAG* THREADPOOL_WORK_ITEM_HANDLE;
|
||||
typedef void (*THREADPOOL_WORK_FUNCTION)(void* context);
|
||||
|
||||
THANDLE_TYPE_DECLARE(THREADPOOL);
|
||||
|
@ -77,6 +77,12 @@ MOCKABLE_FUNCTION(, THANDLE(THREADPOOL), threadpool_create, EXECUTION_ENGINE_HAN
|
|||
MOCKABLE_FUNCTION(, int, threadpool_open, THANDLE(THREADPOOL), threadpool);
|
||||
MOCKABLE_FUNCTION(, void, threadpool_close, THANDLE(THREADPOOL), threadpool);
|
||||
|
||||
MOCKABLE_FUNCTION(, THREADPOOL_WORK_ITEM_HANDLE, threadpool_create_work_item, THANDLE(THREADPOOL), threadpool, THREADPOOL_WORK_FUNCTION, work_function, void*, work_function_context);
|
||||
|
||||
MOCKABLE_FUNCTION(, int, threadpool_schedule_work_item, THANDLE(THREADPOOL), threadpool, THREADPOOL_WORK_ITEM_HANDLE, work_item_context);
|
||||
|
||||
MOCKABLE_FUNCTION(, void, threadpool_work_context_destroy, THREADPOOL_WORK_ITEM_HANDLE, work_item_context);
|
||||
|
||||
MOCKABLE_FUNCTION(, int, threadpool_schedule_work, THANDLE(THREADPOOL), threadpool, THREADPOOL_WORK_FUNCTION, work_function, void*, work_function_context);
|
||||
|
||||
MOCKABLE_FUNCTION(, int, threadpool_timer_start, THANDLE(THREADPOOL), threadpool, uint32_t, start_delay_ms, uint32_t, timer_period_ms, THREADPOOL_WORK_FUNCTION, work_function, void*, work_function_context, TIMER_INSTANCE_HANDLE*, timer_handle);
|
||||
|
@ -381,3 +387,67 @@ static int threadpool_work_func(void* param);
|
|||
**SRS_THREADPOOL_LINUX_07_084: [** If the work item function is not `NULL`, `threadpool_work_func` shall execute it with `work_function_ctx`. **]**
|
||||
|
||||
**SRS_THREADPOOL_LINUX_07_085: [** `threadpool_work_func` shall loop until `threadpool_close` or `threadpool_destroy` is called. **]**
|
||||
|
||||
### threadpool_create_work_item
|
||||
|
||||
```c
|
||||
MOCKABLE_FUNCTION(, THREADPOOL_WORK_ITEM_HANDLE, threadpool_create_work_item, THANDLE(THREADPOOL), threadpool, THREADPOOL_WORK_FUNCTION, work_function, void*, work_function_context);
|
||||
```
|
||||
|
||||
`threadpool_create_work_item` creates a work item to be executed by the threadpool.
|
||||
|
||||
**S_R_S THREADPOOL_LINUX_05_001: [** If `threadpool` is `NULL`, `threadpool_create_work_item` shall fail and return a `NULL` value. **]**
|
||||
|
||||
**S_R_S_THREADPOOL_LINUX_05_002: [** If `work_function` is `NULL`, `threadpool_create_work_item` shall fail and return a `NULL` value. **]**
|
||||
|
||||
**S_R_S_THREADPOOL_LINUX_05_003: [** `threadpool_create_work_item` shall allocate memory for `threadpool_work_item` of type `THREADPOOL_WORK_ITEM_HANDLE`. **]**
|
||||
|
||||
**S_R_S_THREADPOOL_LINUX_05_004: [** If the `malloc` fails and `threadpool_work_item` is `NULL` then log the error and return `NULL`. **]**
|
||||
|
||||
**S_R_S_THREADPOOL_LINUX_05_005: [** `threadpool_create_work_item` shall copy the `work_function` and `work_function_context` into the `threadpool_work_item` and return `threadpool_work_item` to indicate success. **]**
|
||||
|
||||
### threadpool_schedule_work_item
|
||||
|
||||
```c
|
||||
MOCKABLE_FUNCTION(, int, threadpool_schedule_work_item, THANDLE(THREADPOOL), threadpool, THREADPOOL_WORK_ITEM_HANDLE, work_item);
|
||||
```
|
||||
|
||||
`threadpool_schedule_work_item` schedules a work item to be executed by the threadpool.
|
||||
|
||||
**S_R_S_THREADPOOL_LINUX_05_006: [** If `threadpool` is `NULL`, `threadpool_schedule_work_item` shall fail and return a non-zero value. **]**
|
||||
|
||||
**S_R_S_THREADPOOL_LINUX_05_007: [** If `work_item` is `NULL`, `threadpool_schedule_work_item` shall fail and return a non-zero value. **]**
|
||||
|
||||
**S_R_S_THREADPOOL_LINUX_05_008: [** `threadpool_schedule_work_item` shall call `sm_exec_begin`. **]**
|
||||
|
||||
**S_R_S_THREADPOOL_LINUX_05_009: [** If `sm_exec_begin` returns `SM_EXEC_REFUSED`, `threadpool_schedule_work_item` shall fail and return a non-zero value. **]**
|
||||
|
||||
**S_R_S_THREADPOOL_LINUX_05_010: [** `threadpool_schedule_work_item` shall acquire the `SRW lock` in shared mode by calling `srw_lock_acquire_shared`. **]**
|
||||
|
||||
**S_R_S_THREADPOOL_LINUX_05_011: [** `threadpool_schedule_work_item` shall increment the `insert_pos`. **]**
|
||||
|
||||
**S_R_S_THREADPOOL_LINUX_05_012: [** If task state is `TASK_NOT_USED`, `threadpool_schedule_work_item` shall set the current task state to `TASK_INITIALIZING`. **]**
|
||||
|
||||
**S_R_S_THREADPOOL_LINUX_05_013: [** Otherwise, `threadpool_schedule_work_item` shall release the shared SRW lock by calling `srw_lock_release_shared` and increase `task_array` capacity: **]**
|
||||
|
||||
**S_R_S_THREADPOOL_LINUX_05_014: [** If reallocating the task array fails, `threadpool_schedule_work_item` shall fail and return a `NULL` value. **]**
|
||||
|
||||
**S_R_S_THREADPOOL_LINUX_05_015: [** `threadpool_schedule_work_item` shall copy the `work_function` and `work_function_context` from `work_item` into insert position in the task array and return `0` on success. **]**
|
||||
|
||||
**S_R_S_THREADPOOL_LINUX_05_016: [** `threadpool_schedule_work_item` shall set the `task_state` to `TASK_WAITING` and then release the shared SRW lock. **]**
|
||||
|
||||
**S_R_S_THREADPOOL_LINUX_05_017: [** `threadpool_schedule_work_item` shall unblock the `threadpool` semaphore by calling `sem_post`. **]**
|
||||
|
||||
**S_R_S_THREADPOOL_LINUX_05_018: [** `threadpool_schedule_work_item` shall return `0` on success. **]**
|
||||
|
||||
**S_R_S_THREADPOOL_LINUX_05_019: [** `threadpool_schedule_work_item` shall call `sm_exec_end`. **]**
|
||||
|
||||
### threadpool_destroy_work_item
|
||||
|
||||
```c
|
||||
MOCKABLE_FUNCTION(, void, threadpool_destroy_work_item, THREADPOOL_WORK_ITEM_HANDLE, work_item_context);
|
||||
```
|
||||
|
||||
`threadpool_work_context_destroy` Does nothing and a placeholder for WIN32 equivalent function stub
|
||||
|
||||
**S_R_S_THREADPOOL_LINUX_05_020: [** Free memory allocated to the work item of type `THREADPOOL_WORK_ITEM_HANDLE` created in `threadpool_create_work_item`. **]**
|
||||
|
|
|
@ -36,6 +36,9 @@ extern "C" {
|
|||
THANDLE(THREADPOOL) real_threadpool_create(EXECUTION_ENGINE_HANDLE execution_engine);
|
||||
int real_threadpool_open(THANDLE(THREADPOOL) threadpool);
|
||||
void real_threadpool_close(THANDLE(THREADPOOL) threadpool);
|
||||
THREADPOOL_WORK_ITEM_HANDLE real_threadpool_create_work_item(THANDLE(THREADPOOL) threadpool, THREADPOOL_WORK_FUNCTION work_function, void* work_function_context);
|
||||
int real_threadpool_schedule_work_item(THANDLE(THREADPOOL) threadpool, THREADPOOL_WORK_ITEM_HANDLE work_item_context);
|
||||
void real_threadpool_destroy_work_item(THREADPOOL_WORK_ITEM_HANDLE work_item_context);
|
||||
int real_threadpool_schedule_work(THANDLE(THREADPOOL) threadpool, THREADPOOL_WORK_FUNCTION work_function, void* work_function_context);
|
||||
int real_threadpool_timer_start(THANDLE(THREADPOOL) threadpool, uint32_t start_delay_ms, uint32_t timer_period_ms, THREADPOOL_WORK_FUNCTION work_function, void* work_function_context, TIMER_INSTANCE_HANDLE* timer_handle);
|
||||
int real_threadpool_timer_restart(TIMER_INSTANCE_HANDLE timer, uint32_t start_delay_ms, uint32_t timer_period_ms);
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
#define threadpool_create real_threadpool_create
|
||||
#define threadpool_open real_threadpool_open
|
||||
#define threadpool_close real_threadpool_close
|
||||
#define threadpool_create_work_item real_threadpool_create_work_item
|
||||
#define threadpool_schedule_work_item real_threadpool_schedule_work_item
|
||||
#define threadpool_destroy_work_item real_threadpool_destroy_work_item
|
||||
#define threadpool_schedule_work real_threadpool_schedule_work
|
||||
#define threadpool_timer_start real_threadpool_timer_start
|
||||
#define threadpool_timer_restart real_threadpool_timer_restart
|
||||
|
|
|
@ -73,6 +73,14 @@ typedef struct THREADPOOL_TASK_TAG
|
|||
volatile uint32_t pending_api_calls;
|
||||
} THREADPOOL_TASK;
|
||||
|
||||
typedef struct THREADPOOL_WORK_ITEM_TAG
|
||||
{
|
||||
volatile_atomic int32_t task_state;
|
||||
THREADPOOL_WORK_FUNCTION work_function;
|
||||
void* work_function_ctx;
|
||||
volatile uint32_t pending_api_calls;
|
||||
} THREADPOOL_WORK_ITEM, * THREADPOOL_WORK_ITEM_HANDLE;
|
||||
|
||||
typedef struct THREADPOOL_TAG
|
||||
{
|
||||
volatile_atomic int32_t run_thread;
|
||||
|
@ -507,6 +515,23 @@ void threadpool_close(THANDLE(THREADPOOL) threadpool)
|
|||
}
|
||||
}
|
||||
|
||||
THREADPOOL_WORK_ITEM_HANDLE threadpool_create_work_item(THANDLE(THREADPOOL) threadpool, THREADPOOL_WORK_FUNCTION work_function, void* work_function_context)
|
||||
{
|
||||
LogWarning("Not Implemented: threadpool_create_work_item(%p, %p, %p)", threadpool, work_function, work_function_context);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int threadpool_schedule_work_item(THANDLE(THREADPOOL) threadpool, THREADPOOL_WORK_ITEM_HANDLE work_item_context)
|
||||
{
|
||||
LogWarning("Not Implemented: threadpool_schedule_work_item(%p)", work_item_context);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void threadpool_work_context_destroy(THREADPOOL_WORK_ITEM_HANDLE work_item_context)
|
||||
{
|
||||
LogWarning("Not Implemented: threadpool_work_context_destroy(%p)", work_item_context);
|
||||
}
|
||||
|
||||
int threadpool_schedule_work(THANDLE(THREADPOOL) threadpool, THREADPOOL_WORK_FUNCTION work_function, void* work_function_ctx)
|
||||
{
|
||||
int result;
|
||||
|
|
|
@ -13,7 +13,7 @@ It uses the PTP_POOL associated with the execution engine passed as argument to
|
|||
```c
|
||||
typedef struct THREADPOOL_TAG THREADPOOL;
|
||||
typedef struct TIMER_INSTANCE_TAG* TIMER_INSTANCE_HANDLE;
|
||||
|
||||
typedef struct THREADPOOL_WORK_ITEM_TAG* THREADPOOL_WORK_ITEM_HANDLE;
|
||||
typedef void (*THREADPOOL_WORK_FUNCTION)(void* context);
|
||||
|
||||
THANDLE_TYPE_DECLARE(THREADPOOL);
|
||||
|
@ -23,6 +23,12 @@ MOCKABLE_FUNCTION(, THANDLE(THREADPOOL), threadpool_create, EXECUTION_ENGINE_HAN
|
|||
MOCKABLE_FUNCTION(, int, threadpool_open, THANDLE(THREADPOOL), threadpool);
|
||||
MOCKABLE_FUNCTION(, void, threadpool_close, THANDLE(THREADPOOL), threadpool);
|
||||
|
||||
MOCKABLE_FUNCTION(, THREADPOOL_WORK_ITEM_HANDLE, threadpool_create_work_item, THANDLE(THREADPOOL), threadpool, THREADPOOL_WORK_FUNCTION, work_function, void*, work_function_context);
|
||||
|
||||
MOCKABLE_FUNCTION(, int, threadpool_schedule_work_item, THANDLE(THREADPOOL), threadpool, THREADPOOL_WORK_ITEM_HANDLE, work_item_context);
|
||||
|
||||
MOCKABLE_FUNCTION(, void, threadpool_destroy_work_item, THREADPOOL_WORK_ITEM_HANDLE, work_item_context);
|
||||
|
||||
MOCKABLE_FUNCTION(, int, threadpool_schedule_work, THANDLE(THREADPOOL), threadpool, THREADPOOL_WORK_FUNCTION, work_function, void*, work_function_context);
|
||||
|
||||
MOCKABLE_FUNCTION(, int, threadpool_timer_start, THANDLE(THREADPOOL), threadpool, uint32_t, start_delay_ms, uint32_t, timer_period_ms, THREADPOOL_WORK_FUNCTION, work_function, void*, work_function_context, TIMER_INSTANCE_HANDLE*, timer_handle);
|
||||
|
@ -156,6 +162,21 @@ static VOID CALLBACK on_work_callback(PTP_CALLBACK_INSTANCE instance, PVOID cont
|
|||
|
||||
**SRS_THREADPOOL_WIN32_01_039: [** `on_work_callback` shall free the context allocated in `threadpool_schedule_work`. **]**
|
||||
|
||||
### on_work_callback_v2
|
||||
|
||||
```c
|
||||
static VOID CALLBACK on_work_callback_v2(PTP_CALLBACK_INSTANCE instance, void* context, PTP_WORK work);
|
||||
```
|
||||
|
||||
`on_work_callback_v2` executes the work function passed to `threadpool_create_work_item`.
|
||||
|
||||
**S_R_S_THREADPOOL_WIN32_05_001: [** If `context` is `NULL`, `on_work_callback_v2` shall return. **]**
|
||||
|
||||
**S_R_S_THREADPOOL_WIN32_05_002: [** Otherwise `context` shall be used as the context created in `threadpool_create_work_item`. **]**
|
||||
|
||||
**S_R_S_THREADPOOL_WIN32_05_003: [** The `work_function` callback passed to `threadpool_create_work_item` shall be called with the `work_function_context` as an argument. `work_function_context` was set inside the `threadpool_create_work_item` as an argument to `CreateThreadpoolContext`. **]**
|
||||
|
||||
|
||||
### threadpool_timer_start
|
||||
|
||||
```c
|
||||
|
@ -243,3 +264,54 @@ static VOID CALLBACK on_timer_callback(PTP_CALLBACK_INSTANCE instance, PVOID con
|
|||
**SRS_THREADPOOL_WIN32_42_017: [** Otherwise `context` shall be used as the context created in `threadpool_schedule_work`. **]**
|
||||
|
||||
**SRS_THREADPOOL_WIN32_42_018: [** The `work_function` callback passed to `threadpool_schedule_work` shall be called, passing to it the `work_function_context` argument passed to `threadpool_schedule_work`. **]**
|
||||
|
||||
### threadpool_create_work_item
|
||||
|
||||
```c
|
||||
MOCKABLE_FUNCTION(, THREADPOOL_WORK_ITEM_HANDLE, threadpool_create_work_item, THANDLE(THREADPOOL), threadpool, THREADPOOL_WORK_FUNCTION, work_function, void*, work_function_context);
|
||||
```
|
||||
|
||||
`threadpool_create_work_item` creates a work item to be executed by the threadpool.
|
||||
|
||||
**S_R_S_THREADPOOL_WIN32_05_004: [** If `threadpool` is `NULL`, `threadpool_create_work_item` shall fail and return a `NULL` value. **]**
|
||||
|
||||
**S_R_S_THREADPOOL_WIN32_05_005: [** If `work_function` is `NULL`, `threadpool_create_work_item` shall fail and return a `NULL` value. **]**
|
||||
|
||||
**S_R_S_THREADPOOL_WIN32_05_006: [** Otherwise `threadpool_create_work_item` shall allocate a context `work_item_context` of type `THREADPOOL_WORK_ITEM_HANDLE` where `work_function`, `work_function_context`, and `ptp_work` shall be saved. **]**
|
||||
|
||||
**S_R_S_THREADPOOL_WIN32_05_007: [** If any error occurs, `threadpool_create_work_item` shall fail and return a `NULL` value. **]**
|
||||
|
||||
**S_R_S_THREADPOOL_WIN32_05_008: [** `threadpool_create_work_item` shall create `work_item_context` member variable `ptp_work` of type `PTP_WORK` by calling `CreateThreadpoolWork` to set the callback function as `on_work_callback_v2`. **]**
|
||||
|
||||
**S_R_S_THREADPOOL_WIN32_05_009: [** If there are no errors then this `work_item_context` of type `THREADPOOL_WORK_ITEM_HANDLE` would be returned indicating a succcess to the caller**]**
|
||||
|
||||
**S_R_S_THREADPOOL_WIN32_05_010: [** If any error occurs, `threadpool_create_work_item` shall fail, free the newly created context and return a `NULL` value. **]**
|
||||
|
||||
|
||||
### threadpool_schedule_work_item
|
||||
|
||||
```c
|
||||
MOCKABLE_FUNCTION(, int, threadpool_schedule_work_item, THANDLE(THREADPOOL), threadpool, THREADPOOL_WORK_ITEM_HANDLE, work_item_context);
|
||||
```
|
||||
|
||||
`threadpool_schedule_work_item` schedules a work item to be executed by the threadpool.
|
||||
|
||||
**S_R_S_THREADPOOL_WIN32_05_011: [** If `threadpool` is NULL, `threadpool_schedule_work_item` shall fail and return a `non-zero` value. **]**
|
||||
|
||||
**S_R_S_THREADPOOL_WIN32_05_012: [** If `work_item_context` is NULL, `threadpool_schedule_work_item` shall fail and return a `non-zero` value. **]**
|
||||
|
||||
**S_R_S_THREADPOOL_WIN32_05_013: [** `threadpool_schedule_work_item` shall call `SubmitThreadpoolWork` to submit the work item for execution. **]**
|
||||
|
||||
### threadpool_destroy_work_item
|
||||
|
||||
```c
|
||||
MOCKABLE_FUNCTION(, void, threadpool_destroy_work_item, THREADPOOL_WORK_ITEM_HANDLE, work_item_context);
|
||||
```
|
||||
|
||||
`threadpool_destroy_work_item` closes the `ptp_work` member variable in `work_item_context`and then frees the `work_item_context`
|
||||
|
||||
**S_R_S_THREADPOOL_WIN32_05_014: [** If `work_item_context` is `NULL`, `threadpool_destroy_work_item` shall fail and not do anything before returning. **]**
|
||||
|
||||
**S_R_S_THREADPOOL_WIN32_05_015: [** `threadpool_destroy_work_item` shall call `CloseThreadpoolWork` to close `ptp_work`. **]**
|
||||
|
||||
**S_R_S_THREADPOOL_WIN32_05_016: [** `threadpool_destroy_work_item` shall free the `work_item_context`. **]**
|
|
@ -37,6 +37,12 @@ extern "C" {
|
|||
int real_threadpool_open(THANDLE(THREADPOOL) threadpool);
|
||||
void real_threadpool_close(THANDLE(THREADPOOL) threadpool);
|
||||
|
||||
THREADPOOL_WORK_ITEM_HANDLE real_threadpool_create_work_item(THANDLE(THREADPOOL) threadpool, THREADPOOL_WORK_FUNCTION work_function, void* work_function_context);
|
||||
|
||||
int real_threadpool_schedule_work_item(THANDLE(THREADPOOL) threadpool, THREADPOOL_WORK_ITEM_HANDLE work_item_context);
|
||||
|
||||
void real_threadpool_destroy_work_item(THREADPOOL_WORK_ITEM_HANDLE work_item_context);
|
||||
|
||||
int real_threadpool_schedule_work(THANDLE(THREADPOOL) threadpool, THREADPOOL_WORK_FUNCTION work_function, void* work_function_context);
|
||||
|
||||
int real_threadpool_timer_start(THANDLE(THREADPOOL) threadpool, uint32_t start_delay_ms, uint32_t timer_period_ms, THREADPOOL_WORK_FUNCTION work_function, void* work_function_context, TIMER_INSTANCE_HANDLE* timer_handle);
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
#define threadpool_create real_threadpool_create
|
||||
#define threadpool_open real_threadpool_open
|
||||
#define threadpool_close real_threadpool_close
|
||||
#define threadpool_create_work_item real_threadpool_create_work_item
|
||||
#define threadpool_schedule_work_item real_threadpool_schedule_work_item
|
||||
#define threadpool_destroy_work_item real_threadpool_destroy_work_item
|
||||
#define threadpool_schedule_work real_threadpool_schedule_work
|
||||
#define threadpool_timer_start real_threadpool_timer_start
|
||||
#define threadpool_timer_restart real_threadpool_timer_restart
|
||||
|
|
|
@ -29,6 +29,13 @@ typedef struct WORK_ITEM_CONTEXT_TAG
|
|||
void* work_function_context;
|
||||
} WORK_ITEM_CONTEXT;
|
||||
|
||||
typedef struct THREADPOOL_WORK_ITEM_TAG
|
||||
{
|
||||
THREADPOOL_WORK_FUNCTION work_function;
|
||||
void* work_function_context;
|
||||
PTP_WORK* ptp_work;
|
||||
} THREADPOOL_WORK_ITEM, *THREADPOOL_WORK_ITEM_HANDLE;
|
||||
|
||||
typedef struct TIMER_INSTANCE_TAG
|
||||
{
|
||||
PTP_TIMER timer;
|
||||
|
@ -78,6 +85,11 @@ static VOID CALLBACK on_work_callback(PTP_CALLBACK_INSTANCE instance, PVOID cont
|
|||
}
|
||||
}
|
||||
|
||||
static VOID CALLBACK on_work_callback_v2(PTP_CALLBACK_INSTANCE instance, PVOID context, PTP_WORK work)
|
||||
{
|
||||
LogWarning("Printing %p %p %p", instance, context, work);
|
||||
}
|
||||
|
||||
static void internal_close(THREADPOOL* threadpool)
|
||||
{
|
||||
do
|
||||
|
@ -113,7 +125,7 @@ static void threadpool_dispose(THREADPOOL* threadpool)
|
|||
int32_t current_state = InterlockedCompareExchange(&threadpool->state, THREADPOOL_WIN32_STATE_CLOSING, THREADPOOL_WIN32_STATE_OPEN);
|
||||
if (current_state == THREADPOOL_WIN32_STATE_OPEN)
|
||||
{
|
||||
/* Codes_SRS_THREADPOOL_WIN32_01_007: [ threadpool_destroy shall perform an implicit close if threadpool is OPEN. ]*/
|
||||
/* Codes_SRS_THREADPOOL_WIN32_01_007: [ threadpool_dispose shall perform an implicit close if threadpool is OPEN. ]*/
|
||||
internal_close(threadpool);
|
||||
break;
|
||||
}
|
||||
|
@ -265,6 +277,26 @@ void threadpool_close(THANDLE(THREADPOOL) threadpool)
|
|||
}
|
||||
}
|
||||
|
||||
THREADPOOL_WORK_ITEM_HANDLE threadpool_create_work_item(THANDLE(THREADPOOL) threadpool, THREADPOOL_WORK_FUNCTION work_function, void* work_function_context)
|
||||
{
|
||||
(void*)threadpool;
|
||||
(void*)work_function;
|
||||
(void*)work_function_context;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int threadpool_schedule_work_item(THANDLE(THREADPOOL) threadpool, THREADPOOL_WORK_ITEM_HANDLE work_item_context)
|
||||
{
|
||||
(void*)threadpool;
|
||||
(void*)work_item_context;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void threadpool_destroy_work_item(THREADPOOL_WORK_ITEM_HANDLE work_item_context)
|
||||
{
|
||||
(void*)work_item_context;
|
||||
}
|
||||
|
||||
int threadpool_schedule_work(THANDLE(THREADPOOL) threadpool, THREADPOOL_WORK_FUNCTION work_function, void* work_function_context)
|
||||
{
|
||||
int result;
|
||||
|
|
Загрузка…
Ссылка в новой задаче