зеркало из https://github.com/Azure/c-pal.git
Add 64-bit APIs in interlocked_hl.h and sync.h (#413)
* Specs for interlocked and sync 64 * Specs for interlocked and sync 64 - Parth comments * Mergeable specs * Addressed Parth comments * Address Dan's comments * Implementation of 64 bit for interlocked_hl and sync * Added missing LogErrors * Added missing LogErrors and some Specs corrections * Corrected comment indentations * Addressed Dan's comments * Addressed Jelan's comments
This commit is contained in:
Родитель
76da349891
Коммит
3434cf0416
|
@ -26,8 +26,11 @@ extern "C" {
|
|||
MU_DEFINE_ENUM(WAIT_ON_ADDRESS_RESULT, WAIT_ON_ADDRESS_RESULT_VALUES);
|
||||
|
||||
MOCKABLE_FUNCTION(, WAIT_ON_ADDRESS_RESULT, wait_on_address, volatile_atomic int32_t*, address, int32_t, compare_value, uint32_t, timeout_ms);
|
||||
MOCKABLE_FUNCTION(, WAIT_ON_ADDRESS_RESULT, wait_on_address_64, volatile_atomic int64_t*, address, int64_t, compare_value, uint32_t, timeout_ms);
|
||||
MOCKABLE_FUNCTION(, void, wake_by_address_all, volatile_atomic int32_t*, address);
|
||||
MOCKABLE_FUNCTION(, void, wake_by_address_all_64, volatile_atomic int64_t*, address);
|
||||
MOCKABLE_FUNCTION(, void, wake_by_address_single, volatile_atomic int32_t*, address);
|
||||
MOCKABLE_FUNCTION(, void, wake_by_address_single_64, volatile_atomic int64_t*, address);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -21,8 +21,11 @@
|
|||
#define REGISTER_SYNC_GLOBAL_MOCK_HOOK() \
|
||||
MU_FOR_EACH_1(R2, \
|
||||
wait_on_address, \
|
||||
wait_on_address_64, \
|
||||
wake_by_address_all, \
|
||||
wake_by_address_single \
|
||||
wake_by_address_all_64, \
|
||||
wake_by_address_single, \
|
||||
wake_by_address_single_64 \
|
||||
)
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -31,8 +34,11 @@ extern "C" {
|
|||
|
||||
|
||||
WAIT_ON_ADDRESS_RESULT real_wait_on_address(volatile_atomic int32_t* address, int32_t compare_value, uint32_t timeout_ms);
|
||||
WAIT_ON_ADDRESS_RESULT real_wait_on_address_64(volatile_atomic int64_t* address, int64_t compare_value, uint32_t timeout_ms);
|
||||
void real_wake_by_address_all(volatile_atomic int32_t* address);
|
||||
void real_wake_by_address_all_64(volatile_atomic int64_t* address);
|
||||
void real_wake_by_address_single(volatile_atomic int32_t* address);
|
||||
void real_wake_by_address_single_64(volatile_atomic int64_t* address);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#define wait_on_address real_wait_on_address
|
||||
#define wake_by_address_all real_wake_by_address_all
|
||||
#define wake_by_address_single real_wake_by_address_single
|
||||
#define wait_on_address real_wait_on_address
|
||||
#define wait_on_address_64 real_wait_on_address_64
|
||||
#define wake_by_address_all real_wake_by_address_all
|
||||
#define wake_by_address_all_64 real_wake_by_address_all_64
|
||||
#define wake_by_address_single real_wake_by_address_single
|
||||
#define wake_by_address_single_64 real_wake_by_address_single_64
|
||||
|
||||
#define WAIT_ON_ADDRESS_RESULT real_WAIT_ON_ADDRESS_RESULT
|
||||
#define WAIT_ON_ADDRESS_RESULT real_WAIT_ON_ADDRESS_RESULT
|
||||
|
|
|
@ -37,6 +37,24 @@ static int increment_on_odd_values(void* address)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int increment_on_odd_values_64(void* address)
|
||||
{
|
||||
volatile_atomic int64_t* ptr = (volatile_atomic int64_t*)address;
|
||||
while (interlocked_add_64(ptr, 0) < 98)
|
||||
{
|
||||
int64_t value = interlocked_add_64(ptr, 0);
|
||||
while (value % 2 != 1)
|
||||
{
|
||||
ASSERT_IS_TRUE(wait_on_address_64(ptr, value, UINT32_MAX));
|
||||
value = interlocked_add_64(ptr, 0);
|
||||
}
|
||||
(void)interlocked_increment_64(ptr);
|
||||
wake_by_address_all_64(ptr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int increment_on_even_values(void* address)
|
||||
{
|
||||
volatile_atomic int32_t* ptr = (volatile_atomic int32_t*)address;
|
||||
|
@ -55,6 +73,24 @@ static int increment_on_even_values(void* address)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int increment_on_even_values_64(void* address)
|
||||
{
|
||||
volatile_atomic int64_t* ptr = (volatile_atomic int64_t*)address;
|
||||
while (interlocked_add_64(ptr, 0) < 99)
|
||||
{
|
||||
int64_t value = interlocked_add_64(ptr, 0);
|
||||
while (value % 2 != 0)
|
||||
{
|
||||
ASSERT_IS_TRUE(wait_on_address_64(ptr, value, UINT32_MAX));
|
||||
value = interlocked_add_64(ptr, 0);
|
||||
}
|
||||
(void)interlocked_increment_64(ptr);
|
||||
wake_by_address_all_64(ptr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static volatile_atomic int32_t create_count;
|
||||
static volatile_atomic int32_t woken_threads;
|
||||
static int increment_on_wake_up(void* address)
|
||||
|
@ -70,6 +106,21 @@ static int increment_on_wake_up(void* address)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static volatile_atomic int64_t create_count_64;
|
||||
static volatile_atomic int64_t woken_threads_64;
|
||||
static int increment_on_wake_up_64(void* address)
|
||||
{
|
||||
volatile_atomic int64_t* ptr = (volatile_atomic int64_t*)address;
|
||||
int64_t value = interlocked_add_64(ptr, 0);
|
||||
(void)interlocked_increment_64(&create_count_64);
|
||||
wake_by_address_single_64(&create_count_64);
|
||||
|
||||
ASSERT_ARE_EQUAL(WAIT_ON_ADDRESS_RESULT, WAIT_ON_ADDRESS_OK, wait_on_address_64(ptr, value, UINT32_MAX));
|
||||
(void)interlocked_increment_64(&woken_threads_64);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BEGIN_TEST_SUITE(TEST_SUITE_NAME_FROM_CMAKE)
|
||||
|
||||
TEST_SUITE_INITIALIZE(a)
|
||||
|
@ -90,37 +141,55 @@ TEST_FUNCTION_CLEANUP(d)
|
|||
{
|
||||
}
|
||||
|
||||
/*Tests_SRS_SYNC_43_001: [ wait_on_address shall atomically compare *address and *compare_address.]*/
|
||||
/*Tests_SRS_SYNC_43_007: [ If *address is equal to *compare_address, wait_on_address shall cause the thread to sleep. ]*/
|
||||
/*Tests_SRS_SYNC_43_008: [wait_on_address shall wait indefinitely until it is woken up by a call to wake_by_address_[single/all] if timeout_ms is equal to UINT32_MAX]*/
|
||||
/*Tests_SRS_SYNC_43_003: [ wait_on_address shall wait until another thread in the same process signals at address using wake_by_address_[single/all] and return true. ]*/
|
||||
/* Tests_SRS_SYNC_43_001: [ wait_on_address shall atomically compare *address and *compare_address.] */
|
||||
/* Tests_SRS_SYNC_43_007: [ If *address is equal to *compare_address, wait_on_address shall cause the thread to sleep. ] */
|
||||
/* Tests_SRS_SYNC_43_008: [wait_on_address shall wait indefinitely until it is woken up by a call to wake_by_address_[single/all] if timeout_ms is equal to UINT32_MAX] */
|
||||
/* Tests_SRS_SYNC_43_003: [ wait_on_address shall wait until another thread in the same process signals at address using wake_by_address_[single/all] and return true. ] */
|
||||
TEST_FUNCTION(two_threads_increment_alternately)
|
||||
{
|
||||
///arrange
|
||||
//arrange
|
||||
volatile_atomic int32_t var;
|
||||
(void)interlocked_exchange(&var, 0);
|
||||
THREAD_HANDLE thread1;
|
||||
THREAD_HANDLE thread2;
|
||||
|
||||
///act
|
||||
//act
|
||||
ASSERT_ARE_EQUAL(THREADAPI_RESULT, THREADAPI_OK, ThreadAPI_Create(&thread1, increment_on_even_values, (void*)&var));
|
||||
ASSERT_ARE_EQUAL(THREADAPI_RESULT, THREADAPI_OK, ThreadAPI_Create(&thread2, increment_on_odd_values, (void*)&var));
|
||||
|
||||
///assert
|
||||
//assert
|
||||
ASSERT_ARE_EQUAL(THREADAPI_RESULT, THREADAPI_OK, ThreadAPI_Join(thread1, NULL), "ThreadAPI_Join did not work");
|
||||
ASSERT_ARE_EQUAL(THREADAPI_RESULT, THREADAPI_OK, ThreadAPI_Join(thread2, NULL), "ThreadAPI_Join did not work");
|
||||
ASSERT_ARE_EQUAL(int32_t, 99, interlocked_add(&var, 0), "Threads did not increment value expected number of times.");
|
||||
}
|
||||
|
||||
/*Tests_SRS_SYNC_43_001: [ wait_on_address shall atomically compare *address and *compare_address.]*/
|
||||
/*Tests_SRS_SYNC_43_007: [ If *address is equal to *compare_address, wait_on_address shall cause the thread to sleep. ]*/
|
||||
/*Tests_SRS_SYNC_43_008: [wait_on_address shall wait indefinitely until it is woken up by a call to wake_by_address_[single/all] if timeout_ms is equal to UINT32_MAX]*/
|
||||
/*Tests_SRS_SYNC_43_003: [ wait_on_address shall wait until another thread in the same process signals at address using wake_by_address_[single/all] and return true. ]*/
|
||||
/*Tests_SRS_SYNC_43_004: [ wake_by_address_all shall cause all the thread(s) waiting on a call to wait_on_address with argument address to continue execution. ]*/
|
||||
/*Tests_SRS_SYNC_43_005: [ wake_by_address_single shall cause one thread waiting on a call to wait_on_address with argument address to continue execution. ]*/
|
||||
TEST_FUNCTION(two_threads_increment_alternately_64)
|
||||
{
|
||||
//arrange
|
||||
volatile_atomic int64_t var;
|
||||
(void)interlocked_exchange_64(&var, 0);
|
||||
THREAD_HANDLE thread1;
|
||||
THREAD_HANDLE thread2;
|
||||
|
||||
//act
|
||||
ASSERT_ARE_EQUAL(THREADAPI_RESULT, THREADAPI_OK, ThreadAPI_Create(&thread1, increment_on_even_values_64, (void*)&var));
|
||||
ASSERT_ARE_EQUAL(THREADAPI_RESULT, THREADAPI_OK, ThreadAPI_Create(&thread2, increment_on_odd_values_64, (void*)&var));
|
||||
|
||||
//assert
|
||||
ASSERT_ARE_EQUAL(THREADAPI_RESULT, THREADAPI_OK, ThreadAPI_Join(thread1, NULL), "ThreadAPI_Join did not work");
|
||||
ASSERT_ARE_EQUAL(THREADAPI_RESULT, THREADAPI_OK, ThreadAPI_Join(thread2, NULL), "ThreadAPI_Join did not work");
|
||||
ASSERT_ARE_EQUAL(int64_t, 99, interlocked_add_64(&var, 0), "Threads did not increment value expected number of times.");
|
||||
}
|
||||
|
||||
/* Tests_SRS_SYNC_43_001: [ wait_on_address shall atomically compare *address and *compare_address.] */
|
||||
/* Tests_SRS_SYNC_43_007: [ If *address is equal to *compare_address, wait_on_address shall cause the thread to sleep. ] */
|
||||
/* Tests_SRS_SYNC_43_008: [wait_on_address shall wait indefinitely until it is woken up by a call to wake_by_address_[single/all] if timeout_ms is equal to UINT32_MAX] */
|
||||
/* Tests_SRS_SYNC_43_003: [ wait_on_address shall wait until another thread in the same process signals at address using wake_by_address_[single/all] and return true. ] */
|
||||
/* Tests_SRS_SYNC_43_004: [ wake_by_address_all shall cause all the thread(s) waiting on a call to wait_on_address with argument address to continue execution. ] */
|
||||
/* Tests_SRS_SYNC_43_005: [ wake_by_address_single shall cause one thread waiting on a call to wait_on_address with argument address to continue execution. ] */
|
||||
TEST_FUNCTION(wake_up_all_threads)
|
||||
{
|
||||
///arrange
|
||||
//arrange
|
||||
volatile_atomic int32_t var;
|
||||
(void)interlocked_exchange(&var, 0);
|
||||
(void)interlocked_exchange(&create_count, 0);
|
||||
|
@ -128,7 +197,7 @@ TEST_FUNCTION(wake_up_all_threads)
|
|||
|
||||
(void)interlocked_exchange(&woken_threads, 0);
|
||||
|
||||
///act
|
||||
//act
|
||||
for (int i = 0; i < 100; ++i)
|
||||
{
|
||||
ASSERT_ARE_EQUAL(THREADAPI_RESULT, THREADAPI_OK, ThreadAPI_Create(&threads[i], increment_on_wake_up, (void*)&var));
|
||||
|
@ -164,43 +233,122 @@ TEST_FUNCTION(wake_up_all_threads)
|
|||
}
|
||||
}
|
||||
|
||||
TEST_FUNCTION(wake_up_all_threads_64)
|
||||
{
|
||||
//arrange
|
||||
volatile_atomic int64_t var;
|
||||
(void)interlocked_exchange_64(&var, 0);
|
||||
(void)interlocked_exchange_64(&create_count_64, 0);
|
||||
THREAD_HANDLE threads[100];
|
||||
|
||||
/*Tests_SRS_SYNC_43_001: [ wait_on_address shall atomically compare *address and *compare_address.]*/
|
||||
/*Tests_SRS_SYNC_43_002: [ wait_on_address shall immediately return true if *address is not equal to *compare_address.]*/
|
||||
(void)interlocked_exchange_64(&woken_threads_64, 0);
|
||||
|
||||
//act
|
||||
for (int i = 0; i < 100; ++i)
|
||||
{
|
||||
ASSERT_ARE_EQUAL(THREADAPI_RESULT, THREADAPI_OK, ThreadAPI_Create(&threads[i], increment_on_wake_up_64, (void*)&var));
|
||||
}
|
||||
|
||||
LogInfo("Waiting for threads to spin");
|
||||
int64_t current_create_count = interlocked_add_64(&create_count_64, 0);
|
||||
while (current_create_count < 100)
|
||||
{
|
||||
ASSERT_ARE_EQUAL(WAIT_ON_ADDRESS_RESULT, WAIT_ON_ADDRESS_OK, wait_on_address_64(&create_count_64, current_create_count, UINT32_MAX));
|
||||
current_create_count = interlocked_add_64(&create_count_64, 0);
|
||||
}
|
||||
|
||||
// have a cycle of sleep and wake by address all
|
||||
// we want to check that we wake up more than one thread most of the times as it cannot be make predictable when the threads run
|
||||
// ideally we'd have all threads woken by one call, but it can so happen that not all threads end up in their
|
||||
// wait at the time we call the first wake_by_address_all_64
|
||||
int32_t wake_by_address_all_call_count = 0;
|
||||
do
|
||||
{
|
||||
// sleep 1s
|
||||
ThreadAPI_Sleep(1000);
|
||||
wake_by_address_all_call_count++;
|
||||
|
||||
// wake all threads
|
||||
wake_by_address_all_64(&var);
|
||||
} while (interlocked_add_64(&woken_threads_64, 0) < 100);
|
||||
|
||||
LogInfo("Joining threads");
|
||||
for (int i = 0; i < 100; ++i)
|
||||
{
|
||||
ASSERT_ARE_EQUAL(THREADAPI_RESULT, THREADAPI_OK, ThreadAPI_Join(threads[i], NULL), "ThreadAPI_Join did not work");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Tests_SRS_SYNC_43_001: [ wait_on_address shall atomically compare *address and *compare_address.] */
|
||||
/* Tests_SRS_SYNC_43_002: [ wait_on_address shall immediately return true if *address is not equal to *compare_address.] */
|
||||
TEST_FUNCTION(wait_on_address_returns_immediately)
|
||||
{
|
||||
///arrange
|
||||
//arrange
|
||||
volatile_atomic int32_t var;
|
||||
(void)interlocked_exchange(&var, 0);
|
||||
int value = 1;
|
||||
|
||||
///act
|
||||
//act
|
||||
WAIT_ON_ADDRESS_RESULT return_val = wait_on_address(&var, value, UINT32_MAX);
|
||||
|
||||
///assert
|
||||
//assert
|
||||
ASSERT_ARE_EQUAL(WAIT_ON_ADDRESS_RESULT, WAIT_ON_ADDRESS_OK, return_val, "wait_on_address should have returned ok");
|
||||
}
|
||||
|
||||
/*Tests_SRS_SYNC_43_001: [ wait_on_address shall atomically compare *address and *compare_address.]*/
|
||||
/*Tests_SRS_SYNC_43_002: [ wait_on_address shall immediately return true if *address is not equal to *compare_address.]*/
|
||||
/*Tests_SRS_SYNC_43_009: [ If timeout_ms milliseconds elapse, wait_on_address shall return false. ]*/
|
||||
TEST_FUNCTION(wait_on_address_64_returns_immediately)
|
||||
{
|
||||
//arrange
|
||||
volatile_atomic int64_t var;
|
||||
(void)interlocked_exchange_64(&var, 0);
|
||||
int64_t value = 1;
|
||||
|
||||
//act
|
||||
WAIT_ON_ADDRESS_RESULT return_val = wait_on_address_64(&var, value, UINT32_MAX);
|
||||
|
||||
//assert
|
||||
ASSERT_ARE_EQUAL(WAIT_ON_ADDRESS_RESULT, WAIT_ON_ADDRESS_OK, return_val, "wait_on_address_64 should have returned ok");
|
||||
}
|
||||
|
||||
/* Tests_SRS_SYNC_43_001: [ wait_on_address shall atomically compare *address and *compare_address.] */
|
||||
/* Tests_SRS_SYNC_43_002: [ wait_on_address shall immediately return true if *address is not equal to *compare_address.] */
|
||||
/* Tests_SRS_SYNC_43_009: [ If timeout_ms milliseconds elapse, wait_on_address shall return false. ] */
|
||||
TEST_FUNCTION(wait_on_address_returns_after_timeout_elapses)
|
||||
{
|
||||
///arrange
|
||||
//arrange
|
||||
volatile_atomic int32_t var;
|
||||
(void)interlocked_exchange(&var, 0);
|
||||
int value = 0;
|
||||
int timeout = 1000;
|
||||
double tolerance_factor = 1.5;
|
||||
|
||||
/// act
|
||||
// act
|
||||
double start_time = timer_global_get_elapsed_ms();
|
||||
WAIT_ON_ADDRESS_RESULT return_val = wait_on_address(&var, value, timeout);
|
||||
double time_elapsed = timer_global_get_elapsed_ms() - start_time;
|
||||
|
||||
///assert
|
||||
//assert
|
||||
ASSERT_IS_TRUE(time_elapsed < timeout* tolerance_factor, "Too much time elapsed. Maximum Expected: %lf, Actual: %lf", timeout*tolerance_factor, time_elapsed);
|
||||
ASSERT_ARE_EQUAL(WAIT_ON_ADDRESS_RESULT, WAIT_ON_ADDRESS_TIMEOUT, return_val, "wait_on_address should have returned timeout");
|
||||
}
|
||||
|
||||
TEST_FUNCTION(wait_on_address_64_returns_after_timeout_elapses)
|
||||
{
|
||||
//arrange
|
||||
volatile_atomic int64_t var;
|
||||
(void)interlocked_exchange_64(&var, 0);
|
||||
int64_t value = 0;
|
||||
int32_t timeout = 1000;
|
||||
double tolerance_factor = 1.5;
|
||||
|
||||
// act
|
||||
double start_time = timer_global_get_elapsed_ms();
|
||||
WAIT_ON_ADDRESS_RESULT return_val = wait_on_address_64(&var, value, timeout);
|
||||
double time_elapsed = timer_global_get_elapsed_ms() - start_time;
|
||||
|
||||
//assert
|
||||
ASSERT_IS_TRUE(time_elapsed < timeout * tolerance_factor, "Too much time elapsed. Maximum Expected: %lf, Actual: %lf", timeout * tolerance_factor, time_elapsed);
|
||||
ASSERT_ARE_EQUAL(WAIT_ON_ADDRESS_RESULT, WAIT_ON_ADDRESS_TIMEOUT, return_val, "wait_on_address_64 should have returned timeout");
|
||||
}
|
||||
|
||||
END_TEST_SUITE(TEST_SUITE_NAME_FROM_CMAKE)
|
||||
|
|
|
@ -23,9 +23,9 @@ MOCKABLE_FUNCTION(, WAIT_ON_ADDRESS_RESULT, wait_on_address, volatile_atomic int
|
|||
|
||||
**SRS_SYNC_LINUX_43_001: [** `wait_on_address` shall initialize a `timespec` struct with `.tv_nsec` equal to `timeout_ms* 10^6`. **]**
|
||||
|
||||
**SRS_SYNC_LINUX_43_002: [** `wait_on_address` shall call `syscall` from `sys/syscall.h` with arguments `SYS_futex`, `address`, `FUTEX_WAIT_PRIVATE`, `compare_value`, `*timeout_struct`, `NULL`, `0`. **]**
|
||||
**SRS_SYNC_LINUX_43_002: [** `wait_on_address` shall call `syscall` to wait on value at `address` to change to a value different than the one provided in `compare_value`. **]**
|
||||
|
||||
**SRS_SYNC_LINUX_43_003: [** `wait_on_address` shall return `WAIT_ON_ADDRESS_OK` if `syscall` returns `0`.**]**
|
||||
**SRS_SYNC_LINUX_43_003: [** If the value at `address` changes to a value different from `compare_value` then `wait_on_address` shall return `WAIT_ON_ADDRESS_OK`. **]**
|
||||
|
||||
**SRS_SYNC_LINUX_01_001: [** if `syscall` returns a non-zero value and `errno` is `EAGAIN`, `wait_on_address` shall return `WAIT_ON_ADDRESS_OK`. **]**
|
||||
|
||||
|
@ -39,17 +39,18 @@ MOCKABLE_FUNCTION(, WAIT_ON_ADDRESS_RESULT, wait_on_address, volatile_atomic int
|
|||
MOCKABLE_FUNCTION(, WAIT_ON_ADDRESS_RESULT, wait_on_address_64, volatile_atomic int64_t*, address, int64_t, compare_value, uint32_t, timeout_ms)
|
||||
```
|
||||
|
||||
**S_R_S_SYNC_LINUX_05_001: [** `wait_on_address_64` shall initialize a `timespec` struct with `.tv_nsec` equal to `timeout_ms* 10^6`. **]**
|
||||
**SRS_SYNC_LINUX_05_001: [** `wait_on_address_64` shall initialize a `timespec` struct with `.tv_nsec` equal to `timeout_ms* 10^6`. **]**
|
||||
|
||||
**S_R_S_SYNC_LINUX_05_002: [** `wait_on_address_64` shall call `syscall` to wait on value at `address` to change than the one provided in `compare_value`. **]**
|
||||
**SRS_SYNC_LINUX_05_002: [** `wait_on_address_64` shall call `syscall` to wait on value at `address` to change to a value different than the one provided in `compare_value`. **]**
|
||||
|
||||
**S_R_S_SYNC_LINUX_05_003: [** If the value at `address` changes to a value different from `compare_value` then `wait_on_address_64` shall return `WAIT_ON_ADDRESS_OK` . **]**
|
||||
**SRS_SYNC_LINUX_05_003: [** If the value at `address` changes to a value different from `compare_value` then `wait_on_address_64` shall return `WAIT_ON_ADDRESS_OK`. **]**
|
||||
|
||||
**S_R_S_SYNC_LINUX_05_004: [** If `syscall` returns a non-zero value and `errno` is `EAGAIN`, `wait_on_address_64` shall return `WAIT_ON_ADDRESS_OK`. **]**
|
||||
**SRS_SYNC_LINUX_05_004: [** If `syscall` returns a non-zero value and `errno` is `EAGAIN`, `wait_on_address_64` shall return `WAIT_ON_ADDRESS_OK`. **]**
|
||||
|
||||
**S_R_S_SYNC_LINUX_05_005: [** If `syscall` returns a non-zero value and `errno` is `ETIMEDOUT`, `wait_on_address_64` shall return `WAIT_ON_ADDRESS_TIMEOUT`. **]**
|
||||
**SRS_SYNC_LINUX_05_005: [** If `syscall` returns a non-zero value and `errno` is `ETIMEDOUT`, `wait_on_address_64` shall return `WAIT_ON_ADDRESS_TIMEOUT`. **]**
|
||||
|
||||
**SRS_SYNC_LINUX_05_006: [** Otherwise, `wait_on_address_64` shall return `WAIT_ON_ADDRESS_ERROR`. **]**
|
||||
|
||||
**S_R_S_SYNC_LINUX_05_006: [** Otherwise, `wait_on_address_64` shall return `WAIT_ON_ADDRESS_ERROR`. **]**
|
||||
|
||||
## wake_by_address_all
|
||||
|
||||
|
@ -57,14 +58,15 @@ MOCKABLE_FUNCTION(, WAIT_ON_ADDRESS_RESULT, wait_on_address_64, volatile_atomic
|
|||
MOCKABLE_FUNCTION(, void, wake_by_address_all, volatile_atomic int32_t*, address)
|
||||
```
|
||||
|
||||
**SRS_SYNC_LINUX_43_005: [** `wake_by_address_all` shall call `syscall` from `sys/syscall.h` with arguments `SYS_futex`, `address`, `FUTEX_WAKE_PRIVATE`, `INT_MAX`, `NULL`, `NULL`, `0`. **]**
|
||||
**SRS_SYNC_LINUX_43_005: [** `wake_by_address_all` shall call `syscall` to wake all listeners listening on `address`. **]**
|
||||
|
||||
## wake_by_address_all_64
|
||||
|
||||
```c
|
||||
MOCKABLE_FUNCTION(, void, wake_by_address_all_64, volatile_atomic int64_t*, address)
|
||||
```
|
||||
**S_R_S_SYNC_LINUX_05_007: [** `wake_by_address_all_64` shall call `syscall` to wake all listeners listening on `address`. **]**
|
||||
|
||||
**SRS_SYNC_LINUX_05_007: [** `wake_by_address_all_64` shall call `syscall` to wake all listeners listening on `address`. **]**
|
||||
|
||||
## wake_by_address_single
|
||||
|
||||
|
@ -72,7 +74,7 @@ MOCKABLE_FUNCTION(, void, wake_by_address_all_64, volatile_atomic int64_t*, addr
|
|||
MOCKABLE_FUNCTION(, void, wake_by_address_single, volatile_atomic int32_t*, address)
|
||||
```
|
||||
|
||||
**SRS_SYNC_LINUX_43_006: [** `wake_by_address_single` shall call `syscall` from `sys/syscall.h` with arguments `SYS_futex`, `address`, `FUTEX_WAKE_PRIVATE`, `1`, `NULL`, `NULL`, `0`. **]**
|
||||
**SRS_SYNC_LINUX_43_006: [** `wake_by_address_single` shall call `syscall` to wake any single listener listening on `address`. **]**
|
||||
|
||||
## wake_by_address_single_64
|
||||
|
||||
|
@ -80,4 +82,4 @@ MOCKABLE_FUNCTION(, void, wake_by_address_single, volatile_atomic int32_t*, addr
|
|||
MOCKABLE_FUNCTION(, void, wake_by_address_single_64, volatile_atomic int64_t*, address)
|
||||
```
|
||||
|
||||
**S_R_S_SYNC_LINUX_05_008: [** `wake_by_address_single_64` shall call `syscall` to wake any single listener listening on `address`. **]**
|
||||
**SRS_SYNC_LINUX_05_008: [** `wake_by_address_single_64` shall call `syscall` to wake any single listener listening on `address`. **]**
|
|
@ -24,32 +24,71 @@ IMPLEMENT_MOCKABLE_FUNCTION(, WAIT_ON_ADDRESS_RESULT, wait_on_address, volatile_
|
|||
{
|
||||
WAIT_ON_ADDRESS_RESULT result;
|
||||
|
||||
/*Codes_SRS_SYNC_43_001: [ wait_on_address shall atomically compare *address and *compare_address.]*/
|
||||
/*Codes_SRS_SYNC_43_002: [ wait_on_address shall immediately return true if *address is not equal to *compare_address.]*/
|
||||
/*Codes_SRS_SYNC_43_007: [ If *address is equal to *compare_address, wait_on_address shall cause the thread to sleep. ]*/
|
||||
/*Codes_SRS_SYNC_43_009: [ If timeout_ms milliseconds elapse, wait_on_address shall return false. ]*/
|
||||
/*Codes_SRS_SYNC_43_008: [wait_on_address shall wait indefinitely until it is woken up by a call to wake_by_address_[single/all] if timeout_ms is equal to UINT32_MAX]*/
|
||||
/*Codes_SRS_SYNC_43_003: [ wait_on_address shall wait until another thread in the same process signals at address using wake_by_address_[single/all] and return true. ]*/
|
||||
/*Codes_SRS_SYNC_LINUX_43_001: [ wait_on_address shall initialize a timespec struct with .tv_nsec equal to timeout_ms* 10^6. ]*/
|
||||
/* Codes_SRS_SYNC_43_001: [ wait_on_address shall atomically compare *address and *compare_address.] */
|
||||
/* Codes_SRS_SYNC_43_002: [ wait_on_address shall immediately return true if *address is not equal to *compare_address.] */
|
||||
/* Codes_SRS_SYNC_43_007: [ If *address is equal to *compare_address, wait_on_address shall cause the thread to sleep. ] */
|
||||
/* Codes_SRS_SYNC_43_009: [ If timeout_ms milliseconds elapse, wait_on_address shall return false. ] */
|
||||
/* Codes_SRS_SYNC_43_008: [wait_on_address shall wait indefinitely until it is woken up by a call to wake_by_address_[single/all] if timeout_ms is equal to UINT32_MAX] */
|
||||
/* Codes_SRS_SYNC_43_003: [ wait_on_address shall wait until another thread in the same process signals at address using wake_by_address_[single/all] and return true. ] */
|
||||
/* Codes_SRS_SYNC_LINUX_43_001: [ wait_on_address shall initialize a timespec struct with .tv_nsec equal to timeout_ms* 10^6. ] */
|
||||
struct timespec timeout = {timeout_ms / 1000, (timeout_ms % 1000) * 1e6 };
|
||||
|
||||
/*Codes_SRS_SYNC_LINUX_43_002: [ wait_on_address shall call syscall from sys/syscall.h with arguments SYS_futex, address, FUTEX_WAIT_PRIVATE, compare_value, *timeout_struct, NULL, 0. ]*/
|
||||
/* Codes_SRS_SYNC_LINUX_43_002: [ wait_on_address shall call syscall to wait on value at address to change to a value different than the one provided in compare_value. ] */
|
||||
int syscall_result = syscall(SYS_futex, address, FUTEX_WAIT_PRIVATE, compare_value, &timeout, NULL, 0);
|
||||
if (syscall_result == 0)
|
||||
{
|
||||
/*Codes_SRS_SYNC_LINUX_43_003: [ wait_on_address shall return true if syscall returns 0.]*/
|
||||
/* Codes_SRS_SYNC_LINUX_43_003: [ If the value at address changes to a value different from compare_value then wait_on_address shall return WAIT_ON_ADDRESS_OK. ] */
|
||||
result = WAIT_ON_ADDRESS_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (errno == EAGAIN)
|
||||
{
|
||||
/* Codes_SRS_SYNC_LINUX_01_001: [ if syscall returns a non-zero value and errno is EAGAIN, wait_on_address shall return WAIT_ON_ADDRESS_OK. ]*/
|
||||
/* Codes_SRS_SYNC_LINUX_01_001: [ if syscall returns a non-zero value and errno is EAGAIN, wait_on_address shall return WAIT_ON_ADDRESS_OK. ] */
|
||||
result = WAIT_ON_ADDRESS_OK;
|
||||
}
|
||||
else if (errno == ETIMEDOUT)
|
||||
{
|
||||
/* Codes_SRS_SYNC_LINUX_24_001: [ if syscall returns a non-zero value and errno is ETIMEDOUT, wait_on_address shall return WAIT_ON_ADDRESS_TIMEOUT. ]*/
|
||||
/* Codes_SRS_SYNC_LINUX_24_001: [ if syscall returns a non-zero value and errno is ETIMEDOUT, wait_on_address shall return WAIT_ON_ADDRESS_TIMEOUT. ] */
|
||||
result = WAIT_ON_ADDRESS_TIMEOUT;
|
||||
}
|
||||
else
|
||||
{
|
||||
char err_msg[128];
|
||||
(void)strerror_r(errno, err_msg, 128);
|
||||
LogError("Failure in syscall, Error: %d: (%s)", errno, err_msg);
|
||||
/* Codes_SRS_SYNC_LINUX_43_004: [ Otherwise, wait_on_address shall return WAIT_ON_ADDRESS_ERROR. ] */
|
||||
result = WAIT_ON_ADDRESS_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, WAIT_ON_ADDRESS_RESULT, wait_on_address_64, volatile_atomic int64_t*, address, int64_t, compare_value, uint32_t, timeout_ms)
|
||||
{
|
||||
WAIT_ON_ADDRESS_RESULT result;
|
||||
|
||||
/* Codes_SRS_SYNC_LINUX_05_001: [ wait_on_address_64 shall initialize a timespec struct with .tv_nsec equal to timeout_ms* 10^6. ] */
|
||||
struct timespec timeout = {timeout_ms / 1000, (timeout_ms % 1000) * 1e6 };
|
||||
|
||||
/* Codes_SRS_SYNC_LINUX_05_002: [ wait_on_address_64 shall call syscall to wait on value at address to change to a value different than the one provided in compare_value. ] */
|
||||
int syscall_result = syscall(SYS_futex, address, FUTEX_WAIT_PRIVATE, compare_value, &timeout, NULL, 0);
|
||||
if (syscall_result == 0)
|
||||
{
|
||||
/* Codes_SRS_SYNC_LINUX_05_003: [ If the value at address changes to a value different from compare_value then wait_on_address_64 shall return WAIT_ON_ADDRESS_OK. ] */
|
||||
result = WAIT_ON_ADDRESS_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (errno == EAGAIN)
|
||||
{
|
||||
/* Codes_SRS_SYNC_LINUX_05_004: [ If syscall returns a non-zero value and errno is EAGAIN, wait_on_address_64 shall return WAIT_ON_ADDRESS_OK. ] */
|
||||
result = WAIT_ON_ADDRESS_OK;
|
||||
}
|
||||
else if (errno == ETIMEDOUT)
|
||||
{
|
||||
/* Codes_SRS_SYNC_LINUX_05_005: [ If syscall returns a non-zero value and errno is ETIMEDOUT, wait_on_address_64 shall return WAIT_ON_ADDRESS_TIMEOUT. ] */
|
||||
result = WAIT_ON_ADDRESS_TIMEOUT;
|
||||
}
|
||||
else
|
||||
|
@ -57,7 +96,7 @@ IMPLEMENT_MOCKABLE_FUNCTION(, WAIT_ON_ADDRESS_RESULT, wait_on_address, volatile_
|
|||
char err_msg[128];
|
||||
(void)strerror_r(errno, err_msg, 128);
|
||||
LogError("failure in syscall, Error: %d: (%s)", errno, err_msg);
|
||||
/*Codes_SRS_SYNC_LINUX_43_004: [ Otherwise, wait_on_address shall return WAIT_ON_ADDRESS_ERROR.*/
|
||||
/* Codes_SRS_SYNC_LINUX_05_006: [ Otherwise, wait_on_address_64 shall return WAIT_ON_ADDRESS_ERROR. ] */
|
||||
result = WAIT_ON_ADDRESS_ERROR;
|
||||
}
|
||||
}
|
||||
|
@ -67,14 +106,26 @@ IMPLEMENT_MOCKABLE_FUNCTION(, WAIT_ON_ADDRESS_RESULT, wait_on_address, volatile_
|
|||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, void, wake_by_address_all, volatile_atomic int32_t*, address)
|
||||
{
|
||||
/*Codes_SRS_SYNC_43_004: [ wake_by_address_all shall cause all the thread(s) waiting on a call to wait_on_address with argument address to continue execution. ]*/
|
||||
/*Codes_SRS_SYNC_LINUX_43_005: [ wake_by_address_all shall call syscall from sys/syscall.h with arguments SYS_futex, address, FUTEX_WAKE_PRIVATE, INT_MAX, NULL, NULL, 0. ]*/
|
||||
/* Codes_SRS_SYNC_43_004: [ wake_by_address_all shall cause all the thread(s) waiting on a call to wait_on_address with argument address to continue execution. ] */
|
||||
/* Codes_SRS_SYNC_LINUX_43_005: [ wake_by_address_all shall call syscall to wake all listeners listening on address. ] */
|
||||
syscall(SYS_futex, address, FUTEX_WAKE_PRIVATE, INT_MAX, NULL, NULL, 0);
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, void, wake_by_address_all_64, volatile_atomic int64_t*, address)
|
||||
{
|
||||
/* Codes_SRS_SYNC_LINUX_05_007: [ wake_by_address_all_64 shall call syscall to wake all listeners listening on address. ] */
|
||||
syscall(SYS_futex, address, FUTEX_WAKE_PRIVATE, INT_MAX, NULL, NULL, 0);
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, void, wake_by_address_single, volatile_atomic int32_t*, address)
|
||||
{
|
||||
/*Codes_SRS_SYNC_43_005: [ wake_by_address_single shall cause one thread waiting on a call to wait_on_address with argument address to continue execution. ]*/
|
||||
/*Codes_SRS_SYNC_LINUX_43_006: [ wake_by_address_single shall call syscall from sys/syscall.h with arguments SYS_futex, address, FUTEX_WAKE_PRIVATE, 1, NULL, NULL, 0. ]*/
|
||||
/* Codes_SRS_SYNC_43_005: [ wake_by_address_single shall cause one thread waiting on a call to wait_on_address with argument address to continue execution. ] */
|
||||
/* Codes_SRS_SYNC_LINUX_43_006: [ wake_by_address_single shall call syscall to wake any single listener listening on address. ] */
|
||||
syscall(SYS_futex, address, FUTEX_WAKE_PRIVATE, 1, NULL, NULL, 0);
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, void, wake_by_address_single_64, volatile_atomic int64_t*, address)
|
||||
{
|
||||
/* Codes_SRS_SYNC_LINUX_05_008: [ wake_by_address_single_64 shall call syscall to wake any single listener listening on address. ] */
|
||||
syscall(SYS_futex, address, FUTEX_WAKE_PRIVATE, 1, NULL, NULL, 0);
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ static int expected_return_val;
|
|||
|
||||
static int hook_mock_syscall(long call_code, int* uaddr, int futex_op, int val, const struct timespec* timeout, int* uaddr2, int val3)
|
||||
{
|
||||
/*Tests_SRS_SYNC_LINUX_43_001: [ wait_on_address shall initialize a timespec struct with .tv_nsec equal to timeout_ms* 10^6. ]*/
|
||||
/* Tests_SRS_SYNC_LINUX_43_001: [ wait_on_address shall initialize a timespec struct with .tv_nsec equal to timeout_ms* 10^6. ] */
|
||||
if(check_timeout)
|
||||
{
|
||||
ASSERT_ARE_EQUAL(long, (expected_timeout_ms / 1000), (long)timeout->tv_sec);
|
||||
|
@ -80,32 +80,53 @@ TEST_FUNCTION_CLEANUP(cleans)
|
|||
{
|
||||
}
|
||||
|
||||
/*Tests_SRS_SYNC_LINUX_43_002: [ wait_on_address shall call syscall from sys/syscall.h with arguments SYS_futex, address, FUTEX_WAIT_PRIVATE, compare_value, timeout_struct, NULL, NULL. ]*/
|
||||
/*Tests_SRS_SYNC_LINUX_43_003: [ wait_on_address shall return true if syscall returns 0.]*/
|
||||
/* Tests_SRS_SYNC_LINUX_43_002: [ wait_on_address shall call syscall to wait on value at address to change to a value different than the one provided in compare_value. ] */
|
||||
/* Tests_SRS_SYNC_LINUX_43_003: [ If the value at address changes to a value different from compare_value then wait_on_address shall return WAIT_ON_ADDRESS_OK. ] */
|
||||
|
||||
TEST_FUNCTION(wait_on_address_calls_syscall_successfully)
|
||||
{
|
||||
///arrange
|
||||
//arrange
|
||||
volatile_atomic int32_t var;
|
||||
(void)atomic_exchange(&var, INT32_MAX);
|
||||
check_timeout = true;
|
||||
expected_timeout_ms = 100;
|
||||
expected_return_val = 0;
|
||||
STRICT_EXPECTED_CALL(mock_syscall(SYS_futex, (int32_t*)&var, FUTEX_WAIT_PRIVATE, INT32_MAX, IGNORED_ARG, NULL, 0));
|
||||
STRICT_EXPECTED_CALL(mock_syscall(SYS_futex, (int*)&var, FUTEX_WAIT_PRIVATE, INT32_MAX, IGNORED_ARG, NULL, 0));
|
||||
|
||||
///act
|
||||
//act
|
||||
WAIT_ON_ADDRESS_RESULT return_val = wait_on_address(&var, INT32_MAX, expected_timeout_ms);
|
||||
|
||||
///assert
|
||||
//assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls(), "Actual calls differ from expected calls");
|
||||
ASSERT_ARE_EQUAL(WAIT_ON_ADDRESS_RESULT, WAIT_ON_ADDRESS_OK, return_val, "wait_on_address should have returned ok");
|
||||
}
|
||||
|
||||
/*Tests_SRS_SYNC_LINUX_43_002: [ wait_on_address shall call syscall from sys/syscall.h with arguments SYS_futex, address, FUTEX_WAIT_PRIVATE, *compare_address, timeout_struct, NULL, NULL. ]*/
|
||||
/*Tests_SRS_SYNC_LINUX_43_004: [ Otherwise, wait_on_address shall return false.*/
|
||||
/* Tests_SRS_SYNC_LINUX_05_001: [ wait_on_address_64 shall initialize a timespec struct with .tv_nsec equal to timeout_ms* 10^6. ] */
|
||||
/* Tests_SRS_SYNC_LINUX_05_002: [ wait_on_address_64 shall call syscall to wait on value at address to change to a value different than the one provided in compare_value. ] */
|
||||
/* Tests_SRS_SYNC_LINUX_05_003: [ If the value at address changes to a value different from compare_value then wait_on_address_64 shall return WAIT_ON_ADDRESS_OK. ] */
|
||||
TEST_FUNCTION(wait_on_address_calls_64_syscall_successfully)
|
||||
{
|
||||
//arrange
|
||||
volatile_atomic int64_t var;
|
||||
(void)atomic_exchange(&var, INT64_MAX);
|
||||
check_timeout = true;
|
||||
expected_timeout_ms = 100;
|
||||
expected_return_val = 0;
|
||||
STRICT_EXPECTED_CALL(mock_syscall(SYS_futex, (int*)&var, FUTEX_WAIT_PRIVATE, var, IGNORED_ARG, NULL, 0));
|
||||
|
||||
//act
|
||||
WAIT_ON_ADDRESS_RESULT return_val = wait_on_address_64(&var, INT64_MAX, expected_timeout_ms);
|
||||
|
||||
//assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls(), "Actual calls differ from expected calls");
|
||||
ASSERT_ARE_EQUAL(WAIT_ON_ADDRESS_RESULT, WAIT_ON_ADDRESS_OK, return_val, "wait_on_address_64 should have returned ok");
|
||||
}
|
||||
|
||||
/* Tests_SRS_SYNC_LINUX_43_002: [ wait_on_address shall call syscall to wait on value at address to change to a value different than the one provided in compare_value. ] */
|
||||
/* Tests_SRS_SYNC_LINUX_43_004: [ Otherwise, wait_on_address shall return WAIT_ON_ADDRESS_ERROR.] */
|
||||
TEST_FUNCTION(wait_on_address_calls_sycall_unsuccessfully)
|
||||
{
|
||||
///arrange
|
||||
//arrange
|
||||
volatile_atomic int32_t var;
|
||||
int32_t val = INT32_MAX;
|
||||
(void)atomic_exchange(&var, val);
|
||||
|
@ -114,18 +135,40 @@ TEST_FUNCTION(wait_on_address_calls_sycall_unsuccessfully)
|
|||
expected_return_val = -1;
|
||||
STRICT_EXPECTED_CALL(mock_syscall(SYS_futex, (int*)&var, FUTEX_WAIT_PRIVATE, val, IGNORED_ARG, NULL, 0));
|
||||
|
||||
///act
|
||||
//act
|
||||
WAIT_ON_ADDRESS_RESULT return_val = wait_on_address(&var, val, expected_timeout_ms);
|
||||
|
||||
///assert
|
||||
//assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls(), "Actual calls differ from expected calls");
|
||||
ASSERT_ARE_EQUAL(WAIT_ON_ADDRESS_RESULT, WAIT_ON_ADDRESS_ERROR, return_val, "wait_on_address should have returned error");
|
||||
}
|
||||
|
||||
/* Tests_SRS_SYNC_LINUX_01_001: [ if syscall returns a non-zero value and errno is EAGAIN, wait_on_address shall return true. ]*/
|
||||
/* Tests_SRS_SYNC_LINUX_05_001: [ wait_on_address_64 shall initialize a timespec struct with .tv_nsec equal to timeout_ms* 10^6. ] */
|
||||
/* Tests_SRS_SYNC_LINUX_05_002: [ wait_on_address_64 shall call syscall to wait on value at address to change to a value different than the one provided in compare_value. ] */
|
||||
/* Tests_SRS_SYNC_LINUX_05_006: [ Otherwise, wait_on_address_64 shall return WAIT_ON_ADDRESS_ERROR. ] */
|
||||
TEST_FUNCTION(wait_on_address_64_calls_syscall_unsuccessfully)
|
||||
{
|
||||
//arrange
|
||||
volatile_atomic int64_t var;
|
||||
int64_t val = INT64_MAX;
|
||||
(void)atomic_exchange(&var, val);
|
||||
check_timeout = true;
|
||||
expected_timeout_ms = 1500;
|
||||
expected_return_val = -1;
|
||||
STRICT_EXPECTED_CALL(mock_syscall(SYS_futex, (int*)&var, FUTEX_WAIT_PRIVATE, val, IGNORED_ARG, NULL, 0));
|
||||
|
||||
//act
|
||||
WAIT_ON_ADDRESS_RESULT return_val = wait_on_address_64(&var, val, expected_timeout_ms);
|
||||
|
||||
//assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls(), "Actual calls differ from expected calls");
|
||||
ASSERT_ARE_EQUAL(WAIT_ON_ADDRESS_RESULT, WAIT_ON_ADDRESS_ERROR, return_val, "wait_on_address_64 should have returned error");
|
||||
}
|
||||
|
||||
/* Tests_SRS_SYNC_LINUX_01_001: [ if syscall returns a non-zero value and errno is EAGAIN, wait_on_address shall return WAIT_ON_ADDRESS_OK. ] */
|
||||
TEST_FUNCTION(when_syscall_fails_and_errno_is_EAGAIN_wait_on_address_succeeds)
|
||||
{
|
||||
///arrange
|
||||
//arrange
|
||||
volatile_atomic int32_t var;
|
||||
int32_t val = INT32_MAX;
|
||||
(void)atomic_exchange(&var, val);
|
||||
|
@ -134,18 +177,40 @@ TEST_FUNCTION(when_syscall_fails_and_errno_is_EAGAIN_wait_on_address_succeeds)
|
|||
STRICT_EXPECTED_CALL(mock_syscall(SYS_futex, (int*)&var, FUTEX_WAIT_PRIVATE, val, IGNORED_ARG, NULL, 0))
|
||||
.SetReturn(-1);
|
||||
|
||||
///act
|
||||
//act
|
||||
WAIT_ON_ADDRESS_RESULT return_val = wait_on_address(&var, val, expected_timeout_ms);
|
||||
|
||||
///assert
|
||||
//assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls(), "Actual calls differ from expected calls");
|
||||
ASSERT_ARE_EQUAL(WAIT_ON_ADDRESS_RESULT, WAIT_ON_ADDRESS_OK, return_val, "wait_on_address should have returned ok");
|
||||
}
|
||||
|
||||
/* Tests_SRS_SYNC_LINUX_24_001: [ if syscall returns a non-zero value and errno is ETIMEDOUT, wait_on_address shall return WAIT_ON_ADDRESS_TIMEOUT. ]*/
|
||||
/* Tests_SRS_SYNC_LINUX_05_001: [ wait_on_address_64 shall initialize a timespec struct with .tv_nsec equal to timeout_ms* 10^6. ] */
|
||||
/* Tests_SRS_SYNC_LINUX_05_002: [ wait_on_address_64 shall call syscall to wait on value at address to change to a value different than the one provided in compare_value. ] */
|
||||
/* Tests_SRS_SYNC_LINUX_05_004: [ If syscall returns a non-zero value and errno is EAGAIN, wait_on_address_64 shall return WAIT_ON_ADDRESS_OK. ] */
|
||||
TEST_FUNCTION(when_syscall_fails_and_errno_is_EAGAIN_wait_on_address_64_succeeds)
|
||||
{
|
||||
//arrange
|
||||
volatile_atomic int64_t var;
|
||||
int64_t val = INT64_MAX;
|
||||
(void)atomic_exchange(&var, val);
|
||||
mock_errno = EAGAIN;
|
||||
|
||||
STRICT_EXPECTED_CALL(mock_syscall(SYS_futex, (int*)&var, FUTEX_WAIT_PRIVATE, val, IGNORED_ARG, NULL, 0))
|
||||
.SetReturn(-1);
|
||||
|
||||
//act
|
||||
WAIT_ON_ADDRESS_RESULT return_val = wait_on_address_64(&var, val, expected_timeout_ms);
|
||||
|
||||
//assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls(), "Actual calls differ from expected calls");
|
||||
ASSERT_ARE_EQUAL(WAIT_ON_ADDRESS_RESULT, WAIT_ON_ADDRESS_OK, return_val, "wait_on_address_64 should have returned ok");
|
||||
}
|
||||
|
||||
/* Tests_SRS_SYNC_LINUX_24_001: [ if syscall returns a non-zero value and errno is ETIMEDOUT, wait_on_address shall return WAIT_ON_ADDRESS_TIMEOUT. ] */
|
||||
TEST_FUNCTION(when_syscall_fails_and_errno_is_ETIME_wait_on_address_fails)
|
||||
{
|
||||
///arrange
|
||||
//arrange
|
||||
volatile_atomic int32_t var;
|
||||
int32_t val = INT32_MAX;
|
||||
(void)atomic_exchange(&var, val);
|
||||
|
@ -154,43 +219,97 @@ TEST_FUNCTION(when_syscall_fails_and_errno_is_ETIME_wait_on_address_fails)
|
|||
STRICT_EXPECTED_CALL(mock_syscall(SYS_futex, (int*)&var, FUTEX_WAIT_PRIVATE, val, IGNORED_ARG, NULL, 0))
|
||||
.SetReturn(-1);
|
||||
|
||||
///act
|
||||
//act
|
||||
WAIT_ON_ADDRESS_RESULT return_val = wait_on_address(&var, val, expected_timeout_ms);
|
||||
|
||||
///assert
|
||||
//assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls(), "Actual calls differ from expected calls");
|
||||
ASSERT_ARE_EQUAL(WAIT_ON_ADDRESS_RESULT, WAIT_ON_ADDRESS_TIMEOUT, return_val, "wait_on_address should have returned timeout");
|
||||
}
|
||||
|
||||
/*Tests_SRS_SYNC_LINUX_43_005: [ wake_by_address_all shall call syscall from sys/syscall.h with arguments SYS_futex, address, FUTEX_WAKE_PRIVATE, INT_MAX, NULL, NULL, NULL. ]*/
|
||||
/* Tests_SRS_SYNC_LINUX_05_001: [ wait_on_address_64 shall initialize a timespec struct with .tv_nsec equal to timeout_ms* 10^6. ] */
|
||||
/* Tests_SRS_SYNC_LINUX_05_002: [ wait_on_address_64 shall call syscall to wait on value at address to change to a value different than the one provided in compare_value. ] */
|
||||
/* Tests_SRS_SYNC_LINUX_05_005: [ If syscall returns a non-zero value and errno is ETIMEDOUT, wait_on_address_64 shall return WAIT_ON_ADDRESS_TIMEOUT. ]*/
|
||||
TEST_FUNCTION(when_syscall_fails_and_errno_is_ETIME_wait_on_address_64_fails)
|
||||
{
|
||||
//arrange
|
||||
volatile_atomic int64_t var;
|
||||
int64_t val = INT64_MAX;
|
||||
(void)atomic_exchange(&var, val);
|
||||
mock_errno = ETIMEDOUT;
|
||||
|
||||
STRICT_EXPECTED_CALL(mock_syscall(SYS_futex, (int*)&var, FUTEX_WAIT_PRIVATE, val, IGNORED_ARG, NULL, 0))
|
||||
.SetReturn(-1);
|
||||
|
||||
//act
|
||||
WAIT_ON_ADDRESS_RESULT return_val = wait_on_address_64(&var, val, expected_timeout_ms);
|
||||
|
||||
//assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls(), "Actual calls differ from expected calls");
|
||||
ASSERT_ARE_EQUAL(WAIT_ON_ADDRESS_RESULT, WAIT_ON_ADDRESS_TIMEOUT, return_val, "wait_on_address_64 should have returned timeout");
|
||||
}
|
||||
|
||||
/* Tests_SRS_SYNC_LINUX_43_005: [ wake_by_address_all shall call syscall to wake all listeners listening on address. ] */
|
||||
TEST_FUNCTION(wake_by_address_all_calls_sycall)
|
||||
{
|
||||
///arrange
|
||||
//arrange
|
||||
volatile_atomic int32_t var;
|
||||
int32_t val = INT32_MAX;
|
||||
(void)atomic_exchange(&var, val);
|
||||
STRICT_EXPECTED_CALL(mock_syscall(SYS_futex, (int*)&var, FUTEX_WAKE_PRIVATE, INT_MAX, NULL, NULL, 0));
|
||||
|
||||
///act
|
||||
//act
|
||||
wake_by_address_all(&var);
|
||||
|
||||
///assert
|
||||
//assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls(), "Actual calls differ from expected calls");
|
||||
}
|
||||
|
||||
/*Tests_SRS_SYNC_LINUX_43_006: [ wake_by_address_single shall call syscall from sys/syscall.h with arguments SYS_futex, address, FUTEX_WAKE_PRIVATE, 1, NULL, NULL, NULL. ]*/
|
||||
/* Tests_SRS_SYNC_LINUX_05_007: [ wake_by_address_all_64 shall call syscall to wake all listeners listening on address. ] */
|
||||
TEST_FUNCTION(wake_by_address_all_64_calls_sycall)
|
||||
{
|
||||
//arrange
|
||||
volatile_atomic int64_t var;
|
||||
int64_t val = INT64_MAX;
|
||||
(void)atomic_exchange(&var, val);
|
||||
STRICT_EXPECTED_CALL(mock_syscall(SYS_futex, (int*)&var, FUTEX_WAKE_PRIVATE, INT_MAX, NULL, NULL, 0));
|
||||
|
||||
//act
|
||||
wake_by_address_all_64(&var);
|
||||
|
||||
//assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls(), "Actual calls differ from expected calls");
|
||||
}
|
||||
|
||||
/* Tests_SRS_SYNC_LINUX_43_006: [ wake_by_address_single shall call syscall to wake any single listener listening on address. ] */
|
||||
TEST_FUNCTION(wake_by_address_single_calls_sycall)
|
||||
{
|
||||
///arrange
|
||||
//arrange
|
||||
volatile_atomic int32_t var;
|
||||
int32_t val = INT32_MAX;
|
||||
(void)atomic_exchange(&var, val);
|
||||
STRICT_EXPECTED_CALL(mock_syscall(SYS_futex, (int*)&var, FUTEX_WAKE_PRIVATE, 1, NULL, NULL, 0));
|
||||
|
||||
///act
|
||||
//act
|
||||
wake_by_address_single(&var);
|
||||
|
||||
///assert
|
||||
//assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls(), "Actual calls differ from expected calls");
|
||||
}
|
||||
|
||||
/* Tests_SRS_SYNC_LINUX_05_008: [ wake_by_address_single_64 shall call syscall to wake any single listener listening on address. ] */
|
||||
TEST_FUNCTION(wake_by_address_single_64_calls_sycall)
|
||||
{
|
||||
//arrange
|
||||
volatile_atomic int64_t var;
|
||||
int64_t val = INT64_MAX;
|
||||
(void)atomic_exchange(&var, val);
|
||||
STRICT_EXPECTED_CALL(mock_syscall(SYS_futex, (int*)&var, FUTEX_WAKE_PRIVATE, 1, NULL, NULL, 0));
|
||||
|
||||
//act
|
||||
wake_by_address_single_64(&var);
|
||||
|
||||
//assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls(), "Actual calls differ from expected calls");
|
||||
}
|
||||
END_TEST_SUITE(TEST_SUITE_NAME_FROM_CMAKE)
|
||||
|
|
|
@ -34,19 +34,21 @@ MOCKABLE_FUNCTION(, WAIT_ON_ADDRESS_RESULT, wait_on_address, volatile_atomic int
|
|||
```c
|
||||
MOCKABLE_FUNCTION(, WAIT_ON_ADDRESS_RESULT, wait_on_address_64, volatile_atomic int64_t*, address, int64_t, compare_value, uint32_t, timeout_ms)
|
||||
```
|
||||
**S_R_S_SYNC_WIN32_05_001: [** `wait_on_address_64` shall call `WaitOnAddress` to wait on the value at 64-bit `address` to be different than `compare_value` for `timeout_ms` milliseconds. **]**
|
||||
|
||||
**S_R_S_SYNC_WIN32_05_002: [** If `WaitOnAddress` fails due to timeout, `wait_on_address_64` shall fail and return `WAIT_ON_ADDRESS_TIMEOUT`. **]**
|
||||
**SRS_SYNC_WIN32_05_001: [** `wait_on_address_64` shall call `WaitOnAddress` to wait on the value at 64-bit `address` to be different than `compare_value` for `timeout_ms` milliseconds. **]**
|
||||
|
||||
**S_R_S_SYNC_WIN32_05_003: [** If `WaitOnAddress` fails due to any other reason, `wait_on_address_64` shall fail and return `WAIT_ON_ADDRESS_ERROR`. **]**
|
||||
**SRS_SYNC_WIN32_05_002: [** If `WaitOnAddress` fails due to timeout, `wait_on_address_64` shall fail and return `WAIT_ON_ADDRESS_TIMEOUT`. **]**
|
||||
|
||||
**S_R_S_SYNC_WIN32_05_004: [** If `WaitOnAddress` succeeds, `wait_on_address` shall return `WAIT_ON_ADDRESS_OK`. **]**
|
||||
**SRS_SYNC_WIN32_05_003: [** If `WaitOnAddress` fails due to any other reason, `wait_on_address_64` shall fail and return `WAIT_ON_ADDRESS_ERROR`. **]**
|
||||
|
||||
**SRS_SYNC_WIN32_05_004: [** If `WaitOnAddress` succeeds, `wait_on_address_64` shall return `WAIT_ON_ADDRESS_OK`. **]**
|
||||
|
||||
## wake_by_address_all
|
||||
|
||||
```c
|
||||
MOCKABLE_FUNCTION(, void, wake_by_address_all, volatile_atomic int32_t*, address)
|
||||
```
|
||||
|
||||
**SRS_SYNC_WIN32_43_003: [** `wake_by_address_all` shall call `WakeByAddressAll` to notify all listeners waiting on the 32-bit `address`. **]**
|
||||
|
||||
## wake_by_address_all_64
|
||||
|
@ -54,7 +56,8 @@ MOCKABLE_FUNCTION(, void, wake_by_address_all, volatile_atomic int32_t*, address
|
|||
```c
|
||||
MOCKABLE_FUNCTION(, void, wake_by_address_all_64, volatile_atomic int64_t*, address)
|
||||
```
|
||||
**S_R_S_SYNC_WIN32_05_005: [** `wake_by_address_all_64` shall call `WakeByAddressAll` to notify all listeners waiting on the 64-bit `address`. **]**
|
||||
|
||||
**SRS_SYNC_WIN32_05_005: [** `wake_by_address_all_64` shall call `WakeByAddressAll` to notify all listeners waiting on the 64-bit `address`. **]**
|
||||
|
||||
## wake_by_address_single
|
||||
|
||||
|
@ -62,10 +65,10 @@ MOCKABLE_FUNCTION(, void, wake_by_address_all_64, volatile_atomic int64_t*, addr
|
|||
MOCKABLE_FUNCTION(, void, wake_by_address_single, volatile_atomic int32_t*, address)
|
||||
```
|
||||
|
||||
**SRS_SYNC_WIN32_43_004: [** `wake_by_address_single` shall call `WakeByAddressSingle` notify a single listeners waiting on the 32-bit `address`. **]**
|
||||
**SRS_SYNC_WIN32_43_004: [** `wake_by_address_single` shall call `WakeByAddressSingle` to notify a single listeners waiting on the 32-bit `address`. **]**
|
||||
|
||||
```c
|
||||
MOCKABLE_FUNCTION(, void, wake_by_address_single_64, volatile_atomic int64_t*, address)
|
||||
```
|
||||
|
||||
**S_R_S_SYNC_WIN32_05_006: [** `wake_by_address_single_64` shall call `WakeByAddressSingle` notify a single listeners waiting on the 64-bit `address`. **]**
|
||||
**SRS_SYNC_WIN32_05_006: [** `wake_by_address_single_64` shall call `WakeByAddressSingle` to notify a single listeners waiting on the 64-bit `address`. **]**
|
|
@ -10,72 +10,72 @@
|
|||
|
||||
#include "umock_c/umock_c_prod.h" // for IMPLEMENT_MOCKABLE_FUNCTION
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, int32_t, interlocked_add, volatile int32_t*, addend, int32_t, value)
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, int32_t, interlocked_add, volatile int32_t*, addend, int32_t, value)
|
||||
{
|
||||
/*Codes_SRS_INTERLOCKED_43_001 [ interlocked_add shall atomically add *addend with value and store the result in *addend.]*/
|
||||
/*Codes_SRS_INTERLOCKED_43_032: [ interlocked_add shall return the result of the addition.]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_001: [ interlocked_add shall call InterlockedAdd from windows.h. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_002: [ interlocked_add shall return the result of the addition. ]*/
|
||||
/* Codes_SRS_INTERLOCKED_43_001 [ interlocked_add shall atomically add *addend with value and store the result in *addend.] */
|
||||
/* Codes_SRS_INTERLOCKED_43_032: [ interlocked_add shall return the result of the addition.] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_001: [ interlocked_add shall call InterlockedAdd from windows.h. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_002: [ interlocked_add shall return the result of the addition. ] */
|
||||
|
||||
return InterlockedAdd((volatile LONG*)addend, value);
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, int64_t, interlocked_add_64, volatile int64_t*, addend, int64_t, value)
|
||||
{
|
||||
/*Codes_SRS_INTERLOCKED_43_065: [ interlocked_add_64 shall atomically add 64-bit integers *addend and value and store the result in *addend. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_43_066: [ interlocked_add_64 shall return the result of the addition. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_064: [ interlocked_add_64 shall call InterlockedAdd64 from windows.h. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_065: [ interlocked_add_64 shall return the result of the addition. ]*/
|
||||
/* Codes_SRS_INTERLOCKED_43_065: [ interlocked_add_64 shall atomically add 64-bit integers *addend and value and store the result in *addend. ] */
|
||||
/* Codes_SRS_INTERLOCKED_43_066: [ interlocked_add_64 shall return the result of the addition. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_064: [ interlocked_add_64 shall call InterlockedAdd64 from windows.h. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_065: [ interlocked_add_64 shall return the result of the addition. ] */
|
||||
|
||||
return InterlockedAdd64((volatile LONG64*)addend, value);
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, int32_t, interlocked_and, volatile int32_t*, destination, int32_t, value)
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, int32_t, interlocked_and, volatile int32_t*, destination, int32_t, value)
|
||||
{
|
||||
/*Codes_SRS_INTERLOCKED_43_002 [ interlocked_and shall perform an atomic bitwise AND operation on the 32-bit integer values *destination and value and store the result in *destination.]*/
|
||||
/*Codes_SRS_INTERLOCKED_43_033: [ interlocked_and shall return the initial value of *destination.]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_003: [ interlocked_and shall call InterlockedAnd from windows.h. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_004: [ interlocked_and shall return the initial value of *destination. ]*/
|
||||
/* Codes_SRS_INTERLOCKED_43_002 [ interlocked_and shall perform an atomic bitwise AND operation on the 32-bit integer values *destination and value and store the result in *destination.] */
|
||||
/* Codes_SRS_INTERLOCKED_43_033: [ interlocked_and shall return the initial value of *destination.] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_003: [ interlocked_and shall call InterlockedAnd from windows.h. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_004: [ interlocked_and shall return the initial value of *destination. ] */
|
||||
|
||||
return InterlockedAnd((volatile LONG*)destination, value);
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, int16_t, interlocked_and_16, volatile int16_t*, destination, int16_t, value)
|
||||
{
|
||||
/*Codes_SRS_INTERLOCKED_43_003 [ interlocked_and_16 shall perform an atomic bitwise AND operation on the 16-bit integer values *destination and value and store the result in *destination.]*/
|
||||
/*Codes_SRS_INTERLOCKED_43_034: [ interlocked_and_16 shall return the initial value of *destination.]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_005: [ interlocked_and_16 shall call InterlockedAnd16 from windows.h. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_006: [ interlocked_and_16 shall return the initial value of *destination. ]*/
|
||||
/* Codes_SRS_INTERLOCKED_43_003 [ interlocked_and_16 shall perform an atomic bitwise AND operation on the 16-bit integer values *destination and value and store the result in *destination.] */
|
||||
/* Codes_SRS_INTERLOCKED_43_034: [ interlocked_and_16 shall return the initial value of *destination.] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_005: [ interlocked_and_16 shall call InterlockedAnd16 from windows.h. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_006: [ interlocked_and_16 shall return the initial value of *destination. ] */
|
||||
|
||||
return InterlockedAnd16((volatile SHORT*)destination, value);
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, int64_t, interlocked_and_64, volatile int64_t*, destination, int64_t, value)
|
||||
{
|
||||
/*Codes_SRS_INTERLOCKED_43_004 [ interlocked_and_64 shall perform an atomic bitwise AND operation on the 64-bit integer values *destination and value and store the result in *destination.]*/
|
||||
/*Codes_SRS_INTERLOCKED_43_035: [ interlocked_and_64 shall return the initial value of *destination.]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_007: [ interlocked_and_64 shall call InterlockedAnd64 from windows.h. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_008: [ interlocked_and_64 shall return the initial value of *destination. ]*/
|
||||
/* Codes_SRS_INTERLOCKED_43_004 [ interlocked_and_64 shall perform an atomic bitwise AND operation on the 64-bit integer values *destination and value and store the result in *destination.] */
|
||||
/* Codes_SRS_INTERLOCKED_43_035: [ interlocked_and_64 shall return the initial value of *destination.] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_007: [ interlocked_and_64 shall call InterlockedAnd64 from windows.h. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_008: [ interlocked_and_64 shall return the initial value of *destination. ] */
|
||||
|
||||
return InterlockedAnd64((volatile LONG64*)destination, value);
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, int8_t, interlocked_and_8, volatile int8_t*, destination, int8_t, value)
|
||||
{
|
||||
/*Codes_SRS_INTERLOCKED_43_005 [ interlocked_and_8 shall perform an atomic bitwise AND operation on the 8-bit integer values *destination and value and store the result in *destination]*/
|
||||
/*Codes_SRS_INTERLOCKED_43_036: [ interlocked_and_8 shall return the initial value of *destination. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_009: [ interlocked_and_8 shall call InterlockedAnd8 from windows.h. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_010: [ interlocked_and_8 shall return the initial value of *destination. ]*/
|
||||
/* Codes_SRS_INTERLOCKED_43_005 [ interlocked_and_8 shall perform an atomic bitwise AND operation on the 8-bit integer values *destination and value and store the result in *destination] */
|
||||
/* Codes_SRS_INTERLOCKED_43_036: [ interlocked_and_8 shall return the initial value of *destination. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_009: [ interlocked_and_8 shall call InterlockedAnd8 from windows.h. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_010: [ interlocked_and_8 shall return the initial value of *destination. ] */
|
||||
|
||||
return InterlockedAnd8((volatile char*)destination, value);
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, int32_t, interlocked_compare_exchange, volatile int32_t*, destination, int32_t, exchange, int32_t, comperand)
|
||||
{
|
||||
/*Codes_SRS_INTERLOCKED_43_006 [ interlocked_compare_exchange shall compare the 32-bit integers pointed to by destination and comperand. If they are equal, *destination is set to exchange. These operations are performed atomically.*]*/
|
||||
/*Codes_SRS_INTERLOCKED_43_037: [ interlocked_compare_exchange shall return the initial value of *destination.]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_011: [ interlocked_compare_exchange shall call InterlockedCompareExchange from windows.h. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_012: [ interlocked_compare_exchange shall return the initial value of *destination. ]*/
|
||||
/* Codes_SRS_INTERLOCKED_43_006 [ interlocked_compare_exchange shall compare the 32-bit integers pointed to by destination and comperand. If they are equal, *destination is set to exchange. These operations are performed atomically.*] */
|
||||
/* Codes_SRS_INTERLOCKED_43_037: [ interlocked_compare_exchange shall return the initial value of *destination.] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_011: [ interlocked_compare_exchange shall call InterlockedCompareExchange from windows.h. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_012: [ interlocked_compare_exchange shall return the initial value of *destination. ] */
|
||||
|
||||
return InterlockedCompareExchange((volatile LONG*)destination, exchange, comperand);
|
||||
}
|
||||
|
@ -83,13 +83,13 @@ IMPLEMENT_MOCKABLE_FUNCTION(, int32_t, interlocked_compare_exchange, volatile in
|
|||
#ifdef _WIN64
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, bool, interlocked_compare_exchange_128, volatile int64_t*, destination, int64_t, exchange_high, int64_t, exchange_low, int64_t*, comperand_result)
|
||||
{
|
||||
/*Codes_SRS_INTERLOCKED_43_007 [ interlocked_compare_exchange_128 shall compare *destination with *comperand_result. If they are equal, destination[0] is set to exchange_low and destination[1] is set to exchange_high. These operations are performed atomically.]*/
|
||||
/*Codes_SRS_INTERLOCKED_43_039: [ interlocked_compare_exchange_128 shall store the initial value of *destination in *comperand_result regardless of the result of the comparison. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_43_038: [ interlocked_compare_exchange_128 shall return true if *comperand_result equals the original value of *destination.]*/
|
||||
/*Codes_SRS_INTERLOCKED_43_063: [ interlocked_compare_exchange_128 shall return false if *comperand_result does not equal the original value of *destination. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_013: [ interlocked_compare_exchange_128 shall call InterlockedCompareExchange128 from windows.h. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_014: [ interlocked_compare_exchange_128 shall return true if *comperand_result equals the original value of *destination.]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_063: [ interlocked_compare_exchange_128 shall return false if *comperand_result does not equal the original value of *destination. ]*/
|
||||
/* Codes_SRS_INTERLOCKED_43_007 [ interlocked_compare_exchange_128 shall compare *destination with *comperand_result. If they are equal, destination[0] is set to exchange_low and destination[1] is set to exchange_high. These operations are performed atomically.] */
|
||||
/* Codes_SRS_INTERLOCKED_43_039: [ interlocked_compare_exchange_128 shall store the initial value of *destination in *comperand_result regardless of the result of the comparison. ] */
|
||||
/* Codes_SRS_INTERLOCKED_43_038: [ interlocked_compare_exchange_128 shall return true if *comperand_result equals the original value of *destination.] */
|
||||
/* Codes_SRS_INTERLOCKED_43_063: [ interlocked_compare_exchange_128 shall return false if *comperand_result does not equal the original value of *destination. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_013: [ interlocked_compare_exchange_128 shall call InterlockedCompareExchange128 from windows.h. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_014: [ interlocked_compare_exchange_128 shall return true if *comperand_result equals the original value of *destination.] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_063: [ interlocked_compare_exchange_128 shall return false if *comperand_result does not equal the original value of *destination. ] */
|
||||
|
||||
return InterlockedCompareExchange128((volatile LONG64*)destination, exchange_high, exchange_low, (LONG64*)comperand_result);
|
||||
}
|
||||
|
@ -97,240 +97,240 @@ IMPLEMENT_MOCKABLE_FUNCTION(, bool, interlocked_compare_exchange_128, volatile i
|
|||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, int16_t, interlocked_compare_exchange_16, volatile int16_t*, destination, int16_t, exchange, int16_t, comperand)
|
||||
{
|
||||
/*Codes_SRS_INTERLOCKED_43_009 [interlocked_compare_exchange_16 shall compare the 16-bit integers pointed to by destination and comperand. If they are equal, *destination is set to exchange. These operations are performed atomically.]*/
|
||||
/*Codes_SRS_INTERLOCKED_43_040: [ interlocked_compare_exchange_16 shall return the initial value of *destination. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_015: [ interlocked_compare_exchange_16 shall call InterlockedCompareExchange16 from windows.h. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_016: [ interlocked_compare_exchange_16 shall return the initial value of *destination. ]*/
|
||||
/* Codes_SRS_INTERLOCKED_43_009 [interlocked_compare_exchange_16 shall compare the 16-bit integers pointed to by destination and comperand. If they are equal, *destination is set to exchange. These operations are performed atomically.] */
|
||||
/* Codes_SRS_INTERLOCKED_43_040: [ interlocked_compare_exchange_16 shall return the initial value of *destination. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_015: [ interlocked_compare_exchange_16 shall call InterlockedCompareExchange16 from windows.h. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_016: [ interlocked_compare_exchange_16 shall return the initial value of *destination. ] */
|
||||
|
||||
return InterlockedCompareExchange16((volatile SHORT*)destination, exchange, comperand);
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, int64_t, interlocked_compare_exchange_64, volatile int64_t*, destination, int64_t, exchange, int64_t, comperand)
|
||||
{
|
||||
/*Codes_SRS_INTERLOCKED_43_008 [interlocked_compare_exchange_64 shall compare the 64-bit integers pointed to by destination and comperand. If they are equal, *destination is set to exchange. These operations are performed atomically.]*/
|
||||
/*Codes_SRS_INTERLOCKED_43_041: [ interlocked_compare_exchange_64 shall return the initial value of *destination. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_017: [ interlocked_compare_exchange_64 shall call InterlockedCompareExchange64 from windows.h. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_018: [ interlocked_compare_exchange_64 shall return the initial value of *destination. ]*/
|
||||
/* Codes_SRS_INTERLOCKED_43_008 [interlocked_compare_exchange_64 shall compare the 64-bit integers pointed to by destination and comperand. If they are equal, *destination is set to exchange. These operations are performed atomically.] */
|
||||
/* Codes_SRS_INTERLOCKED_43_041: [ interlocked_compare_exchange_64 shall return the initial value of *destination. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_017: [ interlocked_compare_exchange_64 shall call InterlockedCompareExchange64 from windows.h. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_018: [ interlocked_compare_exchange_64 shall return the initial value of *destination. ] */
|
||||
|
||||
return InterlockedCompareExchange64((volatile LONG64*)destination, exchange, comperand);
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, void*, interlocked_compare_exchange_pointer, void* volatile*, destination, void*, exchange, void*, comperand)
|
||||
{
|
||||
/*Codes_SRS_INTERLOCKED_43_010 [interlocked_compare_exchange_pointer shall compare the pointers destination and comperand. If they are equal, *destination is set to exchange. These operations are performed atomically.]*/
|
||||
/*Codes_SRS_INTERLOCKED_43_042: [ interlocked_compare_exchange_pointer shall return the initial value of *destination. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_019: [ interlocked_compare_exchange_pointer shall call InterlockedCompareExchangePointer from windows.h. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_020: [ interlocked_compare_exchange_pointer shall return the initial value of *destination. ]*/
|
||||
/* Codes_SRS_INTERLOCKED_43_010 [interlocked_compare_exchange_pointer shall compare the pointers destination and comperand. If they are equal, *destination is set to exchange. These operations are performed atomically.] */
|
||||
/* Codes_SRS_INTERLOCKED_43_042: [ interlocked_compare_exchange_pointer shall return the initial value of *destination. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_019: [ interlocked_compare_exchange_pointer shall call InterlockedCompareExchangePointer from windows.h. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_020: [ interlocked_compare_exchange_pointer shall return the initial value of *destination. ] */
|
||||
|
||||
return InterlockedCompareExchangePointer((PVOID volatile *)destination, exchange, comperand);
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, int32_t, interlocked_decrement, volatile int32_t*, addend)
|
||||
{
|
||||
/*Codes_SRS_INTERLOCKED_43_011[ interlocked_decrement shall atomically decrement (decrease by one) the 32-bit variable *addend.]*/
|
||||
/*Codes_SRS_INTERLOCKED_43_043: [ interlocked_decrement shall return the decremented value. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_021: [ interlocked_decrement shall call InterlockedDecrement from windows.h. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_022: [ interlocked_decrement shall return the resulting 32-bit integer value. ]*/
|
||||
/* Codes_SRS_INTERLOCKED_43_011[ interlocked_decrement shall atomically decrement (decrease by one) the 32-bit variable *addend.] */
|
||||
/* Codes_SRS_INTERLOCKED_43_043: [ interlocked_decrement shall return the decremented value. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_021: [ interlocked_decrement shall call InterlockedDecrement from windows.h. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_022: [ interlocked_decrement shall return the resulting 32-bit integer value. ] */
|
||||
|
||||
return InterlockedDecrement((volatile LONG*)addend);
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, int16_t, interlocked_decrement_16, volatile int16_t*, addend)
|
||||
{
|
||||
/*Codes_SRS_INTERLOCKED_43_012[ interlocked_decrement_16 shall atomically decrement (decrease by one) the 16-bit variable *addend.]*/
|
||||
/*Codes_SRS_INTERLOCKED_43_044: [ interlocked_decrement_16 shall return the decremented value. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_023: [ interlocked_decrement_16 shall call InterlockedDecrement16 from windows.h. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_024: [ interlocked_decrement_16 shall return the resulting 16-bit integer value. ]*/
|
||||
/* Codes_SRS_INTERLOCKED_43_012[ interlocked_decrement_16 shall atomically decrement (decrease by one) the 16-bit variable *addend.] */
|
||||
/* Codes_SRS_INTERLOCKED_43_044: [ interlocked_decrement_16 shall return the decremented value. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_023: [ interlocked_decrement_16 shall call InterlockedDecrement16 from windows.h. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_024: [ interlocked_decrement_16 shall return the resulting 16-bit integer value. ] */
|
||||
|
||||
return InterlockedDecrement16((volatile SHORT*)addend);
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, int64_t, interlocked_decrement_64, volatile int64_t*, addend)
|
||||
{
|
||||
/*Codes_SRS_INTERLOCKED_43_013[ interlocked_decrement_64 shall atomically decrement (decrease by one) the 64-bit variable *addend.]*/
|
||||
/*Codes_SRS_INTERLOCKED_43_045: [ interlocked_decrement_64 shall return the decremented value. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_025: [ interlocked_decrement_64 shall call InterlockedDecrement64 from windows.h. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_026: [ interlocked_decrement_64 shall return the resulting 64-bit integer value. ]*/
|
||||
/* Codes_SRS_INTERLOCKED_43_013[ interlocked_decrement_64 shall atomically decrement (decrease by one) the 64-bit variable *addend.] */
|
||||
/* Codes_SRS_INTERLOCKED_43_045: [ interlocked_decrement_64 shall return the decremented value. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_025: [ interlocked_decrement_64 shall call InterlockedDecrement64 from windows.h. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_026: [ interlocked_decrement_64 shall return the resulting 64-bit integer value. ] */
|
||||
|
||||
return InterlockedDecrement64((volatile LONG64*)addend);
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, int32_t, interlocked_exchange, volatile int32_t*, target, int32_t, value)
|
||||
{
|
||||
/*Codes_SRS_INTERLOCKED_43_014 [ interlocked_exchange shall set the 32-bit variable pointed to by target to value as an atomic operation.]*/
|
||||
/*Codes_SRS_INTERLOCKED_43_046: [ interlocked_exchange shall return the initial value pointed to by target. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_027: [ interlocked_exchange shall call InterlockedExchange from windows.h. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_028: [ interlocked_exchange shall return the initial value pointed to by target. ]*/
|
||||
/* Codes_SRS_INTERLOCKED_43_014 [ interlocked_exchange shall set the 32-bit variable pointed to by target to value as an atomic operation.] */
|
||||
/* Codes_SRS_INTERLOCKED_43_046: [ interlocked_exchange shall return the initial value pointed to by target. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_027: [ interlocked_exchange shall call InterlockedExchange from windows.h. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_028: [ interlocked_exchange shall return the initial value pointed to by target. ] */
|
||||
|
||||
return InterlockedExchange((volatile LONG*)target, value);
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, int16_t, interlocked_exchange_16, volatile int16_t*, target, int16_t, value)
|
||||
{
|
||||
/*Codes_SRS_INTERLOCKED_43_015 [ interlocked_exchange_16 shall set the 16-bit variable pointed to by target to value as an atomic operation.]*/
|
||||
/*Codes_SRS_INTERLOCKED_43_047: [ interlocked_exchange_16 shall return the initial value pointed to by target. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_029: [ interlocked_exchange_16 shall call InterlockedExchange16 from windows.h. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_030: [ interlocked_exchange_16 shall return the initial value pointed to by target. ]*/
|
||||
/* Codes_SRS_INTERLOCKED_43_015 [ interlocked_exchange_16 shall set the 16-bit variable pointed to by target to value as an atomic operation.] */
|
||||
/* Codes_SRS_INTERLOCKED_43_047: [ interlocked_exchange_16 shall return the initial value pointed to by target. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_029: [ interlocked_exchange_16 shall call InterlockedExchange16 from windows.h. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_030: [ interlocked_exchange_16 shall return the initial value pointed to by target. ] */
|
||||
|
||||
return InterlockedExchange16((volatile SHORT*)target, value);
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, int64_t, interlocked_exchange_64, volatile int64_t*, target, int64_t, value)
|
||||
{
|
||||
/*Codes_SRS_INTERLOCKED_43_016 [ interlocked_exchange_64 shall set the 64-bit variable pointed to by target to value as an atomic operation.]*/
|
||||
/*Codes_SRS_INTERLOCKED_43_048: [ interlocked_exchange_64 shall return the initial value pointed to by target. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_031: [ interlocked_exchange_64 shall call InterlockedExchange64 from windows.h. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_032: [ interlocked_exchange_64 shall return the initial value pointed to by target. ]*/
|
||||
/* Codes_SRS_INTERLOCKED_43_016 [ interlocked_exchange_64 shall set the 64-bit variable pointed to by target to value as an atomic operation.] */
|
||||
/* Codes_SRS_INTERLOCKED_43_048: [ interlocked_exchange_64 shall return the initial value pointed to by target. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_031: [ interlocked_exchange_64 shall call InterlockedExchange64 from windows.h. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_032: [ interlocked_exchange_64 shall return the initial value pointed to by target. ] */
|
||||
|
||||
return InterlockedExchange64((volatile LONG64*)target, value);
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, int8_t, interlocked_exchange_8, volatile int8_t*, target, int8_t, value)
|
||||
{
|
||||
/*Codes_SRS_INTERLOCKED_43_017 [ interlocked_exchange_8 shall set the 8-bit variable pointed to by target to value as an atomic operation.]*/
|
||||
/*Codes_SRS_INTERLOCKED_43_049: [ interlocked_exchange_8 shall return the initial value pointed to by target. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_033: [ interlocked_exchange_8 shall call InterlockedExchange8 from windows.h. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_034: [ interlocked_exchange_8 shall return the initial value pointed to by target. ]*/
|
||||
/* Codes_SRS_INTERLOCKED_43_017 [ interlocked_exchange_8 shall set the 8-bit variable pointed to by target to value as an atomic operation.] */
|
||||
/* Codes_SRS_INTERLOCKED_43_049: [ interlocked_exchange_8 shall return the initial value pointed to by target. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_033: [ interlocked_exchange_8 shall call InterlockedExchange8 from windows.h. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_034: [ interlocked_exchange_8 shall return the initial value pointed to by target. ] */
|
||||
|
||||
return InterlockedExchange8((volatile CHAR*)target, value);
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, int32_t, interlocked_exchange_add, volatile int32_t*, addend, int32_t, value)
|
||||
{
|
||||
/*Codes_SRS_INTERLOCKED_43_018 [ interlocked_exchange_add shall perform an atomic addition of the 32-bit values *addend and value and store the result in *addend.]*/
|
||||
/*Codes_SRS_INTERLOCKED_43_050: [ interlocked_exchange_add shall return the initial value of *addend. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_035: [ interlocked_exchange_add shall call InterlockedExchangeAdd from windows.h. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_036: [ interlocked_exchange_add shall return the initial value of *addend. ]*/
|
||||
/* Codes_SRS_INTERLOCKED_43_018 [ interlocked_exchange_add shall perform an atomic addition of the 32-bit values *addend and value and store the result in *addend.] */
|
||||
/* Codes_SRS_INTERLOCKED_43_050: [ interlocked_exchange_add shall return the initial value of *addend. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_035: [ interlocked_exchange_add shall call InterlockedExchangeAdd from windows.h. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_036: [ interlocked_exchange_add shall return the initial value of *addend. ] */
|
||||
|
||||
return InterlockedExchangeAdd((volatile LONG*)addend, value);
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, int64_t, interlocked_exchange_add_64, volatile int64_t*, addend, int64_t, value)
|
||||
{
|
||||
/*Codes_SRS_INTERLOCKED_43_019 [ interlocked_exchange_add_64 shall perform an atomic addition of the 64-bit values *addend and value and store the result in *addend.]*/
|
||||
/*Codes_SRS_INTERLOCKED_43_064: [ interlocked_exchange_add_64 shall return the initial value of *addend. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_037: [ interlocked_exchange_add_64 shall call InterlockedExchangeAdd64 from windows.h. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_038: [ interlocked_exchange_add_64 shall return the initial value of *addend. ]*/
|
||||
/* Codes_SRS_INTERLOCKED_43_019 [ interlocked_exchange_add_64 shall perform an atomic addition of the 64-bit values *addend and value and store the result in *addend.] */
|
||||
/* Codes_SRS_INTERLOCKED_43_064: [ interlocked_exchange_add_64 shall return the initial value of *addend. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_037: [ interlocked_exchange_add_64 shall call InterlockedExchangeAdd64 from windows.h. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_038: [ interlocked_exchange_add_64 shall return the initial value of *addend. ] */
|
||||
|
||||
return InterlockedExchangeAdd64((volatile LONG64*)addend, value);
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, void*, interlocked_exchange_pointer, void* volatile*, target, void*, value)
|
||||
{
|
||||
/*Codes_SRS_INTERLOCKED_43_020 [ interlocked_exchange_pointer shall atomically set *target to value]*/
|
||||
/*Codes_SRS_INTERLOCKED_43_051: [ interlocked_exchange_pointer shall return the initial value of *target. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_039: [ interlocked_exchange_pointer shall call InterlockedExchangePointer from windows.h. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_040: [interlocked_exchange_pointer shall return the initial address pointed to by the target parameter ]*/
|
||||
/* Codes_SRS_INTERLOCKED_43_020 [ interlocked_exchange_pointer shall atomically set *target to value] */
|
||||
/* Codes_SRS_INTERLOCKED_43_051: [ interlocked_exchange_pointer shall return the initial value of *target. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_039: [ interlocked_exchange_pointer shall call InterlockedExchangePointer from windows.h. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_040: [interlocked_exchange_pointer shall return the initial address pointed to by the target parameter ] */
|
||||
|
||||
return InterlockedExchangePointer((PVOID volatile*)target, value);
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, int32_t, interlocked_increment, volatile int32_t*, addend)
|
||||
{
|
||||
/*Codes_SRS_INTERLOCKED_43_021 [ interlocked_increment shall atomically increment (increase by one) the 32-bit variable *addend.]*/
|
||||
/*Codes_SRS_INTERLOCKED_43_052: [ interlocked_increment shall return the incremented value. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_041: [ interlocked_increment shall call InterlockedIncrement from windows.h. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_042: [ interlocked_increment shall return the incremented 32-bit integer. ]*/
|
||||
/* Codes_SRS_INTERLOCKED_43_021 [ interlocked_increment shall atomically increment (increase by one) the 32-bit variable *addend.] */
|
||||
/* Codes_SRS_INTERLOCKED_43_052: [ interlocked_increment shall return the incremented value. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_041: [ interlocked_increment shall call InterlockedIncrement from windows.h. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_042: [ interlocked_increment shall return the incremented 32-bit integer. ] */
|
||||
|
||||
return InterlockedIncrement((volatile LONG*)addend);
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, int16_t, interlocked_increment_16, volatile int16_t*, addend)
|
||||
{
|
||||
/*Codes_SRS_INTERLOCKED_43_022 [ interlocked_increment_16 shall atomically increment (increase by one) the 16-bit variable *addend.]*/
|
||||
/*Codes_SRS_INTERLOCKED_43_053: [ interlocked_increment_16 shall return the incremented value. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_043: [ interlocked_increment_16 shall call InterlockedIncrement16 from windows.h. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_044: [ interlocked_increment_16 shall return the incremented 16-bit integer. ]*/
|
||||
/* Codes_SRS_INTERLOCKED_43_022 [ interlocked_increment_16 shall atomically increment (increase by one) the 16-bit variable *addend.] */
|
||||
/* Codes_SRS_INTERLOCKED_43_053: [ interlocked_increment_16 shall return the incremented value. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_043: [ interlocked_increment_16 shall call InterlockedIncrement16 from windows.h. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_044: [ interlocked_increment_16 shall return the incremented 16-bit integer. ] */
|
||||
|
||||
return InterlockedIncrement16((volatile SHORT*)addend);
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, int64_t, interlocked_increment_64, volatile int64_t*, addend)
|
||||
{
|
||||
/*Codes_SRS_INTERLOCKED_43_023 [ interlocked_increment_64 shall atomically increment (increase by one) the 64-bit variable *addend.]*/
|
||||
/*Codes_SRS_INTERLOCKED_43_054: [ interlocked_increment_64 shall return the incremented value. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_045: [ interlocked_increment_64 shall call InterlockedIncrement64 from windows.h. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_046: [ interlocked_increment_64 shall return the incremented 64-bit integer. ]*/
|
||||
/* Codes_SRS_INTERLOCKED_43_023 [ interlocked_increment_64 shall atomically increment (increase by one) the 64-bit variable *addend.] */
|
||||
/* Codes_SRS_INTERLOCKED_43_054: [ interlocked_increment_64 shall return the incremented value. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_045: [ interlocked_increment_64 shall call InterlockedIncrement64 from windows.h. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_046: [ interlocked_increment_64 shall return the incremented 64-bit integer. ] */
|
||||
|
||||
return InterlockedIncrement64((volatile LONG64*)addend);
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, int32_t, interlocked_or, volatile int32_t*, destination, int32_t, value)
|
||||
{
|
||||
/*Codes_SRS_INTERLOCKED_43_024 [ interlocked_or shall perform an atomic bitwise OR operation on the 32-bit integers *destination and value and store the result in destination.]*/
|
||||
/*Codes_SRS_INTERLOCKED_43_055: [ interlocked_or shall return the initial value of *destination. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_047: [ interlocked_or shall call InterlockedOr from windows.h. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_048: [ interlocked_or shall return the initial value of *destination. ]*/
|
||||
/* Codes_SRS_INTERLOCKED_43_024 [ interlocked_or shall perform an atomic bitwise OR operation on the 32-bit integers *destination and value and store the result in destination.] */
|
||||
/* Codes_SRS_INTERLOCKED_43_055: [ interlocked_or shall return the initial value of *destination. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_047: [ interlocked_or shall call InterlockedOr from windows.h. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_048: [ interlocked_or shall return the initial value of *destination. ] */
|
||||
|
||||
return InterlockedOr((volatile LONG*)destination, value);
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, int16_t, interlocked_or_16, volatile int16_t*, destination, int16_t, value)
|
||||
{
|
||||
/*Codes_SRS_INTERLOCKED_43_025 [ interlocked_or_16 shall perform an atomic bitwise OR operation on the 16-bit integers *destination and value and store the result in destination.]*/
|
||||
/*Codes_SRS_INTERLOCKED_43_056: [ interlocked_or_16 shall return the initial value of *destination. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_049: [ interlocked_or_16 shall call InterlockedOr16 from windows.h. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_050: [ interlocked_or_16 shall return the initial value of *destination. ]*/
|
||||
/* Codes_SRS_INTERLOCKED_43_025 [ interlocked_or_16 shall perform an atomic bitwise OR operation on the 16-bit integers *destination and value and store the result in destination.] */
|
||||
/* Codes_SRS_INTERLOCKED_43_056: [ interlocked_or_16 shall return the initial value of *destination. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_049: [ interlocked_or_16 shall call InterlockedOr16 from windows.h. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_050: [ interlocked_or_16 shall return the initial value of *destination. ] */
|
||||
|
||||
return InterlockedOr16((volatile SHORT*)destination, value);
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, int64_t, interlocked_or_64, volatile int64_t*, destination, int64_t, value)
|
||||
{
|
||||
/*Codes_SRS_INTERLOCKED_43_026 [ interlocked_or_64 shall perform an atomic bitwise OR operation on the 64-bit integers *destination and value and store the result in destination.]*/
|
||||
/*Codes_SRS_INTERLOCKED_43_057: [ interlocked_or_64 shall return the initial value of *destination. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_051: [ interlocked_or_64 shall call InterlockedOr64 from windows.h. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_052: [ interlocked_or_64 shall return the initial value of *destination. ]*/
|
||||
/* Codes_SRS_INTERLOCKED_43_026 [ interlocked_or_64 shall perform an atomic bitwise OR operation on the 64-bit integers *destination and value and store the result in destination.] */
|
||||
/* Codes_SRS_INTERLOCKED_43_057: [ interlocked_or_64 shall return the initial value of *destination. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_051: [ interlocked_or_64 shall call InterlockedOr64 from windows.h. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_052: [ interlocked_or_64 shall return the initial value of *destination. ] */
|
||||
|
||||
return InterlockedOr64((volatile LONG64*)destination, value);
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, int8_t, interlocked_or_8, volatile int8_t*, destination, int8_t, value)
|
||||
{
|
||||
/*Codes_SRS_INTERLOCKED_43_027 [ interlocked_or_8 shall perform an atomic bitwise OR operation on the 8-bit integers *destination and value and store the result in destination.]*/
|
||||
/*Codes_SRS_INTERLOCKED_43_058: [ interlocked_or_8 shall return the initial value of *destination. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_053: [ interlocked_or_8 shall call InterlockedOr8 from windows.h. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_054: [ interlocked_or_8 shall return the initial value of *destination. ]*/
|
||||
/* Codes_SRS_INTERLOCKED_43_027 [ interlocked_or_8 shall perform an atomic bitwise OR operation on the 8-bit integers *destination and value and store the result in destination.] */
|
||||
/* Codes_SRS_INTERLOCKED_43_058: [ interlocked_or_8 shall return the initial value of *destination. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_053: [ interlocked_or_8 shall call InterlockedOr8 from windows.h. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_054: [ interlocked_or_8 shall return the initial value of *destination. ] */
|
||||
|
||||
return InterlockedOr8((volatile char*)destination, value);
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, int32_t, interlocked_xor, volatile int32_t*, destination, int32_t, value)
|
||||
{
|
||||
/*Codes_SRS_INTERLOCKED_43_028 [ interlocked_xor shall perform an atomic bitwise XOR operation on the 32-bit integers *destination and value and store the result in destination.]*/
|
||||
/*Codes_SRS_INTERLOCKED_43_059: [ interlocked_xor shall return the initial value of *destination. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_055: [ interlocked_xor shall call InterlockedXor from windows.h. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_056: [ interlocked_xor shall return the initial value of *destination. ]*/
|
||||
/* Codes_SRS_INTERLOCKED_43_028 [ interlocked_xor shall perform an atomic bitwise XOR operation on the 32-bit integers *destination and value and store the result in destination.] */
|
||||
/* Codes_SRS_INTERLOCKED_43_059: [ interlocked_xor shall return the initial value of *destination. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_055: [ interlocked_xor shall call InterlockedXor from windows.h. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_056: [ interlocked_xor shall return the initial value of *destination. ] */
|
||||
|
||||
return InterlockedXor((volatile LONG*)destination, value);
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, int16_t, interlocked_xor_16, volatile int16_t*, destination, int16_t, value)
|
||||
{
|
||||
/*Codes_SRS_INTERLOCKED_43_029 [ interlocked_xor_16 shall perform an atomic bitwise XOR operation on the 16-bit integers *destination and value and store the result in destination.]*/
|
||||
/*Codes_SRS_INTERLOCKED_43_060: [ interlocked_xor_16 shall return the initial value of *destination. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_057: [ interlocked_xor_16 shall call InterlockedXor16 from windows.h. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_058: [ interlocked_xor_16 shall return the initial value of *destination. ]*/
|
||||
/* Codes_SRS_INTERLOCKED_43_029 [ interlocked_xor_16 shall perform an atomic bitwise XOR operation on the 16-bit integers *destination and value and store the result in destination.] */
|
||||
/* Codes_SRS_INTERLOCKED_43_060: [ interlocked_xor_16 shall return the initial value of *destination. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_057: [ interlocked_xor_16 shall call InterlockedXor16 from windows.h. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_058: [ interlocked_xor_16 shall return the initial value of *destination. ] */
|
||||
|
||||
return InterlockedXor16((volatile SHORT*)destination, value);
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, int64_t, interlocked_xor_64, volatile int64_t*, destination, int64_t, value)
|
||||
{
|
||||
/*Codes_SRS_INTERLOCKED_43_030 [ interlocked_xor_64 shall perform an atomic bitwise XOR operation on the 64-bit integers *destination and value and store the result in destination.]*/
|
||||
/*Codes_SRS_INTERLOCKED_43_061: [ interlocked_xor_64 shall return the initial value of *destination. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_059: [ interlocked_xor_64 shall call InterlockedXor64 from windows.h. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_060: [ interlocked_xor_64 shall return the initial value of *destination. ]*/
|
||||
/* Codes_SRS_INTERLOCKED_43_030 [ interlocked_xor_64 shall perform an atomic bitwise XOR operation on the 64-bit integers *destination and value and store the result in destination.] */
|
||||
/* Codes_SRS_INTERLOCKED_43_061: [ interlocked_xor_64 shall return the initial value of *destination. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_059: [ interlocked_xor_64 shall call InterlockedXor64 from windows.h. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_060: [ interlocked_xor_64 shall return the initial value of *destination. ] */
|
||||
|
||||
return InterlockedXor64((volatile LONG64*)destination, value);
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, int8_t, interlocked_xor_8, volatile int8_t*, destination, int8_t, value)
|
||||
{
|
||||
/*Codes_SRS_INTERLOCKED_43_031 [ interlocked_xor_8 shall perform an atomic bitwise XOR operation on the 8-bit integers *destination and value and store the result in destination.]*/
|
||||
/*Codes_SRS_INTERLOCKED_43_062: [ interlocked_xor_8 shall return the initial value of *destination. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_061: [ interlocked_xor_8 shall call InterlockedXor8 from windows.h. ]*/
|
||||
/*Codes_SRS_INTERLOCKED_WIN32_43_062: [ interlocked_xor_8 shall return the initial value of *destination. ]*/
|
||||
/* Codes_SRS_INTERLOCKED_43_031 [ interlocked_xor_8 shall perform an atomic bitwise XOR operation on the 8-bit integers *destination and value and store the result in destination.] */
|
||||
/* Codes_SRS_INTERLOCKED_43_062: [ interlocked_xor_8 shall return the initial value of *destination. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_061: [ interlocked_xor_8 shall call InterlockedXor8 from windows.h. ] */
|
||||
/* Codes_SRS_INTERLOCKED_WIN32_43_062: [ interlocked_xor_8 shall return the initial value of *destination. ] */
|
||||
|
||||
return InterlockedXor8((volatile char*)destination, value);
|
||||
}
|
||||
|
|
|
@ -19,36 +19,78 @@ MU_DEFINE_ENUM_STRINGS(WAIT_ON_ADDRESS_RESULT, WAIT_ON_ADDRESS_RESULT_VALUES)
|
|||
IMPLEMENT_MOCKABLE_FUNCTION(, WAIT_ON_ADDRESS_RESULT, wait_on_address, volatile_atomic int32_t*, address, int32_t, compare_value, uint32_t, timeout_ms)
|
||||
{
|
||||
WAIT_ON_ADDRESS_RESULT result;
|
||||
/*Codes_SRS_SYNC_WIN32_43_001: [ wait_on_address shall call WaitOnAddress from windows.h with address as Address, a pointer to the value compare_value as CompareAddress, 4 as AddressSize and timeout_ms as dwMilliseconds. ]*/
|
||||
/* Codes_SRS_SYNC_WIN32_43_001: [ wait_on_address shall call WaitOnAddress to wait on the value at 32-bit address to be different than compare_value for timeout_ms milliseconds. ] */
|
||||
if (WaitOnAddress(address, &compare_value, sizeof(int32_t), timeout_ms) != TRUE)
|
||||
{
|
||||
if (GetLastError() == ERROR_TIMEOUT)
|
||||
{
|
||||
/* Codes_SRS_SYNC_WIN32_24_001: [ If WaitOnAddress fails due to timeout, wait_on_address shall fail and return WAIT_ON_ADDRESS_TIMEOUT. ]*/
|
||||
/* Codes_SRS_SYNC_WIN32_24_001: [ If WaitOnAddress fails due to timeout, wait_on_address shall fail and return WAIT_ON_ADDRESS_TIMEOUT. ] */
|
||||
result = WAIT_ON_ADDRESS_TIMEOUT;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogLastError("failure in WaitOnAddress(address=%p, &compare_value=%p, address_size=%zu, timeout_ms=%" PRIu32 ")",
|
||||
address, &compare_value, sizeof(int32_t), timeout_ms);
|
||||
/* Codes_SRS_SYNC_WIN32_24_002: [ If WaitOnAddress fails due to any other reason, wait_on_address shall fail and return WAIT_ON_ADDRESS_ERROR. ]*/
|
||||
/* Codes_SRS_SYNC_WIN32_24_002: [ If WaitOnAddress fails due to any other reason, wait_on_address shall fail and return WAIT_ON_ADDRESS_ERROR. ] */
|
||||
result = WAIT_ON_ADDRESS_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Codes_SRS_SYNC_WIN32_24_003: [ If WaitOnAddress succeeds, wait_on_address shall return WAIT_ON_ADDRESS_OK. ]*/
|
||||
/* Codes_SRS_SYNC_WIN32_24_003: [ If WaitOnAddress succeeds, wait_on_address shall return WAIT_ON_ADDRESS_OK. ] */
|
||||
result = WAIT_ON_ADDRESS_OK;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, WAIT_ON_ADDRESS_RESULT, wait_on_address_64, volatile_atomic int64_t*, address, int64_t, compare_value, uint32_t, timeout_ms)
|
||||
{
|
||||
WAIT_ON_ADDRESS_RESULT result;
|
||||
/* Codes_SRS_SYNC_WIN32_05_001: [ wait_on_address_64 shall call WaitOnAddress to wait on the value at 64-bit address to be different than compare_value for timeout_ms milliseconds. ] */
|
||||
if (WaitOnAddress(address, &compare_value, sizeof(int64_t), timeout_ms) != TRUE)
|
||||
{
|
||||
if (GetLastError() == ERROR_TIMEOUT)
|
||||
{
|
||||
/* Codes_SRS_SYNC_WIN32_05_002: [ If WaitOnAddress fails due to timeout, wait_on_address_64 shall fail and return WAIT_ON_ADDRESS_TIMEOUT. ] */
|
||||
result = WAIT_ON_ADDRESS_TIMEOUT;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogLastError("failure in WaitOnAddress(address=%p, &compare_value=%p, address_size=%zu, timeout_ms=%" PRIu32 ")",
|
||||
address, &compare_value, sizeof(int64_t), timeout_ms);
|
||||
/* Codes_SRS_SYNC_WIN32_05_003: [ If WaitOnAddress fails due to any other reason, wait_on_address_64 shall fail and return WAIT_ON_ADDRESS_ERROR. ] */
|
||||
result = WAIT_ON_ADDRESS_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Codes_SRS_SYNC_WIN32_05_004: [ If WaitOnAddress succeeds, wait_on_address_64 shall return WAIT_ON_ADDRESS_OK. ] */
|
||||
result = WAIT_ON_ADDRESS_OK;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, void, wake_by_address_all, volatile_atomic int32_t*, address)
|
||||
{
|
||||
/*Codes_SRS_SYNC_WIN32_43_003: [ wake_by_address_all shall call WakeByAddressAll from windows.h with address as Address. ]*/
|
||||
/* Codes_SRS_SYNC_WIN32_43_003: [ wake_by_address_all shall call WakeByAddressAll to notify all listeners waiting on the 32-bit address. ] */
|
||||
WakeByAddressAll((PVOID)address);
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, void, wake_by_address_all_64, volatile_atomic int64_t*, address)
|
||||
{
|
||||
/* Codes_SRS_SYNC_WIN32_05_005: [ wake_by_address_all_64 shall call WakeByAddressAll to notify all listeners waiting on the 64-bit address. ] */
|
||||
WakeByAddressAll((PVOID)address);
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, void, wake_by_address_single, volatile_atomic int32_t*, address)
|
||||
{
|
||||
/*Codes_SRS_SYNC_WIN32_43_004: [ wake_by_address_single shall call WakeByAddressSingle from windows.h with address as Address. ]*/
|
||||
/* Codes_SRS_SYNC_WIN32_43_004: [ wake_by_address_single shall call WakeByAddressSingle to notify a single listeners waiting on the 32-bit address. ] */
|
||||
WakeByAddressSingle((PVOID)address);
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, void, wake_by_address_single_64, volatile_atomic int64_t*, address)
|
||||
{
|
||||
/* Codes_SRS_SYNC_WIN32_05_006: [ wake_by_address_single_64 shall call WakeByAddressSingle to notify a single listeners waiting on the 64-bit address. ] */
|
||||
WakeByAddressSingle((PVOID)address);
|
||||
}
|
||||
|
||||
|
|
|
@ -60,12 +60,12 @@ TEST_FUNCTION_CLEANUP(cleans)
|
|||
{
|
||||
}
|
||||
|
||||
/*Tests_SRS_SYNC_WIN32_43_001: [ wait_on_address shall call WaitOnAddress from windows.h with address as Address, a pointer to the value compare_value as CompareAddress, 4 as AddressSize and timeout_ms as dwMilliseconds. ]*/
|
||||
/*Tests_SRS_SYNC_WIN32_24_003: [ If WaitOnAddress succeeds, wait_on_address shall return WAIT_ON_ADDRESS_OK. ]*/
|
||||
/* Tests_SRS_SYNC_WIN32_43_001: [ wait_on_address shall call WaitOnAddress to wait on the value at 32-bit address to be different than compare_value for timeout_ms milliseconds. ] */
|
||||
/* Tests_SRS_SYNC_WIN32_24_003: [ If WaitOnAddress succeeds, wait_on_address shall return WAIT_ON_ADDRESS_OK. ] */
|
||||
TEST_FUNCTION(wait_on_address_calls_WaitOnAddress_successfully)
|
||||
{
|
||||
///arrange
|
||||
volatile int32_t var;
|
||||
volatile int32_t var = 0;
|
||||
int32_t expected_val = INT32_MAX;
|
||||
(void)InterlockedExchange((volatile LONG*)&var, INT32_MAX);
|
||||
uint32_t timeout = 1000;
|
||||
|
@ -81,8 +81,29 @@ TEST_FUNCTION(wait_on_address_calls_WaitOnAddress_successfully)
|
|||
ASSERT_ARE_EQUAL(WAIT_ON_ADDRESS_RESULT, WAIT_ON_ADDRESS_OK, return_val, "wait_on_address should have returned ok");
|
||||
}
|
||||
|
||||
/*Tests_SRS_SYNC_WIN32_43_001: [ wait_on_address shall call WaitOnAddress from windows.h with address as Address, a pointer to the value compare_value as CompareAddress, 4 as AddressSize and timeout_ms as dwMilliseconds. ]*/
|
||||
/*Tests_SRS_SYNC_WIN32_24_002: [ If WaitOnAddress fails due to any other reason, wait_on_address shall fail and return WAIT_ON_ADDRESS_ERROR. ]*/
|
||||
/* Tests_SRS_SYNC_WIN32_05_001: [ wait_on_address_64 shall call WaitOnAddress to wait on the value at 64-bit address to be different than compare_value for timeout_ms milliseconds. ] */
|
||||
/* Tests_SRS_SYNC_WIN32_05_004: [ If WaitOnAddress succeeds, wait_on_address_64 shall return WAIT_ON_ADDRESS_OK. ] */
|
||||
TEST_FUNCTION(wait_on_address_64_calls_WaitOnAddress_successfully)
|
||||
{
|
||||
///arrange
|
||||
volatile int64_t var;
|
||||
int64_t expected_val = INT64_MAX;
|
||||
(void)InterlockedExchange64((volatile LONG64*)&var, INT64_MAX);
|
||||
uint32_t timeout = 1000;
|
||||
STRICT_EXPECTED_CALL(mock_WaitOnAddress((volatile VOID*)&var, IGNORED_ARG, (SIZE_T)8, (DWORD)timeout))
|
||||
.ValidateArgumentBuffer(2, &expected_val, sizeof(expected_val))
|
||||
.SetReturn(true);
|
||||
|
||||
///act
|
||||
WAIT_ON_ADDRESS_RESULT return_val = wait_on_address_64(&var, INT64_MAX, timeout);
|
||||
|
||||
///assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls(), "Actual calls differ from expected calls");
|
||||
ASSERT_ARE_EQUAL(WAIT_ON_ADDRESS_RESULT, WAIT_ON_ADDRESS_OK, return_val, "wait_on_address_64 should have returned ok");
|
||||
}
|
||||
|
||||
/* Tests_SRS_SYNC_WIN32_43_001: [ wait_on_address shall call WaitOnAddress to wait on the value at 32-bit address to be different than compare_value for timeout_ms milliseconds. ] */
|
||||
/* Tests_SRS_SYNC_WIN32_24_002: [ If WaitOnAddress fails due to any other reason, wait_on_address shall fail and return WAIT_ON_ADDRESS_ERROR. ] */
|
||||
TEST_FUNCTION(wait_on_address_calls_fails_when_WaitOnAddress_fails_due_to_timeout)
|
||||
{
|
||||
///arrange
|
||||
|
@ -103,8 +124,30 @@ TEST_FUNCTION(wait_on_address_calls_fails_when_WaitOnAddress_fails_due_to_timeou
|
|||
ASSERT_ARE_EQUAL(WAIT_ON_ADDRESS_RESULT, WAIT_ON_ADDRESS_ERROR, return_val, "wait_on_address should have returned error");
|
||||
}
|
||||
|
||||
/*Tests_SRS_SYNC_WIN32_43_001: [ wait_on_address shall call WaitOnAddress from windows.h with address as Address, a pointer to the value compare_value as CompareAddress, 4 as AddressSize and timeout_ms as dwMilliseconds. ]*/
|
||||
/*Tests_SRS_SYNC_WIN32_24_001: [ If WaitOnAddress fails due to timeout, wait_on_address shall fail and return WAIT_ON_ADDRESS_TIMEOUT. ]*/
|
||||
/* Tests_SRS_SYNC_WIN32_05_001: [ wait_on_address_64 shall call WaitOnAddress to wait on the value at 64-bit address to be different than compare_value for timeout_ms milliseconds. ] */
|
||||
/* Tests_SRS_SYNC_WIN32_05_002: [ If WaitOnAddress fails due to timeout, wait_on_address_64 shall fail and return WAIT_ON_ADDRESS_TIMEOUT. ] */
|
||||
TEST_FUNCTION(wait_on_address_64_calls_fails_when_WaitOnAddress_fails_due_to_timeout)
|
||||
{
|
||||
///arrange
|
||||
volatile int64_t var;
|
||||
int64_t expected_val = INT64_MAX;
|
||||
(void)InterlockedExchange64((volatile LONG64*)&var, INT64_MAX);
|
||||
uint32_t timeout = 1000;
|
||||
STRICT_EXPECTED_CALL(mock_WaitOnAddress((volatile VOID*)&var, IGNORED_ARG, (SIZE_T)8, (DWORD)timeout))
|
||||
.ValidateArgumentBuffer(2, &expected_val, sizeof(expected_val))
|
||||
.SetReturn(false);
|
||||
STRICT_EXPECTED_CALL(mock_GetLastError());
|
||||
|
||||
///act
|
||||
WAIT_ON_ADDRESS_RESULT return_val = wait_on_address_64(&var, INT64_MAX, timeout);
|
||||
|
||||
///assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls(), "Actual calls differ from expected calls");
|
||||
ASSERT_ARE_EQUAL(WAIT_ON_ADDRESS_RESULT, WAIT_ON_ADDRESS_ERROR, return_val, "wait_on_address_64 should have returned error");
|
||||
}
|
||||
|
||||
/* Tests_SRS_SYNC_WIN32_43_001: [ wait_on_address shall call WaitOnAddress to wait on the value at 32-bit address to be different than compare_value for timeout_ms milliseconds. ] */
|
||||
/* Tests_SRS_SYNC_WIN32_24_001: [ If WaitOnAddress fails due to timeout, wait_on_address shall fail and return WAIT_ON_ADDRESS_TIMEOUT. ] */
|
||||
TEST_FUNCTION(wait_on_address_calls_WaitOnAddress_unsuccessfully)
|
||||
{
|
||||
///arrange
|
||||
|
@ -125,7 +168,29 @@ TEST_FUNCTION(wait_on_address_calls_WaitOnAddress_unsuccessfully)
|
|||
ASSERT_ARE_EQUAL(WAIT_ON_ADDRESS_RESULT, WAIT_ON_ADDRESS_TIMEOUT, return_val, "wait_on_address should have returned timeout");
|
||||
}
|
||||
|
||||
/*Tests_SRS_SYNC_WIN32_43_003: [ wake_by_address_all shall call WakeByAddressAll from windows.h with address as Address. ]*/
|
||||
/* Tests_SRS_SYNC_WIN32_05_001: [ wait_on_address_64 shall call WaitOnAddress to wait on the value at 64-bit address to be different than compare_value for timeout_ms milliseconds. ] */
|
||||
/* Tests_SRS_SYNC_WIN32_05_003: [ If WaitOnAddress fails due to any other reason, wait_on_address_64 shall fail and return WAIT_ON_ADDRESS_ERROR. ] */
|
||||
TEST_FUNCTION(wait_on_address_64_calls_WaitOnAddress_unsuccessfully)
|
||||
{
|
||||
///arrange
|
||||
volatile int64_t var = 0;
|
||||
int64_t expected_val = INT64_MAX;
|
||||
(void)InterlockedExchange64((volatile LONG64*)&var, INT64_MAX);
|
||||
uint32_t timeout = 1000;
|
||||
STRICT_EXPECTED_CALL(mock_WaitOnAddress((volatile VOID*)&var, IGNORED_ARG, (SIZE_T)8, (DWORD)timeout))
|
||||
.ValidateArgumentBuffer(2, &expected_val, sizeof(expected_val))
|
||||
.SetReturn(false);
|
||||
STRICT_EXPECTED_CALL(mock_GetLastError()).SetReturn(ERROR_TIMEOUT);
|
||||
|
||||
///act
|
||||
WAIT_ON_ADDRESS_RESULT return_val = wait_on_address_64(&var, INT64_MAX, timeout);
|
||||
|
||||
///assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls(), "Actual calls differ from expected calls");
|
||||
ASSERT_ARE_EQUAL(WAIT_ON_ADDRESS_RESULT, WAIT_ON_ADDRESS_TIMEOUT, return_val, "wait_on_address_64 should have returned timeout");
|
||||
}
|
||||
|
||||
/* Tests_SRS_SYNC_WIN32_43_003: [ wake_by_address_all shall call WakeByAddressAll to notify all listeners waiting on the 32-bit address. ] */
|
||||
TEST_FUNCTION(wake_by_address_all_calls_WakeByAddressAll)
|
||||
{
|
||||
///arrange
|
||||
|
@ -140,7 +205,22 @@ TEST_FUNCTION(wake_by_address_all_calls_WakeByAddressAll)
|
|||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls(), "Actual calls differ from expected calls");
|
||||
}
|
||||
|
||||
/*Tests_SRS_SYNC_WIN32_43_004: [ wake_by_address_single shall call WakeByAddressSingle from windows.h with address as Address. ]*/
|
||||
/* Tests_SRS_SYNC_WIN32_05_005: [ wake_by_address_all_64 shall call WakeByAddressAll to notify all listeners waiting on the 64-bit address. ] */
|
||||
TEST_FUNCTION(wake_by_address_all_64_calls_WakeByAddressAll)
|
||||
{
|
||||
///arrange
|
||||
volatile int64_t var;
|
||||
int64_t val = INT64_MAX;
|
||||
(void)InterlockedExchange64((volatile LONG64*)&var, val);
|
||||
STRICT_EXPECTED_CALL(mock_WakeByAddressAll((PVOID)&var));
|
||||
///act
|
||||
wake_by_address_all_64(&var);
|
||||
|
||||
///assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls(), "Actual calls differ from expected calls");
|
||||
}
|
||||
|
||||
/* Tests_SRS_SYNC_WIN32_43_004: [ wake_by_address_single shall call WakeByAddressSingle to notify a single listeners waiting on the 32-bit address. ] */
|
||||
TEST_FUNCTION(wake_by_address_single_calls_WakeByAddressSingle)
|
||||
{
|
||||
///arrange
|
||||
|
@ -154,4 +234,19 @@ TEST_FUNCTION(wake_by_address_single_calls_WakeByAddressSingle)
|
|||
///assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls(), "Actual calls differ from expected calls");
|
||||
}
|
||||
|
||||
/* Tests_SRS_SYNC_WIN32_05_006: [ wake_by_address_single_64 shall call WakeByAddressSingle to notify a single listeners waiting on the 64-bit address. ] */
|
||||
TEST_FUNCTION(wake_by_address_single_64_calls_WakeByAddressSingle)
|
||||
{
|
||||
///arrange
|
||||
volatile int64_t var;
|
||||
int64_t val = INT32_MAX;
|
||||
(void)InterlockedExchange64((volatile LONG64*)&var, val);
|
||||
STRICT_EXPECTED_CALL(mock_WakeByAddressSingle((PVOID)&var));
|
||||
///act
|
||||
wake_by_address_single_64(&var);
|
||||
|
||||
///assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls(), "Actual calls differ from expected calls");
|
||||
}
|
||||
END_TEST_SUITE(TEST_SUITE_NAME_FROM_CMAKE)
|
||||
|
|
|
@ -59,92 +59,84 @@ then `InterlockedHL_Add64WithCeiling` fails and returns `INTERLOCKED_HL_ERROR`.
|
|||
### InterlockedHL_WaitForValue
|
||||
|
||||
```c
|
||||
MOCKABLE_FUNCTION_WITH_RETURNS(, INTERLOCKED_HL_RESULT, InterlockedHL_WaitForValue, int32_t volatile_atomic*, address, int32_t, value, uint32_t, milliseconds)(INTERLOCKED_HL_OK, INTERLOCKED_HL_ERROR);
|
||||
MOCKABLE_FUNCTION_WITH_RETURNS(, INTERLOCKED_HL_RESULT, InterlockedHL_WaitForValue, int32_t volatile_atomic*, address_to_check, int32_t, value_to_wait, uint32_t, timeout_ms)(INTERLOCKED_HL_OK, INTERLOCKED_HL_ERROR);
|
||||
```
|
||||
|
||||
`InterlockedHL_WaitForValue` waits for the value at a given address to be equal to a target value.
|
||||
`InterlockedHL_WaitForValue` waits for the value at the given `address_to_check` to be equal to the target `value_to_wait`.
|
||||
|
||||
**SRS_INTERLOCKED_HL_01_002: [** If `address` is `NULL`, `InterlockedHL_WaitForValue` shall fail and return `INTERLOCKED_HL_ERROR`. **]**
|
||||
**SRS_INTERLOCKED_HL_01_002: [** If `address_to_check` is `NULL`, `InterlockedHL_WaitForValue` shall fail and return `INTERLOCKED_HL_ERROR`. **]**
|
||||
|
||||
**SRS_INTERLOCKED_HL_01_003: [** If the value at `address` is equal to `value`, `InterlockedHL_WaitForValue` shall return `INTERLOCKED_HL_OK`. **]**
|
||||
**SRS_INTERLOCKED_HL_01_003: [** If the value at `address_to_check` is equal to `value_to_wait`, `InterlockedHL_WaitForValue` shall return `INTERLOCKED_HL_OK`. **]**
|
||||
|
||||
**SRS_INTERLOCKED_HL_01_004: [** If the value at `address` is not equal to `value`, `InterlockedHL_WaitForValue` shall wait until the value at `address` changes in order to compare it again to `value` by using `wait_on_address`. **]**
|
||||
**SRS_INTERLOCKED_HL_01_004: [** If the value at `address_to_check` is not equal to `value_to_wait`, `InterlockedHL_WaitForValue` shall wait until the value at `address_to_check` changes using `wait_on_address`. **]**
|
||||
|
||||
**SRS_INTERLOCKED_HL_01_005: [** When waiting for the value at address to change, the `milliseconds` argument value shall be used as timeout. **]**
|
||||
**SRS_INTERLOCKED_HL_01_007: [** When `wait_on_address` succeeds, `InterlockedHL_WaitForValue` shall again compare the value at `address_to_check` with `value_to_wait`. **]**
|
||||
|
||||
**SRS_INTERLOCKED_HL_01_007: [** When `wait_on_address` succeeds, the value at address shall be compared to the target value passed in `value` by using `interlocked_add`. **]**
|
||||
|
||||
**SRS_INTERLOCKED_HL_01_008: [** If the value at `address` does not match, `InterlockedHL_WaitForValue` shall issue another call to `wait_on_address`. **]**
|
||||
|
||||
**SRS_INTERLOCKED_HL_11_001: [** If `wait_on_address` timesout, `InterlockedHL_WaitForValue` shall fail and return `INTERLOCKED_HL_TIMEOUT`. **]**
|
||||
**SRS_INTERLOCKED_HL_11_001: [** If `wait_on_address` hits the timeout specified in `timeout_ms`, `InterlockedHL_WaitForValue` shall fail and return `INTERLOCKED_HL_TIMEOUT`. **]**
|
||||
|
||||
**SRS_INTERLOCKED_HL_01_006: [** If `wait_on_address` fails, `InterlockedHL_WaitForValue` shall fail and return `INTERLOCKED_HL_ERROR`. **]**
|
||||
|
||||
### InterlockedHL_WaitForValue64
|
||||
|
||||
```c
|
||||
MOCKABLE_FUNCTION_WITH_RETURNS(, INTERLOCKED_HL_RESULT, InterlockedHL_WaitForValue64, int64_t volatile_atomic*, address, int64_t, value, uint32_t, milliseconds)(INTERLOCKED_HL_OK, INTERLOCKED_HL_ERROR);
|
||||
MOCKABLE_FUNCTION_WITH_RETURNS(, INTERLOCKED_HL_RESULT, InterlockedHL_WaitForValue64, int64_t volatile_atomic*, address_to_check, int64_t, value_to_wait, uint32_t, timeout_ms)(INTERLOCKED_HL_OK, INTERLOCKED_HL_ERROR);
|
||||
```
|
||||
|
||||
`InterlockedHL_WaitForValue64` waits for the value at a given address to be equal to a target value.
|
||||
[Note: address_to_check refers to address, value_to_wait refers to value, and timeout_ms refers to milliseconds]
|
||||
`InterlockedHL_WaitForValue64` waits for the value at the given `address_to_check` to be equal to the target `value_to_wait`.
|
||||
|
||||
**S_R_S_INTERLOCKED_HL_05_001: [** If `address_to_check` is `NULL`, `InterlockedHL_WaitForValue64` shall fail and return `INTERLOCKED_HL_ERROR`. **]**
|
||||
**SRS_INTERLOCKED_HL_05_001: [** If `address_to_check` is `NULL`, `InterlockedHL_WaitForValue64` shall fail and return `INTERLOCKED_HL_ERROR`. **]**
|
||||
|
||||
**S_R_S_INTERLOCKED_HL_05_002: [** If the value at `address_to_check` is equal to `value_to_wait`, `InterlockedHL_WaitForValue64` shall return `INTERLOCKED_HL_OK`. **]**
|
||||
**SRS_INTERLOCKED_HL_05_002: [** If the value at `address_to_check` is equal to `value_to_wait`, `InterlockedHL_WaitForValue64` shall return `INTERLOCKED_HL_OK`. **]**
|
||||
|
||||
**S_R_S_INTERLOCKED_HL_05_003: [** If the value at `address_to_check` is not equal to `value_to_wait`, `InterlockedHL_WaitForValue64` shall wait until the value at `address_to_check` changes using `wait_on_address_64`. **]**
|
||||
**SRS_INTERLOCKED_HL_05_003: [** If the value at `address_to_check` is not equal to `value_to_wait`, `InterlockedHL_WaitForValue64` shall wait until the value at `address_to_check` changes using `wait_on_address_64`. **]**
|
||||
|
||||
**S_R_S_INTERLOCKED_HL_05_004: [** When `wait_on_address_64` succeeds, `InterlockedHL_WaitForValue64` shall again compare the value at `address_to_check` with `value_to_wait`. **]**
|
||||
**SRS_INTERLOCKED_HL_05_004: [** When `wait_on_address_64` succeeds, `InterlockedHL_WaitForValue64` shall again compare the value at `address_to_check` with `value_to_wait`. **]**
|
||||
|
||||
**S_R_S_INTERLOCKED_HL_05_005: [** If `wait_on_address_64` hits the timeout specified in timeout_ms, `InterlockedHL_WaitForValue64` shall fail and return `INTERLOCKED_HL_TIMEOUT`. **]**
|
||||
**SRS_INTERLOCKED_HL_05_005: [** If `wait_on_address_64` hits the timeout specified in timeout_ms, `InterlockedHL_WaitForValue64` shall fail and return `INTERLOCKED_HL_TIMEOUT`. **]**
|
||||
|
||||
**SRS_INTERLOCKED_HL_05_006: [** If `wait_on_address_64` fails, `InterlockedHL_WaitForValue64` shall fail and return `INTERLOCKED_HL_ERROR`. **]**
|
||||
|
||||
**S_R_S_INTERLOCKED_HL_05_006: [** If `wait_on_address_64` fails, `InterlockedHL_WaitForValue64` shall fail and return `INTERLOCKED_HL_ERROR`. **]**
|
||||
|
||||
### InterlockedHL_WaitForNotValue
|
||||
|
||||
```c
|
||||
MOCKABLE_FUNCTION_WITH_RETURNS(, INTERLOCKED_HL_RESULT, InterlockedHL_WaitForNotValue, int32_t volatile_atomic*, address, int32_t, value, uint32_t, milliseconds)(INTERLOCKED_HL_OK, INTERLOCKED_HL_ERROR);
|
||||
MOCKABLE_FUNCTION_WITH_RETURNS(, INTERLOCKED_HL_RESULT, InterlockedHL_WaitForNotValue, int32_t volatile_atomic*, address_to_check, int32_t, value_to_wait, uint32_t, timeout_ms)(INTERLOCKED_HL_OK, INTERLOCKED_HL_ERROR);
|
||||
```
|
||||
|
||||
`InterlockedHL_WaitForNotValue` waits for the value at a given address to not be equal to a target value.
|
||||
`InterlockedHL_WaitForNotValue` waits for the value at the given `address_to_check` to be not equal to the target `value_to_wait`.
|
||||
|
||||
**SRS_INTERLOCKED_HL_42_001: [** If `address` is `NULL`, `InterlockedHL_WaitForNotValue` shall fail and return `INTERLOCKED_HL_ERROR`. **]**
|
||||
**SRS_INTERLOCKED_HL_42_001: [** If `address_to_check` is `NULL`, `InterlockedHL_WaitForNotValue` shall fail and return `INTERLOCKED_HL_ERROR`. **]**
|
||||
|
||||
**SRS_INTERLOCKED_HL_42_002: [** If the value at `address` is not equal to `value`, `InterlockedHL_WaitForNotValue` shall return `INTERLOCKED_HL_OK`. **]**
|
||||
**SRS_INTERLOCKED_HL_42_002: [** If the value at `address_to_check` is not equal to `value_to_wait`, `InterlockedHL_WaitForNotValue` shall return `INTERLOCKED_HL_OK`. **]**
|
||||
|
||||
**SRS_INTERLOCKED_HL_42_003: [** If the value at `address` is equal to `value`, `InterlockedHL_WaitForNotValue` shall wait until the value at `address` changes in order to compare it again to `value` by using `wait_on_address`. **]**
|
||||
**SRS_INTERLOCKED_HL_42_003: [** If the value at `address_to_check` is equal to `value_to_wait`, `InterlockedHL_WaitForNotValue` shall wait until the value at `address_to_check` changes by using `wait_on_address`. **]**
|
||||
|
||||
**SRS_INTERLOCKED_HL_42_004: [** When waiting for the value at address to change, the `milliseconds` argument value shall be used as timeout. **]**
|
||||
**SRS_INTERLOCKED_HL_42_005: [** When `wait_on_address` succeeds, `InterlockedHL_WaitForNotValue64` shall again compare the value at `address_to_check` with `value_to_wait`. **]**
|
||||
|
||||
**SRS_INTERLOCKED_HL_42_005: [** When `wait_on_address` succeeds, the value at address shall be compared to the target value passed in `value` by using `interlocked_add`. **]**
|
||||
|
||||
**SRS_INTERLOCKED_HL_42_006: [** If the value at `address` matches, `InterlockedHL_WaitForNotValue` shall issue another call to `wait_on_address`. **]**
|
||||
|
||||
**SRS_INTERLOCKED_HL_11_002: [** If `wait_on_address` timesout, `InterlockedHL_WaitForNotValue` shall fail and return `INTERLOCKED_HL_TIMEOUT`. **]**
|
||||
**SRS_INTERLOCKED_HL_11_002: [** If `wait_on_address` hits the timeout specified in timeout_ms, `InterlockedHL_WaitForNotValue` shall fail and return `INTERLOCKED_HL_TIMEOUT`. **]**
|
||||
|
||||
**SRS_INTERLOCKED_HL_42_007: [** If `wait_on_address` fails, `InterlockedHL_WaitForNotValue` shall fail and return `INTERLOCKED_HL_ERROR`. **]**
|
||||
|
||||
### InterlockedHL_WaitForNotValue64
|
||||
|
||||
```c
|
||||
MOCKABLE_FUNCTION_WITH_RETURNS(, INTERLOCKED_HL_RESULT, InterlockedHL_WaitForNotValue64, int64_t volatile_atomic*, address, int64_t, value, uint32_t, milliseconds)(INTERLOCKED_HL_OK, INTERLOCKED_HL_ERROR);
|
||||
MOCKABLE_FUNCTION_WITH_RETURNS(, INTERLOCKED_HL_RESULT, InterlockedHL_WaitForNotValue64, int64_t volatile_atomic*, address_to_check, int64_t, value_to_wait, uint32_t, timeout_ms)(INTERLOCKED_HL_OK, INTERLOCKED_HL_ERROR);
|
||||
```
|
||||
|
||||
`InterlockedHL_WaitForValue64` waits for the value at a given address to be not equal to a target value.
|
||||
[Note: address_to_check refers to address, value_to_wait refers to value, and timeout_ms refers to milliseconds]
|
||||
`InterlockedHL_WaitForValue64` waits for the value at the given `address_to_check` to be not equal to the target `value_to_wait`.
|
||||
|
||||
**S_R_S_INTERLOCKED_HL_05_007: [** If `address_to_check` is `NULL`, `InterlockedHL_WaitForNotValue64` shall fail and return `INTERLOCKED_HL_ERROR`. **]**
|
||||
**SRS_INTERLOCKED_HL_05_007: [** If `address_to_check` is `NULL`, `InterlockedHL_WaitForNotValue64` shall fail and return `INTERLOCKED_HL_ERROR`. **]**
|
||||
|
||||
**S_R_S_INTERLOCKED_HL_05_008: [** If the value at `address_to_check` is not equal to `value_to_wait`, `InterlockedHL_WaitForNotValue64` shall return `INTERLOCKED_HL_OK`. **]**
|
||||
**SRS_INTERLOCKED_HL_05_008: [** If the value at `address_to_check` is not equal to `value_to_wait`, `InterlockedHL_WaitForNotValue64` shall return `INTERLOCKED_HL_OK`. **]**
|
||||
|
||||
**S_R_S_INTERLOCKED_HL_05_009: [** If the value at `address_to_check` is equal to `value_to_wait`, `InterlockedHL_WaitForNotValue64` shall wait until the value at `address_to_check` changes using `wait_on_address_64`. **]**
|
||||
**SRS_INTERLOCKED_HL_05_009: [** If the value at `address_to_check` is equal to `value_to_wait`, `InterlockedHL_WaitForNotValue64` shall wait until the value at `address_to_check` changes using `wait_on_address_64`. **]**
|
||||
|
||||
**S_R_S_INTERLOCKED_HL_05_010: [** When `wait_on_address_64` succeeds, `InterlockedHL_WaitForNotValue64` shall again compare the value at `address_to_check` with `value_to_wait`. **]**
|
||||
**SRS_INTERLOCKED_HL_05_010: [** When `wait_on_address_64` succeeds, `InterlockedHL_WaitForNotValue64` shall again compare the value at `address_to_check` with `value_to_wait`. **]**
|
||||
|
||||
**S_R_S_INTERLOCKED_HL_05_011: [** If `wait_on_address_64` hits the timeout specified in timeout_ms, `InterlockedHL_WaitForNotValue64` shall fail and return `INTERLOCKED_HL_TIMEOUT`. **]**
|
||||
**SRS_INTERLOCKED_HL_05_011: [** If `wait_on_address_64` hits the timeout specified in timeout_ms, `InterlockedHL_WaitForNotValue64` shall fail and return `INTERLOCKED_HL_TIMEOUT`. **]**
|
||||
|
||||
**SRS_INTERLOCKED_HL_05_012: [** If `wait_on_address_64` fails, `InterlockedHL_WaitForNotValue64` shall fail and return `INTERLOCKED_HL_ERROR`. **]**
|
||||
|
||||
**S_R_S_INTERLOCKED_HL_05_012: [** If `wait_on_address_64` fails, `InterlockedHL_WaitForNotValue64` shall fail and return `INTERLOCKED_HL_ERROR`. **]**
|
||||
|
||||
### InterlockedHL_CompareExchangeIf
|
||||
```c
|
||||
|
@ -220,13 +212,13 @@ MOCKABLE_FUNCTION_WITH_RETURNS(, INTERLOCKED_HL_RESULT, InterlockedHL_SetAndWake
|
|||
|
||||
`InterlockedHL_SetAndWake64` set the value at `address` to `value` and signals the change of value in `address`. This can be commonly used with `InterlockedHL_WaitForValue64` to signal a waiting thread.
|
||||
|
||||
**S_R_S_INTERLOCKED_HL_05_013: [** If `address` is `NULL` then `InterlockedHL_SetAndWake64` shall fail and return `INTERLOCKED_HL_ERROR`. **]**
|
||||
**SRS_INTERLOCKED_HL_05_013: [** If `address` is `NULL` then `InterlockedHL_SetAndWake64` shall fail and return `INTERLOCKED_HL_ERROR`. **]**
|
||||
|
||||
**S_R_S_INTERLOCKED_HL_05_014: [** `InterlockedHL_SetAndWake64` shall set `value` at `address`. **]**
|
||||
**SRS_INTERLOCKED_HL_05_014: [** `InterlockedHL_SetAndWake64` shall set `value` at `address`. **]**
|
||||
|
||||
**S_R_S_INTERLOCKED_HL_05_015: [** `InterlockedHL_SetAndWake64` shall wake a single thread listening on `address`. **]**
|
||||
**SRS_INTERLOCKED_HL_05_015: [** `InterlockedHL_SetAndWake64` shall wake a single thread listening on `address`. **]**
|
||||
|
||||
**S_R_S_INTERLOCKED_HL_05_016: [** `InterlockedHL_SetAndWake64` shall succeed and return `INTERLOCKED_HL_OK`. **]**
|
||||
**SRS_INTERLOCKED_HL_05_016: [** `InterlockedHL_SetAndWake64` shall succeed and return `INTERLOCKED_HL_OK`. **]**
|
||||
|
||||
### InterlockedHL_SetAndWakeAll
|
||||
```c
|
||||
|
@ -250,13 +242,13 @@ MOCKABLE_FUNCTION_WITH_RETURNS(, INTERLOCKED_HL_RESULT, InterlockedHL_SetAndWake
|
|||
|
||||
`InterlockedHL_SetAndWakeAll64` set the value at `address` to `value` and signals the change of value in `address` to all waiting threads. This can be commonly used with `InterlockedHL_WaitForValue64` to signal a waiting thread.
|
||||
|
||||
**S_R_S_INTERLOCKED_HL_05_017: [** If `address` is `NULL` then `InterlockedHL_SetAndWakeAll64` shall fail and return `INTERLOCKED_HL_ERROR`. **]**
|
||||
**SRS_INTERLOCKED_HL_05_017: [** If `address` is `NULL` then `InterlockedHL_SetAndWakeAll64` shall fail and return `INTERLOCKED_HL_ERROR`. **]**
|
||||
|
||||
**S_R_S_INTERLOCKED_HL_05_018: [** `InterlockedHL_SetAndWakeAll64` shall set `value` at `address`. **]**
|
||||
**SRS_INTERLOCKED_HL_05_018: [** `InterlockedHL_SetAndWakeAll64` shall set `value` at `address`. **]**
|
||||
|
||||
**S_R_S_INTERLOCKED_HL_05_019: [** `InterlockedHL_SetAndWakeAll64` shall wake all threads listening on `address`. **]**
|
||||
**SRS_INTERLOCKED_HL_05_019: [** `InterlockedHL_SetAndWakeAll64` shall wake all threads listening on `address`. **]**
|
||||
|
||||
**S_R_S_INTERLOCKED_HL_05_020: [** `InterlockedHL_SetAndWakeAll64` shall succeed and return `INTERLOCKED_HL_OK`. **]**
|
||||
**SRS_INTERLOCKED_HL_05_020: [** `InterlockedHL_SetAndWakeAll64` shall succeed and return `INTERLOCKED_HL_OK`. **]**
|
||||
|
||||
### InterlockedHL_DecrementAndWake
|
||||
```c
|
||||
|
@ -280,10 +272,10 @@ MOCKABLE_FUNCTION_WITH_RETURNS(, INTERLOCKED_HL_RESULT, InterlockedHL_DecrementA
|
|||
|
||||
`InterlockedHL_DecrementAndWake64` decrements the value at `address` by 1 and signals the change of value in `address`. This can be commonly used with `InterlockedHL_WaitForValue64` to signal a waiting thread.
|
||||
|
||||
**S_R_S_INTERLOCKED_HL_05_021: [** If `address` is `NULL` then `InterlockedHL_DecrementAndWake64` shall fail and return `INTERLOCKED_HL_ERROR`. **]**
|
||||
**SRS_INTERLOCKED_HL_05_021: [** If `address` is `NULL` then `InterlockedHL_DecrementAndWake64` shall fail and return `INTERLOCKED_HL_ERROR`. **]**
|
||||
|
||||
**S_R_S_INTERLOCKED_HL_05_022: [** `InterlockedHL_DecrementAndWake64` shall decrement the `value` at `address` by 1. **]**
|
||||
**SRS_INTERLOCKED_HL_05_022: [** `InterlockedHL_DecrementAndWake64` shall decrement the `value` at `address` by 1. **]**
|
||||
|
||||
**S_R_S_INTERLOCKED_HL_05_023: [** `InterlockedHL_DecrementAndWake64` shall wake a single thread listening on `address`. **]**
|
||||
**SRS_INTERLOCKED_HL_05_023: [** `InterlockedHL_DecrementAndWake64` shall wake a single thread listening on `address`. **]**
|
||||
|
||||
**S_R_S_INTERLOCKED_HL_05_024: [** `InterlockedHL_DecrementAndWake64` shall succeed and return `INTERLOCKED_HL_OK`. **]**
|
||||
**SRS_INTERLOCKED_HL_05_024: [** `InterlockedHL_DecrementAndWake64` shall succeed and return `INTERLOCKED_HL_OK`. **]**
|
|
@ -32,12 +32,18 @@ typedef bool (*INTERLOCKED_COMPARE_EXCHANGE_64_IF)(int64_t target, int64_t excha
|
|||
|
||||
MOCKABLE_FUNCTION_WITH_RETURNS(, INTERLOCKED_HL_RESULT, InterlockedHL_Add64WithCeiling, int64_t volatile_atomic*, Addend, int64_t, Ceiling, int64_t, Value, int64_t*, originalAddend)(INTERLOCKED_HL_OK, INTERLOCKED_HL_ERROR);
|
||||
MOCKABLE_FUNCTION_WITH_RETURNS(, INTERLOCKED_HL_RESULT, InterlockedHL_SetAndWake, int32_t volatile_atomic*, address, int32_t, value)(INTERLOCKED_HL_OK, INTERLOCKED_HL_ERROR);
|
||||
MOCKABLE_FUNCTION_WITH_RETURNS(, INTERLOCKED_HL_RESULT, InterlockedHL_SetAndWake64, int64_t volatile_atomic*, address, int64_t, value)(INTERLOCKED_HL_OK, INTERLOCKED_HL_ERROR);
|
||||
MOCKABLE_FUNCTION_WITH_RETURNS(, INTERLOCKED_HL_RESULT, InterlockedHL_SetAndWakeAll, int32_t volatile_atomic*, address, int32_t, value)(INTERLOCKED_HL_OK, INTERLOCKED_HL_ERROR);
|
||||
MOCKABLE_FUNCTION_WITH_RETURNS(, INTERLOCKED_HL_RESULT, InterlockedHL_WaitForValue, int32_t volatile_atomic*, address, int32_t, value, uint32_t, milliseconds)(INTERLOCKED_HL_OK, INTERLOCKED_HL_ERROR);
|
||||
MOCKABLE_FUNCTION_WITH_RETURNS(, INTERLOCKED_HL_RESULT, InterlockedHL_WaitForNotValue, int32_t volatile_atomic*, address, int32_t, value, uint32_t, milliseconds)(INTERLOCKED_HL_OK, INTERLOCKED_HL_ERROR);
|
||||
MOCKABLE_FUNCTION_WITH_RETURNS(, INTERLOCKED_HL_RESULT, InterlockedHL_SetAndWakeAll64, int64_t volatile_atomic*, address, int64_t, value)(INTERLOCKED_HL_OK, INTERLOCKED_HL_ERROR);
|
||||
MOCKABLE_FUNCTION_WITH_RETURNS(, INTERLOCKED_HL_RESULT, InterlockedHL_WaitForValue, int32_t volatile_atomic*, address_to_check, int32_t, value_to_wait, uint32_t, timeout_ms)(INTERLOCKED_HL_OK, INTERLOCKED_HL_ERROR);
|
||||
MOCKABLE_FUNCTION_WITH_RETURNS(, INTERLOCKED_HL_RESULT, InterlockedHL_WaitForValue64, int64_t volatile_atomic*, address_to_check, int64_t, value_to_wait, uint32_t, timeout_ms)(INTERLOCKED_HL_OK, INTERLOCKED_HL_ERROR);
|
||||
MOCKABLE_FUNCTION_WITH_RETURNS(, INTERLOCKED_HL_RESULT, InterlockedHL_WaitForNotValue, int32_t volatile_atomic*, address_to_check, int32_t, value_to_wait, uint32_t, timeout_ms)(INTERLOCKED_HL_OK, INTERLOCKED_HL_ERROR);
|
||||
MOCKABLE_FUNCTION_WITH_RETURNS(, INTERLOCKED_HL_RESULT, InterlockedHL_WaitForNotValue64, int64_t volatile_atomic*, address_to_check, int64_t, value_to_wait, uint32_t, timeout_ms)(INTERLOCKED_HL_OK, INTERLOCKED_HL_ERROR);
|
||||
MOCKABLE_FUNCTION_WITH_RETURNS(, INTERLOCKED_HL_RESULT, InterlockedHL_CompareExchangeIf, int32_t volatile_atomic*, target, int32_t, exchange, INTERLOCKED_COMPARE_EXCHANGE_IF, compare, int32_t*, original_target)(INTERLOCKED_HL_OK, INTERLOCKED_HL_ERROR);
|
||||
MOCKABLE_FUNCTION_WITH_RETURNS(, INTERLOCKED_HL_RESULT, InterlockedHL_CompareExchange64If, int64_t volatile_atomic*, target, int64_t, exchange, INTERLOCKED_COMPARE_EXCHANGE_64_IF, compare, int64_t*, original_target)(INTERLOCKED_HL_OK, INTERLOCKED_HL_ERROR);
|
||||
MOCKABLE_FUNCTION_WITH_RETURNS(, INTERLOCKED_HL_RESULT, InterlockedHL_DecrementAndWake, int32_t volatile_atomic*, address)(INTERLOCKED_HL_OK, INTERLOCKED_HL_ERROR);
|
||||
MOCKABLE_FUNCTION_WITH_RETURNS(, INTERLOCKED_HL_RESULT, InterlockedHL_DecrementAndWake64, int64_t volatile_atomic*, address)(INTERLOCKED_HL_OK, INTERLOCKED_HL_ERROR);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -12,12 +12,17 @@
|
|||
MU_FOR_EACH_1(R2, \
|
||||
InterlockedHL_Add64WithCeiling, \
|
||||
InterlockedHL_WaitForValue, \
|
||||
InterlockedHL_WaitForValue64, \
|
||||
InterlockedHL_WaitForNotValue, \
|
||||
InterlockedHL_WaitForNotValue64, \
|
||||
InterlockedHL_SetAndWake, \
|
||||
InterlockedHL_SetAndWake64, \
|
||||
InterlockedHL_SetAndWakeAll, \
|
||||
InterlockedHL_SetAndWakeAll64, \
|
||||
InterlockedHL_CompareExchangeIf, \
|
||||
InterlockedHL_CompareExchange64If, \
|
||||
InterlockedHL_DecrementAndWake \
|
||||
InterlockedHL_DecrementAndWake, \
|
||||
InterlockedHL_DecrementAndWake64 \
|
||||
)
|
||||
|
||||
#include "c_pal/interlocked.h"
|
||||
|
@ -26,13 +31,18 @@
|
|||
|
||||
|
||||
INTERLOCKED_HL_RESULT real_InterlockedHL_Add64WithCeiling(int64_t volatile_atomic* Addend, int64_t Ceiling, int64_t Value, int64_t* originalAddend);
|
||||
INTERLOCKED_HL_RESULT real_InterlockedHL_WaitForValue(int32_t volatile_atomic* address, int32_t value, uint32_t milliseconds);
|
||||
INTERLOCKED_HL_RESULT real_InterlockedHL_WaitForNotValue(int32_t volatile_atomic* address, int32_t value, uint32_t milliseconds);
|
||||
INTERLOCKED_HL_RESULT real_InterlockedHL_WaitForValue(int32_t volatile_atomic* address_to_check, int32_t value_to_wait, uint32_t timeout_ms);
|
||||
INTERLOCKED_HL_RESULT real_InterlockedHL_WaitForValue64(int64_t volatile_atomic* address_to_check, int64_t value_to_wait, uint32_t timeout_ms);
|
||||
INTERLOCKED_HL_RESULT real_InterlockedHL_WaitForNotValue(int32_t volatile_atomic* address_to_check, int32_t value_to_wait, uint32_t timeout_ms);
|
||||
INTERLOCKED_HL_RESULT real_InterlockedHL_WaitForNotValue64(int64_t volatile_atomic* address_to_check, int64_t value_to_wait, uint32_t timeout_ms);
|
||||
INTERLOCKED_HL_RESULT real_InterlockedHL_SetAndWake(int32_t volatile_atomic* address, int32_t value);
|
||||
INTERLOCKED_HL_RESULT real_InterlockedHL_SetAndWake64(int64_t volatile_atomic* address, int64_t value);
|
||||
INTERLOCKED_HL_RESULT real_InterlockedHL_SetAndWakeAll(int32_t volatile_atomic* address, int32_t value);
|
||||
INTERLOCKED_HL_RESULT real_InterlockedHL_SetAndWakeAll64(int64_t volatile_atomic* address, int64_t value);
|
||||
INTERLOCKED_HL_RESULT real_InterlockedHL_CompareExchangeIf(int32_t volatile_atomic* target, int32_t exchange, INTERLOCKED_COMPARE_EXCHANGE_IF compare, int32_t* original_target);
|
||||
INTERLOCKED_HL_RESULT real_InterlockedHL_CompareExchange64If(int64_t volatile_atomic* target, int64_t exchange, INTERLOCKED_COMPARE_EXCHANGE_64_IF compare, int64_t* original_target);
|
||||
INTERLOCKED_HL_RESULT real_InterlockedHL_DecrementAndWake(int32_t volatile_atomic* address);
|
||||
INTERLOCKED_HL_RESULT real_InterlockedHL_DecrementAndWake64(int64_t volatile_atomic* address);
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,14 +1,18 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#define InterlockedHL_Add64WithCeiling real_InterlockedHL_Add64WithCeiling
|
||||
#define InterlockedHL_WaitForValue real_InterlockedHL_WaitForValue
|
||||
#define InterlockedHL_WaitForValue64 real_InterlockedHL_WaitForValue64
|
||||
#define InterlockedHL_WaitForNotValue real_InterlockedHL_WaitForNotValue
|
||||
#define InterlockedHL_SetAndWake real_InterlockedHL_SetAndWake
|
||||
#define InterlockedHL_SetAndWakeAll real_InterlockedHL_SetAndWakeAll
|
||||
#define InterlockedHL_CompareExchangeIf real_InterlockedHL_CompareExchangeIf
|
||||
#define InterlockedHL_CompareExchange64If real_InterlockedHL_CompareExchange64If
|
||||
#define InterlockedHL_DecrementAndWake real_InterlockedHL_DecrementAndWake
|
||||
#define InterlockedHL_Add64WithCeiling real_InterlockedHL_Add64WithCeiling
|
||||
#define InterlockedHL_WaitForValue real_InterlockedHL_WaitForValue
|
||||
#define InterlockedHL_WaitForValue64 real_InterlockedHL_WaitForValue64
|
||||
#define InterlockedHL_WaitForNotValue real_InterlockedHL_WaitForNotValue
|
||||
#define InterlockedHL_WaitForNotValue64 real_InterlockedHL_WaitForNotValue64
|
||||
#define InterlockedHL_SetAndWake real_InterlockedHL_SetAndWake
|
||||
#define InterlockedHL_SetAndWake64 real_InterlockedHL_SetAndWake64
|
||||
#define InterlockedHL_SetAndWakeAll real_InterlockedHL_SetAndWakeAll
|
||||
#define InterlockedHL_SetAndWakeAll64 real_InterlockedHL_SetAndWakeAll64
|
||||
#define InterlockedHL_CompareExchangeIf real_InterlockedHL_CompareExchangeIf
|
||||
#define InterlockedHL_CompareExchange64If real_InterlockedHL_CompareExchange64If
|
||||
#define InterlockedHL_DecrementAndWake real_InterlockedHL_DecrementAndWake
|
||||
#define InterlockedHL_DecrementAndWake64 real_InterlockedHL_DecrementAndWake64
|
||||
|
||||
#define INTERLOCKED_HL_RESULT real_INTERLOCKED_HL_RESULT
|
||||
#define INTERLOCKED_HL_RESULT real_INTERLOCKED_HL_RESULT
|
||||
|
|
|
@ -24,7 +24,7 @@ IMPLEMENT_MOCKABLE_FUNCTION(, INTERLOCKED_HL_RESULT, InterlockedHL_Add64WithCeil
|
|||
(originalAddend == NULL)
|
||||
)
|
||||
{
|
||||
LogError("invalid arguments int64_t volatile_atomic* Addend=%p, int64_t Ceiling=%" PRId64 ", int64_t Value=%" PRId64 ", int64_t* originalAddend=%p",
|
||||
LogError("Invalid arguments int64_t volatile_atomic* Addend=%p, int64_t Ceiling=%" PRId64 ", int64_t Value=%" PRId64 ", int64_t* originalAddend=%p",
|
||||
Addend, Ceiling, Value, originalAddend);
|
||||
result = INTERLOCKED_HL_ERROR;
|
||||
}
|
||||
|
@ -79,13 +79,15 @@ IMPLEMENT_MOCKABLE_FUNCTION(, INTERLOCKED_HL_RESULT, InterlockedHL_Add64WithCeil
|
|||
return result;
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, INTERLOCKED_HL_RESULT, InterlockedHL_WaitForValue, int32_t volatile_atomic*, address, int32_t, value, uint32_t, milliseconds)
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, INTERLOCKED_HL_RESULT, InterlockedHL_WaitForValue, int32_t volatile_atomic*, address_to_check, int32_t, value_to_wait, uint32_t, timeout_ms)
|
||||
{
|
||||
INTERLOCKED_HL_RESULT result;
|
||||
INTERLOCKED_HL_RESULT result = INTERLOCKED_HL_ERROR;
|
||||
|
||||
/* Codes_SRS_INTERLOCKED_HL_01_002: [ If address is NULL, InterlockedHL_WaitForValue shall fail and return INTERLOCKED_HL_ERROR. ]*/
|
||||
if (address == NULL)
|
||||
if (address_to_check == NULL)
|
||||
{
|
||||
/* Codes_SRS_INTERLOCKED_HL_01_002: [ If address_to_check is NULL, InterlockedHL_WaitForValue shall fail and return INTERLOCKED_HL_ERROR. ] */
|
||||
LogError("Invalid arguments InterlockedHL_WaitForValue(address=%p, value=%" PRId32 ", milliseconds=%" PRIu32 ")",
|
||||
address_to_check, value_to_wait, timeout_ms);
|
||||
result = INTERLOCKED_HL_ERROR;
|
||||
}
|
||||
else
|
||||
|
@ -94,34 +96,33 @@ IMPLEMENT_MOCKABLE_FUNCTION(, INTERLOCKED_HL_RESULT, InterlockedHL_WaitForValue,
|
|||
|
||||
do
|
||||
{
|
||||
/* Codes_SRS_INTERLOCKED_HL_01_007: [ When wait_on_address succeeds, the value at address shall be compared to the target value passed in value by using interlocked_add. ]*/
|
||||
current_value = interlocked_add(address, 0);
|
||||
if (current_value == value)
|
||||
/* Codes_SRS_INTERLOCKED_HL_01_007: [ When wait_on_address succeeds, the value at address shall be compared to the target value passed in value by using interlocked_add. ] */
|
||||
current_value = interlocked_add(address_to_check, 0);
|
||||
if (current_value == value_to_wait)
|
||||
{
|
||||
/* Codes_SRS_INTERLOCKED_HL_01_003: [ If the value at address is equal to value, InterlockedHL_WaitForValue shall return INTERLOCKED_HL_OK. ]*/
|
||||
/* Codes_SRS_INTERLOCKED_HL_01_003: [ If the value at address_to_check is equal to value_to_wait, InterlockedHL_WaitForValue shall return INTERLOCKED_HL_OK. ] */
|
||||
result = INTERLOCKED_HL_OK;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Codes_SRS_INTERLOCKED_HL_01_008: [ If the value at address does not match, InterlockedHL_WaitForValue shall issue another call to wait_on_address. ]*/
|
||||
|
||||
/* Codes_SRS_INTERLOCKED_HL_01_004: [ If the value at address is not equal to value, InterlockedHL_WaitForValue shall wait until the value at address changes in order to compare it again to value by using wait_on_address. ]*/
|
||||
/* Codes_SRS_INTERLOCKED_HL_01_005: [ When waiting for the value at address to change, the milliseconds argument value shall be used as timeout. ]*/
|
||||
WAIT_ON_ADDRESS_RESULT wait_result = wait_on_address(address, current_value, milliseconds);
|
||||
/* Codes_SRS_INTERLOCKED_HL_01_004: [ If the value at address_to_check is not equal to value_to_wait, InterlockedHL_WaitForValue shall wait until the value at address_to_check changes using wait_on_address. ]*/
|
||||
WAIT_ON_ADDRESS_RESULT wait_result = wait_on_address(address_to_check, current_value, timeout_ms);
|
||||
if (wait_result == WAIT_ON_ADDRESS_OK)
|
||||
{
|
||||
result = INTERLOCKED_HL_OK;
|
||||
/* Codes_SRS_INTERLOCKED_HL_01_007: [ When wait_on_address succeeds, InterlockedHL_WaitForValue shall again compare the value at address_to_check with value_to_wait. ] */
|
||||
// Loop back to compare current_value and value_to_wait
|
||||
continue;
|
||||
}
|
||||
else if (wait_result == WAIT_ON_ADDRESS_TIMEOUT)
|
||||
{
|
||||
/* Codes_SRS_INTERLOCKED_HL_11_001: [ If wait_on_address timesout, InterlockedHL_WaitForValue shall fail and return INTERLOCKED_HL_TIMEOUT. ] */
|
||||
/* Codes_SRS_INTERLOCKED_HL_11_001: [ If wait_on_address hits the timeout specified in timeout_ms, InterlockedHL_WaitForValue shall fail and return INTERLOCKED_HL_TIMEOUT. ] */
|
||||
result = INTERLOCKED_HL_TIMEOUT;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogError("failure in wait_on_address(address=%p, ¤t_value=%p, milliseconds=%" PRIu32 ") result: %" PRI_MU_ENUM "",
|
||||
address, ¤t_value, milliseconds, MU_ENUM_VALUE(WAIT_ON_ADDRESS_RESULT, wait_result));
|
||||
LogError("Failure in InterlockedHL_WaitForValue(address=%p, value=%" PRId32 ", timeout_ms=%" PRIu32 ") current_value=%" PRId32 " result: %" PRI_MU_ENUM " while calling wait_on_address_64.",
|
||||
address_to_check, value_to_wait, timeout_ms, current_value, MU_ENUM_VALUE(WAIT_ON_ADDRESS_RESULT, wait_result));
|
||||
/* Codes_SRS_INTERLOCKED_HL_01_006: [ If wait_on_address fails, InterlockedHL_WaitForValue shall fail and return INTERLOCKED_HL_ERROR. ]*/
|
||||
result = INTERLOCKED_HL_ERROR;
|
||||
break;
|
||||
|
@ -132,15 +133,66 @@ IMPLEMENT_MOCKABLE_FUNCTION(, INTERLOCKED_HL_RESULT, InterlockedHL_WaitForValue,
|
|||
return result;
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, INTERLOCKED_HL_RESULT, InterlockedHL_WaitForNotValue, int32_t volatile_atomic*, address, int32_t, value, uint32_t, milliseconds)
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, INTERLOCKED_HL_RESULT, InterlockedHL_WaitForValue64, int64_t volatile_atomic*, address_to_check, int64_t, value_to_wait, uint32_t, timeout_ms)
|
||||
{
|
||||
INTERLOCKED_HL_RESULT result;
|
||||
INTERLOCKED_HL_RESULT result = INTERLOCKED_HL_ERROR;
|
||||
|
||||
/* Codes_SRS_INTERLOCKED_HL_42_001: [ If address is NULL, InterlockedHL_WaitForNotValue shall fail and return INTERLOCKED_HL_ERROR. ]*/
|
||||
if (address == NULL)
|
||||
if (address_to_check == NULL)
|
||||
{
|
||||
LogError("invalid arguments int32_t volatile_atomic* address=%p, int32_t value=%" PRId32 ", uint32_t milliseconds=%" PRIu32 "",
|
||||
address, value, milliseconds);
|
||||
/* Codes_SRS_INTERLOCKED_HL_05_001: [ If address_to_check is NULL, InterlockedHL_WaitForValue64 shall fail and return INTERLOCKED_HL_ERROR. ] */
|
||||
LogError("Invalid arguments InterlockedHL_WaitForValue64(address=%p, value=%" PRId64 ", milliseconds=%" PRIu32 ")",
|
||||
address_to_check, value_to_wait, timeout_ms);
|
||||
result = INTERLOCKED_HL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
int64_t current_value;
|
||||
do
|
||||
{
|
||||
current_value = interlocked_add_64(address_to_check, 0);
|
||||
if (current_value == value_to_wait)
|
||||
{
|
||||
/* Codes_SRS_INTERLOCKED_HL_05_002: [ If the value at address_to_check is equal to value_to_wait, InterlockedHL_WaitForValue64 shall return INTERLOCKED_HL_OK. ] */
|
||||
result = INTERLOCKED_HL_OK;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Codes_SRS_INTERLOCKED_HL_05_003: [ If the value at address_to_check is not equal to value_to_wait, InterlockedHL_WaitForValue64 shall wait until the value at address_to_check changes using wait_on_address_64. ] */
|
||||
WAIT_ON_ADDRESS_RESULT wait_result = wait_on_address_64(address_to_check, current_value, timeout_ms);
|
||||
if (wait_result == WAIT_ON_ADDRESS_OK)
|
||||
{
|
||||
/* Codes_SRS_INTERLOCKED_HL_05_004: [ When wait_on_address_64 succeeds, InterlockedHL_WaitForValue64 shall again compare the value at address_to_check with value_to_wait. */
|
||||
// Loop back to check current_value and value_to_wait
|
||||
continue;
|
||||
}
|
||||
else if (wait_result == WAIT_ON_ADDRESS_TIMEOUT)
|
||||
{
|
||||
/* Codes_SRS_INTERLOCKED_HL_05_005: [ If wait_on_address_64 hits the timeout specified in timeout_ms, InterlockedHL_WaitForValue64 shall fail and return INTERLOCKED_HL_TIMEOUT. ] */
|
||||
result = INTERLOCKED_HL_TIMEOUT;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogError("Failure in InterlockedHL_WaitForValue64(address=%p, value=%" PRId64 ", timeout_ms=%" PRIu32 ") current_value=%" PRId64 " result: %" PRI_MU_ENUM " while calling wait_on_address_64.",
|
||||
address_to_check, value_to_wait, timeout_ms, current_value, MU_ENUM_VALUE(WAIT_ON_ADDRESS_RESULT, wait_result));
|
||||
/* Codes_SRS_INTERLOCKED_HL_05_006: [ If wait_on_address_64 fails, InterlockedHL_WaitForValue64 shall fail and return INTERLOCKED_HL_ERROR. ] */
|
||||
result = INTERLOCKED_HL_ERROR;
|
||||
break;
|
||||
}
|
||||
} while (1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, INTERLOCKED_HL_RESULT, InterlockedHL_WaitForNotValue, int32_t volatile_atomic*, address_to_check, int32_t, value_to_wait, uint32_t, timeout_ms)
|
||||
{
|
||||
INTERLOCKED_HL_RESULT result = INTERLOCKED_HL_ERROR;
|
||||
|
||||
if (address_to_check == NULL)
|
||||
{
|
||||
/* Codes_SRS_INTERLOCKED_HL_42_001: [ If address_to_check is NULL, InterlockedHL_WaitForNotValue shall fail and return INTERLOCKED_HL_ERROR. ]*/
|
||||
LogError("Invalid arguments InterlockedHL_WaitForNotValue(address=%p, value=%" PRId32 ", milliseconds=%" PRIu32 ")",
|
||||
address_to_check, value_to_wait, timeout_ms);
|
||||
result = INTERLOCKED_HL_ERROR;
|
||||
}
|
||||
else
|
||||
|
@ -149,35 +201,33 @@ IMPLEMENT_MOCKABLE_FUNCTION(, INTERLOCKED_HL_RESULT, InterlockedHL_WaitForNotVal
|
|||
|
||||
do
|
||||
{
|
||||
/* Codes_SRS_INTERLOCKED_HL_42_005: [ When wait_on_address succeeds, the value at address shall be compared to the target value passed in value by using interlocked_add. ]*/
|
||||
current_value = interlocked_add(address, 0);
|
||||
if (current_value != value)
|
||||
current_value = interlocked_add(address_to_check, 0);
|
||||
if (current_value != value_to_wait)
|
||||
{
|
||||
/* Codes_SRS_INTERLOCKED_HL_42_002: [ If the value at address is not equal to value, InterlockedHL_WaitForNotValue shall return INTERLOCKED_HL_OK. ]*/
|
||||
/* Codes_SRS_INTERLOCKED_HL_42_002: [ If the value at address_to_check is not equal to value_to_wait, InterlockedHL_WaitForNotValue shall return INTERLOCKED_HL_OK. ]*/
|
||||
result = INTERLOCKED_HL_OK;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Codes_SRS_INTERLOCKED_HL_42_006: [ If the value at address matches, InterlockedHL_WaitForNotValue shall issue another call to wait_on_address. ]*/
|
||||
|
||||
/* Codes_SRS_INTERLOCKED_HL_42_003: [ If the value at address is equal to value, InterlockedHL_WaitForNotValue shall wait until the value at address changes in order to compare it again to value by using wait_on_address. ]*/
|
||||
/* Codes_SRS_INTERLOCKED_HL_42_004: [ When waiting for the value at address to change, the milliseconds argument value shall be used as timeout. ]*/
|
||||
WAIT_ON_ADDRESS_RESULT wait_result = wait_on_address(address, current_value, milliseconds);
|
||||
/* Codes_SRS_INTERLOCKED_HL_42_003: [ If the value at address_to_check is equal to value_to_wait, InterlockedHL_WaitForNotValue shall wait until the value at address_to_check changes by using wait_on_address. ]*/
|
||||
WAIT_ON_ADDRESS_RESULT wait_result = wait_on_address(address_to_check, current_value, timeout_ms);
|
||||
if (wait_result == WAIT_ON_ADDRESS_OK)
|
||||
{
|
||||
result = INTERLOCKED_HL_OK;
|
||||
/* Codes_SRS_INTERLOCKED_HL_42_005: [When wait_on_address succeeds, InterlockedHL_WaitForNotValue shall again compare the value at address_to_check with value_to_wait.]*/
|
||||
// Loop back to check current_value and value_to_wait
|
||||
continue;
|
||||
}
|
||||
else if (wait_result == WAIT_ON_ADDRESS_TIMEOUT)
|
||||
{
|
||||
/* Codes_SRS_INTERLOCKED_HL_11_002: [ If wait_on_address timesout, InterlockedHL_WaitForNotValue shall fail and return INTERLOCKED_HL_TIMEOUT. ] */
|
||||
/* Codes_SRS_INTERLOCKED_HL_11_002: [ If wait_on_address hits the timeout specified in timeout_ms, InterlockedHL_WaitForNotValue shall fail and return INTERLOCKED_HL_TIMEOUT. ] */
|
||||
result = INTERLOCKED_HL_TIMEOUT;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogError("failure in wait_on_address(address=%p, ¤t_value=%p, milliseconds=%" PRIu32 ") result: %" PRI_MU_ENUM "",
|
||||
address, ¤t_value, milliseconds, MU_ENUM_VALUE(WAIT_ON_ADDRESS_RESULT, wait_result));
|
||||
/* Codes_SRS_INTERLOCKED_HL_42_007: [ If wait_on_address fails, InterlockedHL_WaitForNotValue shall fail and return INTERLOCKED_HL_ERROR. ]*/
|
||||
LogError("Failure in InterlockedHL_WaitForNotValue(address=%p, value=%" PRId32 ", timeout_ms=%" PRIu32 ") current_value=%" PRId32 " result: %" PRI_MU_ENUM " while calling wait_on_address.",
|
||||
address_to_check, value_to_wait, timeout_ms, current_value, MU_ENUM_VALUE(WAIT_ON_ADDRESS_RESULT, wait_result));
|
||||
/* Codes_SRS_INTERLOCKED_HL_42_007: [ If wait_on_address fails, InterlockedHL_WaitForNotValue shall fail and return INTERLOCKED_HL_ERROR. ] */
|
||||
result = INTERLOCKED_HL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
@ -187,6 +237,57 @@ IMPLEMENT_MOCKABLE_FUNCTION(, INTERLOCKED_HL_RESULT, InterlockedHL_WaitForNotVal
|
|||
return result;
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, INTERLOCKED_HL_RESULT, InterlockedHL_WaitForNotValue64, int64_t volatile_atomic*, address_to_check, int64_t, value_to_wait, uint32_t, timeout_ms)
|
||||
{
|
||||
INTERLOCKED_HL_RESULT result = INTERLOCKED_HL_ERROR;
|
||||
|
||||
if (address_to_check == NULL)
|
||||
{
|
||||
/* Codes_SRS_INTERLOCKED_HL_05_007: [ If address_to_check is NULL, InterlockedHL_WaitForNotValue64 shall fail and return INTERLOCKED_HL_ERROR. ] */
|
||||
LogError("Invalid arguments InterlockedHL_WaitForNotValue64(address=%p, value=%" PRId64 ", milliseconds=%" PRIu32 ")",
|
||||
address_to_check, value_to_wait, timeout_ms);
|
||||
result = INTERLOCKED_HL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
int64_t current_value;
|
||||
do
|
||||
{
|
||||
current_value = interlocked_add_64(address_to_check, 0);
|
||||
if (current_value != value_to_wait)
|
||||
{
|
||||
/* Codes_SRS_INTERLOCKED_HL_05_008: [ If the value at address_to_check is not equal to value_to_wait, InterlockedHL_WaitForNotValue64 shall return INTERLOCKED_HL_OK. ] */
|
||||
result = INTERLOCKED_HL_OK;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Codes_SRS_INTERLOCKED_HL_05_009: [ If the value at address_to_check is equal to value_to_wait, InterlockedHL_WaitForNotValue64 shall wait until the value at address_to_check changes using wait_on_address_64. ]*/
|
||||
WAIT_ON_ADDRESS_RESULT wait_result = wait_on_address_64(address_to_check, current_value, timeout_ms);
|
||||
if (wait_result == WAIT_ON_ADDRESS_OK)
|
||||
{
|
||||
/* Codes_SRS_INTERLOCKED_HL_05_010: [ When wait_on_address_64 succeeds, InterlockedHL_WaitForNotValue64 shall again compare the value at address_to_check with value_to_wait. ] */
|
||||
// Loop back to compare current_value and value_to_wait
|
||||
continue;
|
||||
}
|
||||
else if (wait_result == WAIT_ON_ADDRESS_TIMEOUT)
|
||||
{
|
||||
/* Codes_SRS_INTERLOCKED_HL_05_011: [ If wait_on_address_64 hits the timeout specified in timeout_ms, InterlockedHL_WaitForNotValue64 shall fail and return INTERLOCKED_HL_TIMEOUT. ] */
|
||||
result = INTERLOCKED_HL_TIMEOUT;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogError("Failure in InterlockedHL_WaitForNotValue(address=%p, value=%" PRId64 ", timeout_ms=%" PRIu32 ") current_value=%" PRId64 " result: %" PRI_MU_ENUM " while calling wait_on_address_64.",
|
||||
address_to_check, value_to_wait, timeout_ms, current_value, MU_ENUM_VALUE(WAIT_ON_ADDRESS_RESULT, wait_result));
|
||||
/* Codes_SRS_INTERLOCKED_HL_05_012: [ If wait_on_address_64 fails, InterlockedHL_WaitForNotValue64 shall fail and return INTERLOCKED_HL_ERROR. ] */
|
||||
result = INTERLOCKED_HL_ERROR;
|
||||
break;
|
||||
}
|
||||
} while (1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, INTERLOCKED_HL_RESULT, InterlockedHL_CompareExchangeIf, int32_t volatile_atomic*, target, int32_t, exchange, INTERLOCKED_COMPARE_EXCHANGE_IF, compare, int32_t*, original_target)
|
||||
{
|
||||
INTERLOCKED_HL_RESULT result;
|
||||
|
@ -305,6 +406,31 @@ IMPLEMENT_MOCKABLE_FUNCTION(, INTERLOCKED_HL_RESULT, InterlockedHL_SetAndWake, i
|
|||
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, INTERLOCKED_HL_RESULT, InterlockedHL_SetAndWake64, int64_t volatile_atomic*, address, int64_t, value)
|
||||
{
|
||||
INTERLOCKED_HL_RESULT result;
|
||||
if (address == NULL)
|
||||
{
|
||||
/* Codes_SRS_INTERLOCKED_HL_05_013: [ If address is NULL then InterlockedHL_SetAndWake64 shall fail and return INTERLOCKED_HL_ERROR. ] */
|
||||
LogError("invalid arguments int64_t volatile_atomic* address=%p, int64_t value=%" PRId64 "",
|
||||
address, value);
|
||||
result = INTERLOCKED_HL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Codes_SRS_INTERLOCKED_HL_05_014: [ InterlockedHL_SetAndWake64 shall set value at address. ] */
|
||||
(void)interlocked_exchange_64(address, value);
|
||||
|
||||
/* Codes_SRS_INTERLOCKED_HL_05_015: [ InterlockedHL_SetAndWake64 shall wake a single thread listening on address. ] */
|
||||
wake_by_address_single_64(address);
|
||||
|
||||
/* Codes_SRS_INTERLOCKED_HL_05_016: [ InterlockedHL_SetAndWake64 shall succeed and return INTERLOCKED_HL_OK. ] */
|
||||
result = INTERLOCKED_HL_OK;
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, INTERLOCKED_HL_RESULT, InterlockedHL_SetAndWakeAll, int32_t volatile_atomic*, address, int32_t, value)
|
||||
{
|
||||
INTERLOCKED_HL_RESULT result;
|
||||
|
@ -330,6 +456,31 @@ IMPLEMENT_MOCKABLE_FUNCTION(, INTERLOCKED_HL_RESULT, InterlockedHL_SetAndWakeAll
|
|||
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, INTERLOCKED_HL_RESULT, InterlockedHL_SetAndWakeAll64, int64_t volatile_atomic*, address, int64_t, value)
|
||||
{
|
||||
INTERLOCKED_HL_RESULT result;
|
||||
if (address == NULL)
|
||||
{
|
||||
/* Codes_SRS_INTERLOCKED_HL_05_017: [ If address is NULL then InterlockedHL_SetAndWakeAll64 shall fail and return INTERLOCKED_HL_ERROR. ] */
|
||||
LogError("invalid arguments int64_t volatile_atomic* address=%p, int64_t value=%" PRId64 "",
|
||||
address, value);
|
||||
result = INTERLOCKED_HL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Codes_SRS_INTERLOCKED_HL_05_018: [ InterlockedHL_SetAndWakeAll64 shall set value at address. ] */
|
||||
(void)interlocked_exchange_64(address, value);
|
||||
|
||||
/* Codes_SRS_INTERLOCKED_HL_05_019: [ InterlockedHL_SetAndWakeAll64 shall wake all threads listening on address. ] */
|
||||
wake_by_address_all_64(address);
|
||||
|
||||
/* Codes_SRS_INTERLOCKED_HL_05_020: [ InterlockedHL_SetAndWakeAll64 shall succeed and return INTERLOCKED_HL_OK. ] */
|
||||
result = INTERLOCKED_HL_OK;
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, INTERLOCKED_HL_RESULT, InterlockedHL_DecrementAndWake, int32_t volatile_atomic*, address)
|
||||
{
|
||||
INTERLOCKED_HL_RESULT result;
|
||||
|
@ -353,3 +504,27 @@ IMPLEMENT_MOCKABLE_FUNCTION(, INTERLOCKED_HL_RESULT, InterlockedHL_DecrementAndW
|
|||
return result;
|
||||
|
||||
}
|
||||
|
||||
IMPLEMENT_MOCKABLE_FUNCTION(, INTERLOCKED_HL_RESULT, InterlockedHL_DecrementAndWake64, int64_t volatile_atomic*, address)
|
||||
{
|
||||
INTERLOCKED_HL_RESULT result;
|
||||
if (address == NULL)
|
||||
{
|
||||
/* Codes_SRS_INTERLOCKED_HL_05_021: [ If address is NULL then InterlockedHL_DecrementAndWake64 shall fail and return INTERLOCKED_HL_ERROR. ] */
|
||||
LogError("invalid arguments int32_t volatile_atomic* address=%p", address);
|
||||
result = INTERLOCKED_HL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Codes_SRS_INTERLOCKED_HL_05_022: [ InterlockedHL_DecrementAndWake64 shall decrement the value at address by 1. ] */
|
||||
(void)interlocked_decrement_64(address);
|
||||
|
||||
/* Codes_SRS_INTERLOCKED_HL_05_023: [ InterlockedHL_DecrementAndWake64 shall wake a single thread listening on address. ] */
|
||||
wake_by_address_single_64(address);
|
||||
|
||||
/* Codes_SRS_INTERLOCKED_HL_05_024: [ InterlockedHL_DecrementAndWake64 shall succeed and return INTERLOCKED_HL_OK. ] */
|
||||
result = INTERLOCKED_HL_OK;
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ TEST_DEFINE_ENUM_TYPE(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_RESULT_VALUES);
|
|||
BEGIN_TEST_SUITE(TEST_SUITE_NAME_FROM_CMAKE)
|
||||
|
||||
volatile_atomic int32_t globalValue = 10;
|
||||
|
||||
volatile_atomic int64_t globalValue64 = 10;
|
||||
/*
|
||||
Tests:
|
||||
InterlockedHL_WaitForValue
|
||||
|
@ -44,7 +44,7 @@ TEST_FUNCTION(interlocked_hl_decrement_and_wake_operates_successfully)
|
|||
ASSERT_ARE_EQUAL(THREADAPI_RESULT, THREADAPI_OK, ThreadAPI_Create(&helper_thread_handle, decrement_and_wake_helper_thread_function, NULL));
|
||||
|
||||
// act and assert
|
||||
//sleep so that the helper thread can go into wait mode
|
||||
// sleep so that the helper thread can go into wait mode
|
||||
ThreadAPI_Sleep(5000);
|
||||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_OK, InterlockedHL_DecrementAndWake(&globalValue));
|
||||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, 9, globalValue);
|
||||
|
@ -55,6 +55,40 @@ TEST_FUNCTION(interlocked_hl_decrement_and_wake_operates_successfully)
|
|||
ASSERT_ARE_EQUAL(int, 0, return_code);
|
||||
}
|
||||
|
||||
/*
|
||||
Tests:
|
||||
InterlockedHL_WaitForValue64
|
||||
InterlockedHL_DecrementAndWake64
|
||||
*/
|
||||
static int decrement_and_wake_helper_thread_function_64(void* context)
|
||||
{
|
||||
(void)context;
|
||||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_OK, InterlockedHL_WaitForValue64(&globalValue64, 9, UINT32_MAX));
|
||||
return 0;
|
||||
}
|
||||
|
||||
TEST_FUNCTION(interlocked_hl_decrement_and_wake_operates_successfully_64)
|
||||
{
|
||||
// + have a helper thread which waits for decremented value
|
||||
// + main thread creates helper thread and decrements value
|
||||
// + helper thread wakes up when the global address value is decremented by 1
|
||||
// arrange
|
||||
globalValue64 = 10;
|
||||
THREAD_HANDLE helper_thread_handle;
|
||||
ASSERT_ARE_EQUAL(THREADAPI_RESULT, THREADAPI_OK, ThreadAPI_Create(&helper_thread_handle, decrement_and_wake_helper_thread_function_64, NULL));
|
||||
|
||||
// act and assert
|
||||
// sleep so that the helper thread can go into wait mode
|
||||
ThreadAPI_Sleep(5000);
|
||||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_OK, InterlockedHL_DecrementAndWake64(&globalValue64));
|
||||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, 9, globalValue64);
|
||||
|
||||
// cleanup
|
||||
int return_code;
|
||||
ASSERT_ARE_EQUAL(THREADAPI_RESULT, THREADAPI_OK, ThreadAPI_Join(helper_thread_handle, &return_code));
|
||||
ASSERT_ARE_EQUAL(int, 0, return_code);
|
||||
}
|
||||
|
||||
/*
|
||||
Tests:
|
||||
InterlockedHL_WaitForValue
|
||||
|
@ -99,6 +133,50 @@ TEST_FUNCTION(interlocked_hl_set_and_wake_all_operates_successfully)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Tests:
|
||||
InterlockedHL_WaitForValue64
|
||||
InterlockedHL_SetAndWakeAll64
|
||||
*/
|
||||
static int set_and_wake_all_helper_thread_function_64(void* context)
|
||||
{
|
||||
(void)context;
|
||||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_OK, InterlockedHL_WaitForValue64(&globalValue64, 15, UINT32_MAX));
|
||||
return 0;
|
||||
}
|
||||
|
||||
TEST_FUNCTION(interlocked_hl_set_and_wake_all_operates_successfully_64)
|
||||
{
|
||||
// + create 10 helper threads which wait on a value
|
||||
// + main thread creates helper threads and sets value for the helper threads to wake up
|
||||
// + main thread joins on the helper threads and ensures that all threads wake up and terminate
|
||||
// arrange
|
||||
globalValue64 = INT64_MAX;
|
||||
|
||||
enum { NUMBER_OF_HELPER_THREADS = 10 };
|
||||
THREAD_HANDLE helper_threads[NUMBER_OF_HELPER_THREADS];
|
||||
|
||||
for (uint32_t i = 0; i < NUMBER_OF_HELPER_THREADS; ++i)
|
||||
{
|
||||
ASSERT_ARE_EQUAL(THREADAPI_RESULT, THREADAPI_OK, ThreadAPI_Create(&helper_threads[i], set_and_wake_all_helper_thread_function_64, NULL));
|
||||
}
|
||||
|
||||
// wait time so that all helper threads go into wait mode
|
||||
ThreadAPI_Sleep(5000);
|
||||
|
||||
// act and assert
|
||||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_OK, InterlockedHL_SetAndWakeAll64(&globalValue64, 15));
|
||||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, 15, globalValue64);
|
||||
|
||||
// cleanup
|
||||
for (uint32_t i = 0; i < NUMBER_OF_HELPER_THREADS; ++i)
|
||||
{
|
||||
int return_code;
|
||||
ASSERT_ARE_EQUAL(THREADAPI_RESULT, THREADAPI_OK, ThreadAPI_Join(helper_threads[i], &return_code));
|
||||
ASSERT_ARE_EQUAL(int, 0, return_code);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Tests:
|
||||
InterlockedHL_WaitForValue
|
||||
|
@ -137,6 +215,44 @@ TEST_FUNCTION(interlocked_hl_set_and_wake_operates_successfully)
|
|||
ASSERT_ARE_EQUAL(int, 0, return_code);
|
||||
}
|
||||
|
||||
/*
|
||||
Tests:
|
||||
InterlockedHL_WaitForValue64
|
||||
InterlockedHL_SetAndWake64
|
||||
*/
|
||||
static int set_and_wake_helper_thread_function_64(void* context)
|
||||
{
|
||||
(void)context;
|
||||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_OK, InterlockedHL_WaitForValue64(&globalValue64, 20, UINT32_MAX));
|
||||
return 0;
|
||||
}
|
||||
|
||||
TEST_FUNCTION(interlocked_hl_set_and_wake_operates_successfully_64)
|
||||
{
|
||||
// + create 1 helper thread which waits on a value
|
||||
// + main thread creates helper thread and sets a value and wakes up the helper thread
|
||||
// + helper thread return from wait as the value it is waiting on is same
|
||||
// + main thread joins on the helper thread and ensures that the helper thread wakes up and terminates
|
||||
// arrange
|
||||
globalValue64 = 10;
|
||||
|
||||
THREAD_HANDLE helper_thread;
|
||||
|
||||
ASSERT_ARE_EQUAL(THREADAPI_RESULT, THREADAPI_OK, ThreadAPI_Create(&helper_thread, set_and_wake_helper_thread_function_64, NULL));
|
||||
|
||||
// wait time so that all helper thread goes into wait mode
|
||||
ThreadAPI_Sleep(5000);
|
||||
|
||||
// act and assert
|
||||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_OK, InterlockedHL_SetAndWake64(&globalValue64, 20));
|
||||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, 20, globalValue64);
|
||||
|
||||
// cleanup
|
||||
int return_code;
|
||||
ASSERT_ARE_EQUAL(THREADAPI_RESULT, THREADAPI_OK, ThreadAPI_Join(helper_thread, &return_code));
|
||||
ASSERT_ARE_EQUAL(int, 0, return_code);
|
||||
}
|
||||
|
||||
/*
|
||||
Tests:
|
||||
InterlockedHL_WaitForNotValue
|
||||
|
@ -176,6 +292,44 @@ TEST_FUNCTION(interlocked_hl_wait_for_not_value_operates_successfully)
|
|||
ASSERT_ARE_EQUAL(int, 0, return_code);
|
||||
}
|
||||
|
||||
/*
|
||||
Tests:
|
||||
InterlockedHL_WaitForNotValue64
|
||||
InterlockedHL_SetAndWake64
|
||||
*/
|
||||
static int wait_for_not_value_helper_thread_function_64(void* context)
|
||||
{
|
||||
(void)context;
|
||||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_OK, InterlockedHL_WaitForNotValue64(&globalValue64, 25, UINT32_MAX));
|
||||
return 0;
|
||||
}
|
||||
|
||||
TEST_FUNCTION(interlocked_hl_wait_for_not_value_operates_successfully_64)
|
||||
{
|
||||
// + create 1 helper thread which waits on a value
|
||||
// + main thread creates helper thread and sets a different value and wakes up the helper thread
|
||||
// + helper thread returns from wait as the value changed
|
||||
// + main thread joins on the helper thread and ensures that the helper thread wakes up and terminates
|
||||
// arrange
|
||||
globalValue64 = 25;
|
||||
|
||||
THREAD_HANDLE helper_thread;
|
||||
|
||||
ASSERT_ARE_EQUAL(THREADAPI_RESULT, THREADAPI_OK, ThreadAPI_Create(&helper_thread, wait_for_not_value_helper_thread_function_64, NULL));
|
||||
|
||||
// wait time so that all helper thread goes into wait mode as the value is 25
|
||||
ThreadAPI_Sleep(5000);
|
||||
|
||||
// act and assert
|
||||
//set and wake up helper thread
|
||||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_OK, InterlockedHL_SetAndWake64(&globalValue64, 30));
|
||||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, 30, globalValue64);
|
||||
|
||||
// cleanup
|
||||
int return_code;
|
||||
ASSERT_ARE_EQUAL(THREADAPI_RESULT, THREADAPI_OK, ThreadAPI_Join(helper_thread, &return_code));
|
||||
ASSERT_ARE_EQUAL(int, 0, return_code);
|
||||
}
|
||||
/*
|
||||
Tests:
|
||||
InterlockedHL_WaitForNotValue
|
||||
|
@ -192,6 +346,26 @@ TEST_FUNCTION(interlocked_hl_wait_for_not_value_times_out_returns_time_out)
|
|||
// cleanup
|
||||
}
|
||||
|
||||
/*
|
||||
Tests:
|
||||
InterlockedHL_WaitForNotValue64
|
||||
*/
|
||||
TEST_FUNCTION(interlocked_hl_wait_for_not_value_64)
|
||||
{
|
||||
volatile_atomic int64_t localvalue = 0;
|
||||
|
||||
(void)interlocked_exchange_64(&localvalue, 25);
|
||||
|
||||
// act and assert
|
||||
// Wait a second for the value to time out and make sure it returns the correct value
|
||||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_TIMEOUT, InterlockedHL_WaitForNotValue64(&localvalue, 25, 1000));
|
||||
|
||||
(void)interlocked_exchange_64(&localvalue, 100);
|
||||
|
||||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_OK, InterlockedHL_WaitForNotValue64(&localvalue, 25, 1000));
|
||||
// cleanup
|
||||
}
|
||||
|
||||
/*
|
||||
Tests:
|
||||
InterlockedHL_WaitForValue
|
||||
|
@ -208,6 +382,27 @@ TEST_FUNCTION(interlocked_hl_wait_for_value_times_out_returns_time_out)
|
|||
// cleanup
|
||||
}
|
||||
|
||||
/*
|
||||
Tests:
|
||||
InterlockedHL_WaitForValue64
|
||||
*/
|
||||
TEST_FUNCTION(interlocked_hl_wait_for_value_timest)
|
||||
{
|
||||
volatile_atomic int64_t localvalue = 0;
|
||||
|
||||
(void)interlocked_exchange_64(&localvalue, 25);
|
||||
|
||||
// act and assert
|
||||
// Wait a second for the value to time out and make sure it returns the correct value
|
||||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_TIMEOUT, InterlockedHL_WaitForValue64(&localvalue, 1, 1000));
|
||||
|
||||
(void)interlocked_exchange_64(&localvalue, 1);
|
||||
|
||||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_OK, InterlockedHL_WaitForValue64(&localvalue, 1, 1000));
|
||||
|
||||
// cleanup
|
||||
}
|
||||
|
||||
/*
|
||||
Tests:
|
||||
InterlockedHL_Add64WithCeiling
|
||||
|
|
|
@ -61,6 +61,12 @@ typedef struct INPUT_AND_OUTPUT_TAG
|
|||
int32_t Output;
|
||||
} INPUT_AND_OUTPUT;
|
||||
|
||||
typedef struct INPUT_AND_OUTPUT_64_TAG
|
||||
{
|
||||
volatile_atomic int64_t Input;
|
||||
int64_t Output;
|
||||
} INPUT_AND_OUTPUT_64;
|
||||
|
||||
static WAIT_ON_ADDRESS_RESULT hook_wait_on_address(volatile_atomic int32_t* address, int32_t compare_value, uint32_t milliseconds)
|
||||
{
|
||||
(void)address;
|
||||
|
@ -69,6 +75,14 @@ static WAIT_ON_ADDRESS_RESULT hook_wait_on_address(volatile_atomic int32_t* addr
|
|||
return WAIT_ON_ADDRESS_OK;
|
||||
}
|
||||
|
||||
static WAIT_ON_ADDRESS_RESULT hook_wait_on_address_64(volatile_atomic int64_t* address, int64_t compare_value, uint32_t milliseconds)
|
||||
{
|
||||
(void)address;
|
||||
(void)compare_value;
|
||||
(void)milliseconds;
|
||||
return WAIT_ON_ADDRESS_OK;
|
||||
}
|
||||
|
||||
TEST_DEFINE_ENUM_TYPE(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_RESULT_VALUES);
|
||||
IMPLEMENT_UMOCK_C_ENUM_TYPE(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_RESULT_VALUES);
|
||||
|
||||
|
@ -91,6 +105,7 @@ TEST_SUITE_INITIALIZE(a)
|
|||
REGISTER_SYNC_GLOBAL_MOCK_HOOK();
|
||||
|
||||
REGISTER_GLOBAL_MOCK_HOOK(wait_on_address, hook_wait_on_address);
|
||||
REGISTER_GLOBAL_MOCK_HOOK(wait_on_address_64, hook_wait_on_address_64);
|
||||
}
|
||||
|
||||
TEST_SUITE_CLEANUP(b)
|
||||
|
@ -107,8 +122,8 @@ TEST_FUNCTION_CLEANUP(d)
|
|||
{
|
||||
}
|
||||
|
||||
/*Tests_SRS_INTERLOCKED_HL_02_001: [ If Addend is NULL then InterlockedHL_Add64WithCeiling shall fail and return INTERLOCKED_HL_ERROR. ]*/
|
||||
/*Tests_SRS_INTERLOCKED_HL_02_007: [ In all failure cases InterlockedHL_Add64WithCeiling shall not modify Addend or originalAddend*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_02_001: [ If Addend is NULL then InterlockedHL_Add64WithCeiling shall fail and return INTERLOCKED_HL_ERROR. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_02_007: [ In all failure cases InterlockedHL_Add64WithCeiling shall not modify Addend or originalAddend*/
|
||||
TEST_FUNCTION(InterlockedHL_Add64WithCeiling_with_Addend_NULL_fails)
|
||||
{
|
||||
///arrange
|
||||
|
@ -124,7 +139,7 @@ TEST_FUNCTION(InterlockedHL_Add64WithCeiling_with_Addend_NULL_fails)
|
|||
///cleanup
|
||||
}
|
||||
|
||||
/*Tests_SRS_INTERLOCKED_HL_02_006: [ If originalAddend is NULL then InterlockedHL_Add64WithCeiling shall fail and return INTERLOCKED_HL_ERROR. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_02_006: [ If originalAddend is NULL then InterlockedHL_Add64WithCeiling shall fail and return INTERLOCKED_HL_ERROR. ] */
|
||||
TEST_FUNCTION(InterlockedHL_Add64WithCeiling_with_originalAddend_NULL_fails)
|
||||
{
|
||||
///arrange
|
||||
|
@ -140,7 +155,7 @@ TEST_FUNCTION(InterlockedHL_Add64WithCeiling_with_originalAddend_NULL_fails)
|
|||
///cleanup
|
||||
}
|
||||
|
||||
/*Tests_SRS_INTERLOCKED_HL_02_002: [ If Addend + Value would underflow then InterlockedHL_Add64WithCeiling shall fail and return INTERLOCKED_HL_ERROR. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_02_002: [ If Addend + Value would underflow then InterlockedHL_Add64WithCeiling shall fail and return INTERLOCKED_HL_ERROR. ] */
|
||||
TEST_FUNCTION(InterlockedHL_Add64WithCeiling_when_underflow_it_fails)
|
||||
{
|
||||
///arrange
|
||||
|
@ -178,7 +193,7 @@ TEST_FUNCTION(InterlockedHL_Add64WithCeiling_when_underflow_it_fails)
|
|||
real_gballoc_hl_free(cloneOfInputValues);
|
||||
}
|
||||
|
||||
/*Tests_SRS_INTERLOCKED_HL_02_003: [ If Addend + Value would overflow then InterlockedHL_Add64WithCeiling shall fail and return INTERLOCKED_HL_ERROR. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_02_003: [ If Addend + Value would overflow then InterlockedHL_Add64WithCeiling shall fail and return INTERLOCKED_HL_ERROR. ] */
|
||||
TEST_FUNCTION(InterlockedHL_Add64WithCeiling_when_overflow_it_fails)
|
||||
{
|
||||
///arrange
|
||||
|
@ -215,7 +230,7 @@ TEST_FUNCTION(InterlockedHL_Add64WithCeiling_when_overflow_it_fails)
|
|||
real_gballoc_hl_free(cloneOfInputValues);
|
||||
}
|
||||
|
||||
/*Tests_SRS_INTERLOCKED_HL_02_004: [ If Addend + Value would be greater than Ceiling then InterlockedHL_Add64WithCeiling shall fail and return INTERLOCKED_HL_ERROR. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_02_004: [ If Addend + Value would be greater than Ceiling then InterlockedHL_Add64WithCeiling shall fail and return INTERLOCKED_HL_ERROR. ] */
|
||||
TEST_FUNCTION(InterlockedHL_Add64WithCeiling_when_over_the_ceiling_it_fails)
|
||||
{
|
||||
///arrange
|
||||
|
@ -256,7 +271,7 @@ TEST_FUNCTION(InterlockedHL_Add64WithCeiling_when_over_the_ceiling_it_fails)
|
|||
real_gballoc_hl_free(cloneOfInputValues);
|
||||
}
|
||||
|
||||
/*Tests_SRS_INTERLOCKED_HL_02_005: [ Otherwise, InterlockedHL_Add64WithCeiling shall atomically write in Addend the sum of Addend and Value, succeed and return INTERLOCKED_HL_OK. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_02_005: [ Otherwise, InterlockedHL_Add64WithCeiling shall atomically write in Addend the sum of Addend and Value, succeed and return INTERLOCKED_HL_OK. ] */
|
||||
TEST_FUNCTION(InterlockedHL_Add64WithCeiling_succeeds)
|
||||
{
|
||||
///arrange
|
||||
|
@ -301,7 +316,7 @@ TEST_FUNCTION(InterlockedHL_Add64WithCeiling_succeeds)
|
|||
|
||||
/* InterlockedHL_WaitForValue */
|
||||
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_002: [ If address is NULL, InterlockedHL_WaitForValue shall fail and return INTERLOCKED_HL_ERROR. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_002: [ If address_to_check is NULL, InterlockedHL_WaitForValue shall fail and return INTERLOCKED_HL_ERROR. ] */
|
||||
TEST_FUNCTION(InterlockedHL_WaitForValue_with_NULL_address_fails)
|
||||
{
|
||||
// arrange
|
||||
|
@ -315,7 +330,7 @@ TEST_FUNCTION(InterlockedHL_WaitForValue_with_NULL_address_fails)
|
|||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_ERROR, result);
|
||||
}
|
||||
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_003: [ If the value at address is equal to value, InterlockedHL_WaitForValue shall return INTERLOCKED_HL_OK. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_003: [ If the value at address_to_check is equal to value_to_wait, InterlockedHL_WaitForValue shall return INTERLOCKED_HL_OK. ] */
|
||||
TEST_FUNCTION(when_the_value_equals_target_value_InterlockedHL_WaitForValue_returns_OK)
|
||||
{
|
||||
// arrange
|
||||
|
@ -332,9 +347,8 @@ TEST_FUNCTION(when_the_value_equals_target_value_InterlockedHL_WaitForValue_retu
|
|||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_OK, result);
|
||||
}
|
||||
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_004: [ If the value at address is not equal to value, InterlockedHL_WaitForValue shall wait until the value at address changes in order to compare it again to value by using wait_on_address. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_005: [ When waiting for the value at address to change, the milliseconds argument value shall be used as timeout. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_007: [ When wait_on_address succeeds, the value at address shall be compared to the target value passed in value by using interlocked_add. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_004: [ If the value at address_to_check is not equal to value_to_wait, InterlockedHL_WaitForValue shall wait until the value at address_to_check changes using wait_on_address. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_007: [ When wait_on_address succeeds, InterlockedHL_WaitForValue shall again compare the value at address_to_check with value_to_wait. ] */
|
||||
TEST_FUNCTION(when_the_value_equals_target_value_after_waiting_InterlockedHL_WaitForValue_returns_OK)
|
||||
{
|
||||
// arrange
|
||||
|
@ -355,10 +369,8 @@ TEST_FUNCTION(when_the_value_equals_target_value_after_waiting_InterlockedHL_Wai
|
|||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_OK, result);
|
||||
}
|
||||
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_003: [ If the value at address is equal to value, InterlockedHL_WaitForValue shall return INTERLOCKED_HL_OK. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_005: [ When waiting for the value at address to change, the milliseconds argument value shall be used as timeout. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_007: [ When wait_on_address succeeds, the value at address shall be compared to the target value passed in value by using interlocked_add. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_008: [ If the value at address does not match, InterlockedHL_WaitForValue shall issue another call to wait_on_address. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_003: [ If the value at address_to_check is equal to value_to_wait, InterlockedHL_WaitForValue shall return INTERLOCKED_HL_OK. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_007: [ When wait_on_address succeeds, the value at address shall be compared to the target value passed in value by using interlocked_add. ] */
|
||||
TEST_FUNCTION(when_the_value_after_a_succesfull_wait_on_address_does_not_equal_target_a_new_wait_for_address_shall_be_issued)
|
||||
{
|
||||
// arrange
|
||||
|
@ -383,7 +395,7 @@ TEST_FUNCTION(when_the_value_after_a_succesfull_wait_on_address_does_not_equal_t
|
|||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_OK, result);
|
||||
}
|
||||
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_006: [ If wait_on_address fails, InterlockedHL_WaitForValue shall fail and return INTERLOCKED_HL_ERROR. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_006: [ If wait_on_address fails, InterlockedHL_WaitForValue shall fail and return INTERLOCKED_HL_ERROR. ] */
|
||||
TEST_FUNCTION(when_the_wait_on_address_fails_InterlockedHL_WaitForValue_also_fails)
|
||||
{
|
||||
// arrange
|
||||
|
@ -404,7 +416,7 @@ TEST_FUNCTION(when_the_wait_on_address_fails_InterlockedHL_WaitForValue_also_fai
|
|||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_ERROR, result);
|
||||
}
|
||||
|
||||
/* Tests_SRS_INTERLOCKED_HL_11_001: [ If wait_on_address timesout, InterlockedHL_WaitForValue shall fail and return INTERLOCKED_HL_TIMEOUT. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_11_001: [ If wait_on_address hits the timeout specified in timeout_ms, InterlockedHL_WaitForValue shall fail and return INTERLOCKED_HL_TIMEOUT. ] */
|
||||
TEST_FUNCTION(when_the_wait_on_address_timesout_InterlockedHL_WaitForValue_also_timesout)
|
||||
{
|
||||
// arrange
|
||||
|
@ -423,9 +435,135 @@ TEST_FUNCTION(when_the_wait_on_address_timesout_InterlockedHL_WaitForValue_also_
|
|||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_TIMEOUT, result);
|
||||
}
|
||||
|
||||
/* InterlockedHL_WaitForValue64 */
|
||||
|
||||
/* Tests_SRS_INTERLOCKED_HL_05_001: [ If address_to_check is NULL, InterlockedHL_WaitForValue64 shall fail and return INTERLOCKED_HL_ERROR. ] */
|
||||
TEST_FUNCTION(InterlockedHL_WaitForValue64_with_NULL_address_fails)
|
||||
{
|
||||
// arrange
|
||||
INTERLOCKED_HL_RESULT result;
|
||||
|
||||
// act
|
||||
result = InterlockedHL_WaitForValue64(NULL, 0x42, UINT32_MAX);
|
||||
|
||||
// assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_ERROR, result);
|
||||
}
|
||||
|
||||
/* Tests_SRS_INTERLOCKED_HL_05_002: [ If the value at address_to_check is equal to value_to_wait, InterlockedHL_WaitForValue64 shall return INTERLOCKED_HL_OK. ] */
|
||||
TEST_FUNCTION(when_the_value_equals_target_value_InterlockedHL_WaitForValue64_returns_OK)
|
||||
{
|
||||
// arrange
|
||||
INTERLOCKED_HL_RESULT result;
|
||||
volatile_atomic int64_t value = 0x42;
|
||||
|
||||
STRICT_EXPECTED_CALL(interlocked_add_64(&value, 0));
|
||||
|
||||
// act
|
||||
result = InterlockedHL_WaitForValue64(&value, 0x42, UINT32_MAX);
|
||||
|
||||
// assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_OK, result);
|
||||
}
|
||||
|
||||
/* Tests_SRS_INTERLOCKED_HL_05_003: [ If the value at address_to_check is not equal to value_to_wait, InterlockedHL_WaitForValue64 shall wait until the value at address_to_check changes using wait_on_address_64. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_05_004: [ When wait_on_address_64 succeeds, InterlockedHL_WaitForValue64 shall again compare the value at address_to_check with value_to_wait. */
|
||||
/* Tests_SRS_INTERLOCKED_HL_05_002: [ If the value at address_to_check is equal to value_to_wait, InterlockedHL_WaitForValue64 shall return INTERLOCKED_HL_OK. ] */
|
||||
TEST_FUNCTION(when_the_value_equals_target_value_after_waiting_InterlockedHL_WaitForValue64_returns_OK)
|
||||
{
|
||||
// arrange
|
||||
INTERLOCKED_HL_RESULT result;
|
||||
volatile_atomic int64_t value = 0x41;
|
||||
int64_t target_value = 0x42;
|
||||
|
||||
STRICT_EXPECTED_CALL(interlocked_add_64(&value, 0));
|
||||
STRICT_EXPECTED_CALL(wait_on_address_64(&value, IGNORED_ARG, UINT32_MAX))
|
||||
.CopyOutArgumentBuffer_address(&target_value, sizeof(int64_t)); // Here we swap address of value with address of target_value
|
||||
STRICT_EXPECTED_CALL(interlocked_add_64(&value, 0));
|
||||
|
||||
// act
|
||||
result = InterlockedHL_WaitForValue64(&value, 0x42, UINT32_MAX);
|
||||
|
||||
// assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_OK, result);
|
||||
}
|
||||
|
||||
/* Tests_SRS_INTERLOCKED_HL_05_003: [ If the value at address_to_check is not equal to value_to_wait, InterlockedHL_WaitForValue64 shall wait until the value at address_to_check changes using wait_on_address_64. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_05_004: [ When wait_on_address_64 succeeds, InterlockedHL_WaitForValue64 shall again compare the value at address_to_check with value_to_wait. */
|
||||
/* Tests_SRS_INTERLOCKED_HL_05_002: [ If the value at address_to_check is equal to value_to_wait, InterlockedHL_WaitForValue64 shall return INTERLOCKED_HL_OK. ] */
|
||||
TEST_FUNCTION(when_the_value_after_a_succesfull_wait_on_address_64_does_not_equal_target_a_new_wait_for_address_64_shall_be_issued)
|
||||
{
|
||||
// arrange
|
||||
INTERLOCKED_HL_RESULT result;
|
||||
volatile_atomic int64_t value = 0x40;
|
||||
int64_t intermediate_value = 0x41;
|
||||
int64_t final_value = 0x42;
|
||||
|
||||
STRICT_EXPECTED_CALL(interlocked_add_64(&value, 0));
|
||||
STRICT_EXPECTED_CALL(wait_on_address_64(&value, IGNORED_ARG, UINT32_MAX))
|
||||
.CopyOutArgumentBuffer_address(&intermediate_value, sizeof(int64_t));
|
||||
STRICT_EXPECTED_CALL(interlocked_add_64(&value, 0));
|
||||
STRICT_EXPECTED_CALL(wait_on_address_64(&value, IGNORED_ARG, UINT32_MAX))
|
||||
.CopyOutArgumentBuffer_address(&final_value, sizeof(int64_t));
|
||||
STRICT_EXPECTED_CALL(interlocked_add_64(&value, 0));
|
||||
|
||||
// act
|
||||
result = InterlockedHL_WaitForValue64(&value, 0x42, UINT32_MAX);
|
||||
|
||||
// assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_OK, result);
|
||||
}
|
||||
|
||||
/* Tests_SRS_INTERLOCKED_HL_05_003: [ If the value at address_to_check is not equal to value_to_wait, InterlockedHL_WaitForValue64 shall wait until the value at address_to_check changes using wait_on_address_64. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_05_006: [ If wait_on_address_64 fails, InterlockedHL_WaitForValue64 shall fail and return INTERLOCKED_HL_ERROR. ] */
|
||||
TEST_FUNCTION(when_the_wait_on_address_64_fails_InterlockedHL_WaitForValue64_also_fails)
|
||||
{
|
||||
// arrange
|
||||
INTERLOCKED_HL_RESULT result;
|
||||
volatile_atomic int64_t value = 0x40;
|
||||
int64_t intermediate_value = 0x41;
|
||||
|
||||
STRICT_EXPECTED_CALL(interlocked_add_64(&value, 0));
|
||||
STRICT_EXPECTED_CALL(wait_on_address_64(&value, IGNORED_ARG, UINT32_MAX))
|
||||
.CopyOutArgumentBuffer_address(&intermediate_value, sizeof(int64_t))
|
||||
.SetReturn(WAIT_ON_ADDRESS_ERROR);
|
||||
|
||||
// act
|
||||
result = InterlockedHL_WaitForValue64(&value, 0x42, UINT32_MAX);
|
||||
|
||||
// assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_ERROR, result);
|
||||
}
|
||||
|
||||
/* Tests_SRS_INTERLOCKED_HL_05_003: [ If the value at address_to_check is not equal to value_to_wait, InterlockedHL_WaitForValue64 shall wait until the value at address_to_check changes using wait_on_address_64. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_05_005: [ If wait_on_address_64 hits the timeout specified in timeout_ms, InterlockedHL_WaitForValue64 shall fail and return INTERLOCKED_HL_TIMEOUT. ] */
|
||||
TEST_FUNCTION(when_the_wait_on_address_64_timesout_InterlockedHL_WaitForValue64_also_timesout)
|
||||
{
|
||||
// arrange
|
||||
INTERLOCKED_HL_RESULT result;
|
||||
volatile_atomic int64_t value = 0x40;
|
||||
|
||||
STRICT_EXPECTED_CALL(interlocked_add_64(&value, 0));
|
||||
STRICT_EXPECTED_CALL(wait_on_address_64(&value, IGNORED_ARG, 1000))
|
||||
.SetReturn(WAIT_ON_ADDRESS_TIMEOUT);
|
||||
|
||||
// act
|
||||
result = InterlockedHL_WaitForValue64(&value, 0x42, 1000);
|
||||
|
||||
// assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_TIMEOUT, result);
|
||||
}
|
||||
|
||||
|
||||
/* InterlockedHL_WaitForNotValue */
|
||||
|
||||
/* Tests_SRS_INTERLOCKED_HL_42_001: [ If address is NULL, InterlockedHL_WaitForNotValue shall fail and return INTERLOCKED_HL_ERROR. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_42_001: [ If address_to_check is NULL, InterlockedHL_WaitForNotValue shall fail and return INTERLOCKED_HL_ERROR. ] */
|
||||
TEST_FUNCTION(InterlockedHL_WaitForNotValue_with_NULL_address_fails)
|
||||
{
|
||||
// arrange
|
||||
|
@ -439,7 +577,7 @@ TEST_FUNCTION(InterlockedHL_WaitForNotValue_with_NULL_address_fails)
|
|||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_ERROR, result);
|
||||
}
|
||||
|
||||
/* Tests_SRS_INTERLOCKED_HL_42_002: [ If the value at address is not equal to value, InterlockedHL_WaitForNotValue shall return INTERLOCKED_HL_OK. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_42_002: [ If the value at address_to_check is not equal to value_to_wait, InterlockedHL_WaitForNotValue shall return INTERLOCKED_HL_OK. ] */
|
||||
TEST_FUNCTION(when_the_value_does_not_equal_target_value_InterlockedHL_WaitForNotValue_returns_OK)
|
||||
{
|
||||
// arrange
|
||||
|
@ -456,9 +594,8 @@ TEST_FUNCTION(when_the_value_does_not_equal_target_value_InterlockedHL_WaitForNo
|
|||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_OK, result);
|
||||
}
|
||||
|
||||
/* Tests_SRS_INTERLOCKED_HL_42_003: [ If the value at address is equal to value, InterlockedHL_WaitForNotValue shall wait until the value at address changes in order to compare it again to value by using wait_on_address. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_42_004: [ When waiting for the value at address to change, the milliseconds argument value shall be used as timeout. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_42_005: [ When wait_on_address succeeds, the value at address shall be compared to the target value passed in value by using interlocked_add. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_42_003: [ If the value at address_to_check is equal to value_to_wait, InterlockedHL_WaitForNotValue shall wait until the value at address_to_check changes by using wait_on_address. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_42_005: [ When wait_on_address succeeds, InterlockedHL_WaitForNotValue shall again compare the value at address_to_check with value_to_wait. ] */
|
||||
TEST_FUNCTION(when_the_value_does_not_equal_target_value_after_waiting_InterlockedHL_WaitForNotValue_returns_OK)
|
||||
{
|
||||
// arrange
|
||||
|
@ -479,10 +616,8 @@ TEST_FUNCTION(when_the_value_does_not_equal_target_value_after_waiting_Interlock
|
|||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_OK, result);
|
||||
}
|
||||
|
||||
/* Tests_SRS_INTERLOCKED_HL_42_002: [ If the value at address is not equal to value, InterlockedHL_WaitForNotValue shall return INTERLOCKED_HL_OK. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_42_004: [ When waiting for the value at address to change, the milliseconds argument value shall be used as timeout. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_42_005: [ When wait_on_address succeeds, the value at address shall be compared to the target value passed in value by using interlocked_add. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_42_006: [ If the value at address matches, InterlockedHL_WaitForNotValue shall issue another call to wait_on_address. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_42_002: [ If the value at address_to_check is not equal to value_to_wait, InterlockedHL_WaitForNotValue shall return INTERLOCKED_HL_OK. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_42_005: [ When wait_on_address succeeds, InterlockedHL_WaitForNotValue shall again compare the value at address_to_check with value_to_wait. ] */
|
||||
TEST_FUNCTION(when_the_value_after_a_succesfull_wait_on_address_equals_target_a_new_wait_for_address_shall_be_issued)
|
||||
{
|
||||
// arrange
|
||||
|
@ -507,7 +642,7 @@ TEST_FUNCTION(when_the_value_after_a_succesfull_wait_on_address_equals_target_a_
|
|||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_OK, result);
|
||||
}
|
||||
|
||||
/* Tests_SRS_INTERLOCKED_HL_42_007: [ If wait_on_address fails, InterlockedHL_WaitForNotValue shall fail and return INTERLOCKED_HL_ERROR. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_42_007: [ If wait_on_address fails, InterlockedHL_WaitForNotValue shall fail and return INTERLOCKED_HL_ERROR. ] */
|
||||
TEST_FUNCTION(when_the_wait_on_address_fails_InterlockedHL_WaitForNotValue_also_fails)
|
||||
{
|
||||
// arrange
|
||||
|
@ -526,7 +661,7 @@ TEST_FUNCTION(when_the_wait_on_address_fails_InterlockedHL_WaitForNotValue_also_
|
|||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_ERROR, result);
|
||||
}
|
||||
|
||||
/* Tests_SRS_INTERLOCKED_HL_11_002: [ If wait_on_address timesout, InterlockedHL_WaitForNotValue shall fail and return INTERLOCKED_HL_TIMEOUT. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_11_002: [ If wait_on_address hits the timeout specified in timeout_ms, InterlockedHL_WaitForNotValue shall fail and return INTERLOCKED_HL_TIMEOUT. ] */
|
||||
TEST_FUNCTION(when_the_wait_on_address_timesout_InterlockedHL_WaitForNotValue_also_timesout)
|
||||
{
|
||||
// arrange
|
||||
|
@ -545,9 +680,132 @@ TEST_FUNCTION(when_the_wait_on_address_timesout_InterlockedHL_WaitForNotValue_al
|
|||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_TIMEOUT, result);
|
||||
}
|
||||
|
||||
/* InterlockedHL_WaitForNotValue64 */
|
||||
|
||||
/* Tests_SRS_INTERLOCKED_HL_05_007: [ If address_to_check is NULL, InterlockedHL_WaitForNotValue64 shall fail and return INTERLOCKED_HL_ERROR. ] */
|
||||
TEST_FUNCTION(InterlockedHL_WaitForNotValue64_with_NULL_address_fails)
|
||||
{
|
||||
// arrange
|
||||
INTERLOCKED_HL_RESULT result;
|
||||
|
||||
// act
|
||||
result = InterlockedHL_WaitForNotValue64(NULL, 0x42, UINT32_MAX);
|
||||
|
||||
// assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_ERROR, result);
|
||||
}
|
||||
|
||||
/* Tests_SRS_INTERLOCKED_HL_05_008: [ If the value at address_to_check is not equal to value_to_wait, InterlockedHL_WaitForNotValue64 shall return INTERLOCKED_HL_OK. ] */
|
||||
TEST_FUNCTION(when_the_value_does_not_equal_target_value_InterlockedHL_WaitForNotValue64_returns_OK)
|
||||
{
|
||||
// arrange
|
||||
INTERLOCKED_HL_RESULT result;
|
||||
volatile_atomic int64_t value = 0x43;
|
||||
|
||||
STRICT_EXPECTED_CALL(interlocked_add_64(&value, 0));
|
||||
|
||||
// act
|
||||
result = InterlockedHL_WaitForNotValue64(&value, 0x42, UINT32_MAX);
|
||||
|
||||
// assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_OK, result);
|
||||
}
|
||||
|
||||
/* Tests_SRS_INTERLOCKED_HL_05_009: [ If the value at address_to_check is equal to value_to_wait, InterlockedHL_WaitForNotValue64 shall wait until the value at address_to_check changes using wait_on_address_64. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_05_010: [ When wait_on_address_64 succeeds, InterlockedHL_WaitForNotValue64 shall again compare the value at address_to_check with value_to_wait. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_05_008: [ If the value at address_to_check is not equal to value_to_wait, InterlockedHL_WaitForNotValue64 shall return INTERLOCKED_HL_OK. ] */
|
||||
TEST_FUNCTION(when_the_value_does_not_equal_target_value_after_waiting_InterlockedHL_WaitForNotValue64_returns_OK)
|
||||
{
|
||||
// arrange
|
||||
INTERLOCKED_HL_RESULT result;
|
||||
volatile_atomic int64_t value = 0x42;
|
||||
int64_t changed_value = 0x41;
|
||||
|
||||
STRICT_EXPECTED_CALL(interlocked_add_64(&value, 0));
|
||||
STRICT_EXPECTED_CALL(wait_on_address_64(&value, IGNORED_ARG, UINT32_MAX))
|
||||
.CopyOutArgumentBuffer_address(&changed_value, sizeof(changed_value));
|
||||
STRICT_EXPECTED_CALL(interlocked_add_64(&value, 0));
|
||||
|
||||
// act
|
||||
result = InterlockedHL_WaitForNotValue64(&value, 0x42, UINT32_MAX);
|
||||
|
||||
// assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_OK, result);
|
||||
}
|
||||
|
||||
/* Tests_SRS_INTERLOCKED_HL_05_009: [ If the value at address_to_check is equal to value_to_wait, InterlockedHL_WaitForNotValue64 shall wait until the value at address_to_check changes using wait_on_address_64. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_05_010: [ When wait_on_address_64 succeeds, InterlockedHL_WaitForNotValue64 shall again compare the value at address_to_check with value_to_wait. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_05_008: [ If the value at address_to_check is not equal to value_to_wait, InterlockedHL_WaitForNotValue64 shall return INTERLOCKED_HL_OK. ] */
|
||||
TEST_FUNCTION(when_the_value_after_a_succesfull_wait_on_address_64_equals_target_a_new_wait_for_address_64_shall_be_issued)
|
||||
{
|
||||
// arrange
|
||||
INTERLOCKED_HL_RESULT result;
|
||||
volatile_atomic int64_t value = 0x42;
|
||||
int64_t intermediate_value = 0x42;
|
||||
int64_t final_value = 0x41;
|
||||
|
||||
STRICT_EXPECTED_CALL(interlocked_add_64(&value, 0));
|
||||
STRICT_EXPECTED_CALL(wait_on_address_64(&value, IGNORED_ARG, UINT32_MAX))
|
||||
.CopyOutArgumentBuffer_address(&intermediate_value, sizeof(int64_t));
|
||||
STRICT_EXPECTED_CALL(interlocked_add_64(&value, 0));
|
||||
STRICT_EXPECTED_CALL(wait_on_address_64(&value, IGNORED_ARG, UINT32_MAX))
|
||||
.CopyOutArgumentBuffer_address(&final_value, sizeof(int64_t));
|
||||
STRICT_EXPECTED_CALL(interlocked_add_64(&value, 0));
|
||||
|
||||
// act
|
||||
result = InterlockedHL_WaitForNotValue64(&value, 0x42, UINT32_MAX);
|
||||
|
||||
// assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_OK, result);
|
||||
}
|
||||
|
||||
/* Tests_SRS_INTERLOCKED_HL_05_009: [ If the value at address_to_check is equal to value_to_wait, InterlockedHL_WaitForNotValue64 shall wait until the value at address_to_check changes using wait_on_address_64. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_05_012: [ If wait_on_address_64 fails, InterlockedHL_WaitForNotValue64 shall fail and return INTERLOCKED_HL_ERROR. ] */
|
||||
TEST_FUNCTION(when_the_wait_on_address_64_fails_InterlockedHL_WaitForNotValue64_also_fails)
|
||||
{
|
||||
// arrange
|
||||
INTERLOCKED_HL_RESULT result;
|
||||
volatile_atomic int64_t value = 0x42;
|
||||
|
||||
STRICT_EXPECTED_CALL(interlocked_add_64(&value, 0));
|
||||
STRICT_EXPECTED_CALL(wait_on_address_64(&value, IGNORED_ARG, UINT32_MAX))
|
||||
.SetReturn(WAIT_ON_ADDRESS_ERROR);
|
||||
|
||||
// act
|
||||
result = InterlockedHL_WaitForNotValue64(&value, 0x42, UINT32_MAX);
|
||||
|
||||
// assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_ERROR, result);
|
||||
}
|
||||
|
||||
/* Tests_SRS_INTERLOCKED_HL_05_009: [ If the value at address_to_check is equal to value_to_wait, InterlockedHL_WaitForNotValue64 shall wait until the value at address_to_check changes using wait_on_address_64. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_05_011: [ If wait_on_address_64 hits the timeout specified in timeout_ms, InterlockedHL_WaitForNotValue64 shall fail and return INTERLOCKED_HL_TIMEOUT. ] */
|
||||
TEST_FUNCTION(when_the_wait_on_address_64_timesout_InterlockedHL_WaitForNotValue64_also_timesout)
|
||||
{
|
||||
// arrange
|
||||
INTERLOCKED_HL_RESULT result;
|
||||
volatile_atomic int64_t value = 0x42;
|
||||
|
||||
STRICT_EXPECTED_CALL(interlocked_add_64(&value, 0));
|
||||
STRICT_EXPECTED_CALL(wait_on_address_64(&value, IGNORED_ARG, UINT32_MAX))
|
||||
.SetReturn(WAIT_ON_ADDRESS_TIMEOUT);
|
||||
|
||||
// act
|
||||
result = InterlockedHL_WaitForNotValue64(&value, 0x42, UINT32_MAX);
|
||||
|
||||
// assert
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_TIMEOUT, result);
|
||||
}
|
||||
|
||||
/* InterlockedHL_CompareExchangeIf */
|
||||
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_009: [ If target is NULL then InterlockedHL_CompareExchangeIf shall return fail and return INTERLOCKED_HL_ERROR. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_009: [ If target is NULL then InterlockedHL_CompareExchangeIf shall return fail and return INTERLOCKED_HL_ERROR. ] */
|
||||
TEST_FUNCTION(InterlockedHL_CompareExchangeIf_with_target_NULL_fails)
|
||||
{
|
||||
///arrange
|
||||
|
@ -563,7 +821,7 @@ TEST_FUNCTION(InterlockedHL_CompareExchangeIf_with_target_NULL_fails)
|
|||
///clean
|
||||
}
|
||||
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_010: [ If compare is NULL then InterlockedHL_CompareExchangeIf shall return fail and return INTERLOCKED_HL_ERROR. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_010: [ If compare is NULL then InterlockedHL_CompareExchangeIf shall return fail and return INTERLOCKED_HL_ERROR. ] */
|
||||
TEST_FUNCTION(InterlockedHL_CompareExchangeIf_with_compare_NULL_fails)
|
||||
{
|
||||
///arrange
|
||||
|
@ -582,7 +840,7 @@ TEST_FUNCTION(InterlockedHL_CompareExchangeIf_with_compare_NULL_fails)
|
|||
///clean
|
||||
}
|
||||
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_011: [ If original_target is NULL then InterlockedHL_CompareExchangeIf shall return fail and return INTERLOCKED_HL_ERROR. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_011: [ If original_target is NULL then InterlockedHL_CompareExchangeIf shall return fail and return INTERLOCKED_HL_ERROR. ] */
|
||||
TEST_FUNCTION(InterlockedHL_CompareExchangeIf_with_original_target_NULL_fails)
|
||||
{
|
||||
///arrange
|
||||
|
@ -601,10 +859,10 @@ TEST_FUNCTION(InterlockedHL_CompareExchangeIf_with_original_target_NULL_fails)
|
|||
///clean
|
||||
}
|
||||
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_012: [ InterlockedHL_CompareExchangeIf shall acquire the initial value of target. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_013: [ If compare(target, exchange) returns true then InterlockedHL_CompareExchangeIf shall exchange target with exchange. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_015: [ If target did not change meanwhile then InterlockedHL_CompareExchangeIf shall return INTERLOCKED_HL_OK and shall peform the exchange of values. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_016: [ original_target shall be set to the original value of target. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_012: [ InterlockedHL_CompareExchangeIf shall acquire the initial value of target. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_013: [ If compare(target, exchange) returns true then InterlockedHL_CompareExchangeIf shall exchange target with exchange. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_015: [ If target did not change meanwhile then InterlockedHL_CompareExchangeIf shall return INTERLOCKED_HL_OK and shall peform the exchange of values. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_016: [ original_target shall be set to the original value of target. ] */
|
||||
TEST_FUNCTION(InterlockedHL_CompareExchangeIf_with_compare_true_changed_false_succeeds)
|
||||
{
|
||||
///arrange
|
||||
|
@ -630,10 +888,10 @@ TEST_FUNCTION(InterlockedHL_CompareExchangeIf_with_compare_true_changed_false_su
|
|||
///clean
|
||||
}
|
||||
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_012: [ InterlockedHL_CompareExchangeIf shall acquire the initial value of target. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_013: [ If compare(target, exchange) returns true then InterlockedHL_CompareExchangeIf shall exchange target with exchange. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_014: [ If target changed meanwhile then InterlockedHL_CompareExchangeIf shall return INTERLOCKED_HL_CHANGED and shall not peform any exchange of values. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_016: [ original_target shall be set to the original value of target. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_012: [ InterlockedHL_CompareExchangeIf shall acquire the initial value of target. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_013: [ If compare(target, exchange) returns true then InterlockedHL_CompareExchangeIf shall exchange target with exchange. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_014: [ If target changed meanwhile then InterlockedHL_CompareExchangeIf shall return INTERLOCKED_HL_CHANGED and shall not peform any exchange of values. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_016: [ original_target shall be set to the original value of target. ] */
|
||||
TEST_FUNCTION(InterlockedHL_CompareExchangeIf_with_compare_true_changed_true_succeeds)
|
||||
{
|
||||
///arrange
|
||||
|
@ -659,9 +917,9 @@ TEST_FUNCTION(InterlockedHL_CompareExchangeIf_with_compare_true_changed_true_suc
|
|||
///clean
|
||||
}
|
||||
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_012: [ InterlockedHL_CompareExchangeIf shall acquire the initial value of target. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_017: [ If compare returns false then InterlockedHL_CompareExchangeIf shall not perform any exchanges and return INTERLOCKED_HL_OK. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_016: [ original_target shall be set to the original value of target. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_012: [ InterlockedHL_CompareExchangeIf shall acquire the initial value of target. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_017: [ If compare returns false then InterlockedHL_CompareExchangeIf shall not perform any exchanges and return INTERLOCKED_HL_OK. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_01_016: [ original_target shall be set to the original value of target. ] */
|
||||
TEST_FUNCTION(InterlockedHL_CompareExchangeIf_with_compare_false_succeeds)
|
||||
{
|
||||
///arrange
|
||||
|
@ -688,7 +946,7 @@ TEST_FUNCTION(InterlockedHL_CompareExchangeIf_with_compare_false_succeeds)
|
|||
|
||||
/* InterlockedHL_CompareExchange64If */
|
||||
|
||||
/*Tests_SRS_INTERLOCKED_HL_02_008: [ If target is NULL then InterlockedHL_CompareExchange64If shall return fail and return INTERLOCKED_HL_ERROR. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_02_008: [ If target is NULL then InterlockedHL_CompareExchange64If shall return fail and return INTERLOCKED_HL_ERROR. ] */
|
||||
TEST_FUNCTION(InterlockedHL_CompareExchange64If_with_target_NULL_fails)
|
||||
{
|
||||
///arrange
|
||||
|
@ -704,7 +962,7 @@ TEST_FUNCTION(InterlockedHL_CompareExchange64If_with_target_NULL_fails)
|
|||
///clean
|
||||
}
|
||||
|
||||
/*Tests_SRS_INTERLOCKED_HL_02_009: [ If compare is NULL then InterlockedHL_CompareExchange64If shall return fail and return INTERLOCKED_HL_ERROR. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_02_009: [ If compare is NULL then InterlockedHL_CompareExchange64If shall return fail and return INTERLOCKED_HL_ERROR. ] */
|
||||
TEST_FUNCTION(InterlockedHL_CompareExchange64If_with_compare_NULL_fails)
|
||||
{
|
||||
///arrange
|
||||
|
@ -723,7 +981,7 @@ TEST_FUNCTION(InterlockedHL_CompareExchange64If_with_compare_NULL_fails)
|
|||
///clean
|
||||
}
|
||||
|
||||
/*Tests_SRS_INTERLOCKED_HL_02_010: [ If original_target is NULL then InterlockedHL_CompareExchange64If shall return fail and return INTERLOCKED_HL_ERROR. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_02_010: [ If original_target is NULL then InterlockedHL_CompareExchange64If shall return fail and return INTERLOCKED_HL_ERROR. ] */
|
||||
TEST_FUNCTION(InterlockedHL_CompareExchange64If_with_original_target_NULL_fails)
|
||||
{
|
||||
///arrange
|
||||
|
@ -742,10 +1000,10 @@ TEST_FUNCTION(InterlockedHL_CompareExchange64If_with_original_target_NULL_fails)
|
|||
///clean
|
||||
}
|
||||
|
||||
/*Tests_SRS_INTERLOCKED_HL_02_011: [ InterlockedHL_CompareExchange64If shall acquire the initial value of target. ]*/
|
||||
/*Tests_SRS_INTERLOCKED_HL_02_012: [ If compare(target, exchange) returns true then InterlockedHL_CompareExchange64If shall exchange target with exchange. ]*/
|
||||
/*Tests_SRS_INTERLOCKED_HL_02_014: [ If target did not change meanwhile then InterlockedHL_CompareExchange64If shall return INTERLOCKED_HL_OK and shall peform the exchange of values. ]*/
|
||||
/*Tests_SRS_INTERLOCKED_HL_02_016: [ original_target shall be set to the original value of target. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_02_011: [ InterlockedHL_CompareExchange64If shall acquire the initial value of target. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_02_012: [ If compare(target, exchange) returns true then InterlockedHL_CompareExchange64If shall exchange target with exchange. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_02_014: [ If target did not change meanwhile then InterlockedHL_CompareExchange64If shall return INTERLOCKED_HL_OK and shall peform the exchange of values. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_02_016: [ original_target shall be set to the original value of target. ] */
|
||||
TEST_FUNCTION(InterlockedHL_CompareExchange64If_with_compare_true_changed_false_succeeds)
|
||||
{
|
||||
///arrange
|
||||
|
@ -771,10 +1029,10 @@ TEST_FUNCTION(InterlockedHL_CompareExchange64If_with_compare_true_changed_false_
|
|||
///clean
|
||||
}
|
||||
|
||||
/*Tests_SRS_INTERLOCKED_HL_02_011: [ InterlockedHL_CompareExchange64If shall acquire the initial value of target. ]*/
|
||||
/*Tests_SRS_INTERLOCKED_HL_02_012: [ If compare(target, exchange) returns true then InterlockedHL_CompareExchange64If shall exchange target with exchange. ]*/
|
||||
/*Tests_SRS_INTERLOCKED_HL_02_013: [ If target changed meanwhile then InterlockedHL_CompareExchange64If shall return INTERLOCKED_HL_CHANGED and shall not peform any exchange of values. ]*/
|
||||
/*Tests_SRS_INTERLOCKED_HL_02_016: [ original_target shall be set to the original value of target. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_02_011: [ InterlockedHL_CompareExchange64If shall acquire the initial value of target. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_02_012: [ If compare(target, exchange) returns true then InterlockedHL_CompareExchange64If shall exchange target with exchange. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_02_013: [ If target changed meanwhile then InterlockedHL_CompareExchange64If shall return INTERLOCKED_HL_CHANGED and shall not peform any exchange of values. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_02_016: [ original_target shall be set to the original value of target. ] */
|
||||
TEST_FUNCTION(InterlockedHL_CompareExchange64If_with_compare_true_changed_true_succeeds)
|
||||
{
|
||||
///arrange
|
||||
|
@ -800,10 +1058,10 @@ TEST_FUNCTION(InterlockedHL_CompareExchange64If_with_compare_true_changed_true_s
|
|||
///clean
|
||||
}
|
||||
|
||||
/*Tests_SRS_INTERLOCKED_HL_02_011: [ InterlockedHL_CompareExchange64If shall acquire the initial value of target. ]*/
|
||||
/*Tests_SRS_INTERLOCKED_HL_02_015: [ If compare returns false then InterlockedHL_CompareExchange64If shall not perform any exchanges and return INTERLOCKED_HL_OK. ]*/
|
||||
/*Tests_SRS_INTERLOCKED_HL_02_013: [ If target changed meanwhile then InterlockedHL_CompareExchange64If shall return INTERLOCKED_HL_CHANGED and shall not peform any exchange of values. ]*/
|
||||
/*Tests_SRS_INTERLOCKED_HL_02_016: [ original_target shall be set to the original value of target. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_02_011: [ InterlockedHL_CompareExchange64If shall acquire the initial value of target. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_02_015: [ If compare returns false then InterlockedHL_CompareExchange64If shall not perform any exchanges and return INTERLOCKED_HL_OK. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_02_013: [ If target changed meanwhile then InterlockedHL_CompareExchange64If shall return INTERLOCKED_HL_CHANGED and shall not peform any exchange of values. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_02_016: [ original_target shall be set to the original value of target. ] */
|
||||
TEST_FUNCTION(InterlockedHL_CompareExchange64If_with_compare_false_succeeds)
|
||||
{
|
||||
///arrange
|
||||
|
@ -828,10 +1086,10 @@ TEST_FUNCTION(InterlockedHL_CompareExchange64If_with_compare_false_succeeds)
|
|||
///clean
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
/* InterlockedHL_SetAndWake */
|
||||
|
||||
/*Tests_SRS_INTERLOCKED_HL_02_020: [ If address is NULL then InterlockedHL_SetAndWake shall fail and return INTERLOCKED_HL_ERROR. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_02_020: [ If address is NULL then InterlockedHL_SetAndWake shall fail and return INTERLOCKED_HL_ERROR. ] */
|
||||
TEST_FUNCTION(InterlockedHL_SetAndWake_with_address_NULL_fails)
|
||||
{
|
||||
///arrange
|
||||
|
@ -844,9 +1102,9 @@ TEST_FUNCTION(InterlockedHL_SetAndWake_with_address_NULL_fails)
|
|||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_ERROR, result);
|
||||
}
|
||||
|
||||
/*Tests_SRS_INTERLOCKED_HL_02_017: [ InterlockedHL_SetAndWake shall set address to value. ]*/
|
||||
/*Tests_SRS_INTERLOCKED_HL_02_018: [ InterlockedHL_SetAndWake shall call wake_by_address_single. ]*/
|
||||
/*Tests_SRS_INTERLOCKED_HL_02_019: [ InterlockedHL_SetAndWake shall succeed and return INTERLOCKED_HL_OK. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_02_017: [ InterlockedHL_SetAndWake shall set address to value. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_02_018: [ InterlockedHL_SetAndWake shall call wake_by_address_single. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_02_019: [ InterlockedHL_SetAndWake shall succeed and return INTERLOCKED_HL_OK. ] */
|
||||
TEST_FUNCTION(InterlockedHL_SetAndWake_succeeds)
|
||||
{
|
||||
///arrange
|
||||
|
@ -864,7 +1122,44 @@ TEST_FUNCTION(InterlockedHL_SetAndWake_succeeds)
|
|||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_OK, result);
|
||||
}
|
||||
|
||||
/*Tests_SRS_INTERLOCKED_HL_02_028: [ If address is NULL then InterlockedHL_SetAndWakeAll shall fail and return INTERLOCKED_HL_ERROR. ]*/
|
||||
/* InterlockedHL_SetAndWake64 */
|
||||
|
||||
/* Tests_SRS_INTERLOCKED_HL_05_013: [ If address is NULL then InterlockedHL_SetAndWake64 shall fail and return INTERLOCKED_HL_ERROR. ] */
|
||||
TEST_FUNCTION(InterlockedHL_SetAndWake64_with_address_NULL_fails)
|
||||
{
|
||||
///arrange
|
||||
INTERLOCKED_HL_RESULT result;
|
||||
|
||||
///act
|
||||
result = InterlockedHL_SetAndWake64(NULL, 3);
|
||||
|
||||
///assert
|
||||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_ERROR, result);
|
||||
}
|
||||
|
||||
/* Tests_SRS_INTERLOCKED_HL_05_014: [ InterlockedHL_SetAndWake64 shall set value at address. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_05_015: [ InterlockedHL_SetAndWake64 shall wake a single thread listening on address. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_05_016: [ InterlockedHL_SetAndWake64 shall succeed and return INTERLOCKED_HL_OK. ] */
|
||||
TEST_FUNCTION(InterlockedHL_SetAndWake64_succeeds)
|
||||
{
|
||||
///arrange
|
||||
volatile_atomic int64_t hereLiesAThree = 3;
|
||||
int64_t thatIsGoingToTurn4 = 4;
|
||||
INTERLOCKED_HL_RESULT result;
|
||||
|
||||
STRICT_EXPECTED_CALL(interlocked_exchange_64(&hereLiesAThree, thatIsGoingToTurn4));
|
||||
STRICT_EXPECTED_CALL(wake_by_address_single_64(&hereLiesAThree));
|
||||
|
||||
///act
|
||||
result = InterlockedHL_SetAndWake64(&hereLiesAThree, thatIsGoingToTurn4);
|
||||
|
||||
///assert
|
||||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_OK, result);
|
||||
}
|
||||
|
||||
/* InterlockedHL_SetAndWakeAll */
|
||||
|
||||
/* Tests_SRS_INTERLOCKED_HL_02_028: [ If address is NULL then InterlockedHL_SetAndWakeAll shall fail and return INTERLOCKED_HL_ERROR. ] */
|
||||
TEST_FUNCTION(InterlockedHL_SetAndWakeAll_with_address_NULL_fails)
|
||||
{
|
||||
///arrange
|
||||
|
@ -877,9 +1172,9 @@ TEST_FUNCTION(InterlockedHL_SetAndWakeAll_with_address_NULL_fails)
|
|||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_ERROR, result);
|
||||
}
|
||||
|
||||
/*Tests_SRS_INTERLOCKED_HL_02_029: [ InterlockedHL_SetAndWakeAll shall set address to value. ]*/
|
||||
/*Tests_SRS_INTERLOCKED_HL_02_030: [ InterlockedHL_SetAndWakeAll shall call wake_by_address_all. ]*/
|
||||
/*Tests_SRS_INTERLOCKED_HL_02_031: [ InterlockedHL_SetAndWakeAll shall succeed and return INTERLOCKED_HL_OK. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_02_029: [ InterlockedHL_SetAndWakeAll shall set address to value. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_02_030: [ InterlockedHL_SetAndWakeAll shall call wake_by_address_all. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_02_031: [ InterlockedHL_SetAndWakeAll shall succeed and return INTERLOCKED_HL_OK. ] */
|
||||
TEST_FUNCTION(InterlockedHL_SetAndWakeAll_succeeds)
|
||||
{
|
||||
///arrange
|
||||
|
@ -896,11 +1191,45 @@ TEST_FUNCTION(InterlockedHL_SetAndWakeAll_succeeds)
|
|||
///assert
|
||||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_OK, result);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* InterlockedHL_SetAndWakeAll64 */
|
||||
|
||||
/* Tests_SRS_INTERLOCKED_HL_05_017: [ If address is NULL then InterlockedHL_SetAndWakeAll64 shall fail and return INTERLOCKED_HL_ERROR. ] */
|
||||
TEST_FUNCTION(InterlockedHL_SetAndWakeAll64_with_address_NULL_fails)
|
||||
{
|
||||
///arrange
|
||||
INTERLOCKED_HL_RESULT result;
|
||||
|
||||
///act
|
||||
result = InterlockedHL_SetAndWakeAll64(NULL, 3);
|
||||
|
||||
///assert
|
||||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_ERROR, result);
|
||||
}
|
||||
|
||||
/* Tests_SRS_INTERLOCKED_HL_05_018: [ InterlockedHL_SetAndWakeAll64 shall set value at address. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_05_019: [ InterlockedHL_SetAndWakeAll64 shall wake all threads listening on address. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_05_020: [ InterlockedHL_SetAndWakeAll64 shall succeed and return INTERLOCKED_HL_OK. ] */
|
||||
TEST_FUNCTION(InterlockedHL_SetAndWakeAll64_succeeds)
|
||||
{
|
||||
///arrange
|
||||
volatile_atomic int64_t hereLiesAThree = 3;
|
||||
int64_t thatIsGoingToTurn4 = 4;
|
||||
INTERLOCKED_HL_RESULT result;
|
||||
|
||||
STRICT_EXPECTED_CALL(interlocked_exchange_64(&hereLiesAThree, thatIsGoingToTurn4));
|
||||
STRICT_EXPECTED_CALL(wake_by_address_all_64(&hereLiesAThree));
|
||||
|
||||
///act
|
||||
result = InterlockedHL_SetAndWakeAll64(&hereLiesAThree, thatIsGoingToTurn4);
|
||||
|
||||
///assert
|
||||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_OK, result);
|
||||
}
|
||||
|
||||
/* InterlockedHL_DecrementAndWake */
|
||||
|
||||
/*Tests_SRS_INTERLOCKED_HL_44_001: [ If address is NULL then InterlockedHL_DecrementAndWake shall fail and return INTERLOCKED_HL_ERROR. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_44_001: [ If address is NULL then InterlockedHL_DecrementAndWake shall fail and return INTERLOCKED_HL_ERROR. ] */
|
||||
TEST_FUNCTION(InterlockedHL_DecrementAndWake_with_NULL_address_fails)
|
||||
{
|
||||
// arrange
|
||||
|
@ -913,9 +1242,9 @@ TEST_FUNCTION(InterlockedHL_DecrementAndWake_with_NULL_address_fails)
|
|||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_ERROR, result);
|
||||
}
|
||||
|
||||
/*Tests_SRS_INTERLOCKED_HL_44_002: [ InterlockedHL_DecrementAndWake shall decrement the value at address by 1. ]*/
|
||||
/*Tests_SRS_INTERLOCKED_HL_44_003: [ InterlockedHL_DecrementAndWake shall call wake_by_address_single. ]*/
|
||||
/*Tests_SRS_INTERLOCKED_HL_44_004: [ InterlockedHL_DecrementAndWake shall succeed and return INTERLOCKED_HL_OK. ]*/
|
||||
/* Tests_SRS_INTERLOCKED_HL_44_002: [ InterlockedHL_DecrementAndWake shall decrement the value at address by 1. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_44_003: [ InterlockedHL_DecrementAndWake shall call wake_by_address_single. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_44_004: [ InterlockedHL_DecrementAndWake shall succeed and return INTERLOCKED_HL_OK. ] */
|
||||
TEST_FUNCTION(InterlockedHL_DecrementAndWake_with_Valid_Inputs_success)
|
||||
{
|
||||
///arrange
|
||||
|
@ -950,4 +1279,57 @@ TEST_FUNCTION(InterlockedHL_DecrementAndWake_with_Valid_Inputs_success)
|
|||
}
|
||||
}
|
||||
|
||||
/* InterlockedHL_DecrementAndWake64 */
|
||||
|
||||
/* Tests_SRS_INTERLOCKED_HL_05_021: [ If address is NULL then InterlockedHL_DecrementAndWake64 shall fail and return INTERLOCKED_HL_ERROR. ] */
|
||||
TEST_FUNCTION(InterlockedHL_DecrementAndWake64_with_NULL_address_fails)
|
||||
{
|
||||
// arrange
|
||||
INTERLOCKED_HL_RESULT result;
|
||||
|
||||
// act
|
||||
result = InterlockedHL_DecrementAndWake64(NULL);
|
||||
|
||||
// assert
|
||||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_ERROR, result);
|
||||
}
|
||||
|
||||
/* Tests_SRS_INTERLOCKED_HL_05_022: [ InterlockedHL_DecrementAndWake64 shall decrement the value at address by 1. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_05_023: [ InterlockedHL_DecrementAndWake64 shall wake a single thread listening on address. ] */
|
||||
/* Tests_SRS_INTERLOCKED_HL_05_024: [ InterlockedHL_DecrementAndWake64 shall succeed and return INTERLOCKED_HL_OK. ] */
|
||||
TEST_FUNCTION(InterlockedHL_DecrementAndWake64_with_Valid_Inputs_success)
|
||||
{
|
||||
///arrange
|
||||
INPUT_AND_OUTPUT_64 testCases[] =
|
||||
{
|
||||
/*Input*/ /*Output*/
|
||||
{ INT64_MAX, INT64_MAX - 1},
|
||||
{ INT64_MAX - 1, INT64_MAX - 2},
|
||||
{ INT64_MIN, INT64_MAX},
|
||||
{ INT64_MIN + 1, INT64_MIN},
|
||||
{ -1, -2 },
|
||||
{ 0, -1} ,
|
||||
{ 1, 0},
|
||||
{ 1024, 1023 },
|
||||
{ -1024, -1025 },
|
||||
};
|
||||
size_t nTestCases = sizeof(testCases) / sizeof(testCases[0]);
|
||||
for (size_t i = 0; i < nTestCases; i++)
|
||||
{
|
||||
///arrange
|
||||
umock_c_reset_all_calls();
|
||||
STRICT_EXPECTED_CALL(interlocked_decrement_64(&(testCases[i].Input)));
|
||||
STRICT_EXPECTED_CALL(wake_by_address_single_64(&(testCases[i].Input)));
|
||||
|
||||
///act
|
||||
INTERLOCKED_HL_RESULT result = InterlockedHL_DecrementAndWake64(&(testCases[i].Input));
|
||||
|
||||
///assert
|
||||
ASSERT_ARE_EQUAL(INTERLOCKED_HL_RESULT, INTERLOCKED_HL_OK, result);
|
||||
ASSERT_ARE_EQUAL(int64_t, testCases[i].Output, testCases[i].Input);
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
END_TEST_SUITE(TEST_SUITE_NAME_FROM_CMAKE)
|
||||
|
|
|
@ -14,11 +14,11 @@
|
|||
#include "umock_c/umock_c.h"
|
||||
#include "umock_c/umocktypes_stdint.h"
|
||||
#include "umock_c/umocktypes.h"
|
||||
// IWYU pragma: no_include "c_pal/ps_util.h"
|
||||
// IWYU pragma: no_include "c_pal/ps_util.h"
|
||||
#include "c_pal/interlocked.h"// IWYU pragma: keep
|
||||
|
||||
#define ENABLE_MOCKS
|
||||
#include "c_pal/gballoc_hl.h"
|
||||
#include "c_pal/gballoc_hl.h"
|
||||
#include "c_pal/gballoc_hl_redirect.h"
|
||||
#include "c_pal/interlocked_hl.h"
|
||||
#include "c_pal/log_critical_and_terminate.h" // IWYU pragma: keep
|
||||
|
|
Загрузка…
Ссылка в новой задаче