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:
Nishikant Deshmukh 2024-11-18 20:10:04 -08:00 коммит произвёл GitHub
Родитель 76da349891
Коммит 3434cf0416
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
19 изменённых файлов: 1659 добавлений и 423 удалений

Просмотреть файл

@ -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, &current_value=%p, milliseconds=%" PRIu32 ") result: %" PRI_MU_ENUM "",
address, &current_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, &current_value=%p, milliseconds=%" PRIu32 ") result: %" PRI_MU_ENUM "",
address, &current_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