Specs for interlocked and sync 64 (#411)

* Specs for interlocked and sync 64

* Specs for interlocked and sync 64 - Parth comments

* Mergeable specs

* Addressed Parth comments

* Address Dan's comments
This commit is contained in:
Nishikant Deshmukh 2024-11-15 15:40:39 -08:00 коммит произвёл GitHub
Родитель 9ee20f092c
Коммит 76da349891
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
3 изменённых файлов: 162 добавлений и 4 удалений

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

@ -8,8 +8,11 @@
```c
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);
```
## wait_on_address
@ -30,6 +33,24 @@ MOCKABLE_FUNCTION(, WAIT_ON_ADDRESS_RESULT, wait_on_address, volatile_atomic int
**SRS_SYNC_LINUX_43_004: [** Otherwise, `wait_on_address` shall return `WAIT_ON_ADDRESS_ERROR`.**]**
## wait_on_address_64
```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_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`. **]**
**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` . **]**
**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`. **]**
**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`. **]**
**S_R_S_SYNC_LINUX_05_006: [** Otherwise, `wait_on_address_64` shall return `WAIT_ON_ADDRESS_ERROR`. **]**
## wake_by_address_all
```c
@ -38,6 +59,13 @@ 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`. **]**
## 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`. **]**
## wake_by_address_single
```c
@ -45,3 +73,11 @@ MOCKABLE_FUNCTION(, void, wake_by_address_single, volatile_atomic int32_t*, addr
```
**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`. **]**
## wake_by_address_single_64
```c
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`. **]**

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

@ -8,8 +8,11 @@
```c
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);
```
## wait_on_address
@ -18,7 +21,7 @@ MOCKABLE_FUNCTION(, void, wake_by_address_single, volatile_atomic int32_t*, addr
MOCKABLE_FUNCTION(, WAIT_ON_ADDRESS_RESULT, wait_on_address, volatile_atomic int32_t*, address, int32_t, compare_value, uint32_t, timeout_ms)
```
**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`. **]**
**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. **]**
**SRS_SYNC_WIN32_24_001: [** If `WaitOnAddress` fails due to timeout, `wait_on_address` shall fail and return `WAIT_ON_ADDRESS_TIMEOUT`. **]**
@ -26,12 +29,32 @@ MOCKABLE_FUNCTION(, WAIT_ON_ADDRESS_RESULT, wait_on_address, volatile_atomic int
**SRS_SYNC_WIN32_24_003: [** If `WaitOnAddress` succeeds, `wait_on_address` shall return `WAIT_ON_ADDRESS_OK`. **]**
## wait_on_address_64
```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`. **]**
**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`. **]**
**S_R_S_SYNC_WIN32_05_004: [** If `WaitOnAddress` succeeds, `wait_on_address` 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` from `windows.h` with `address` as `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
```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`. **]**
## wake_by_address_single
@ -39,4 +62,10 @@ MOCKABLE_FUNCTION(, void, wake_by_address_all, volatile_atomic int32_t*, address
MOCKABLE_FUNCTION(, void, wake_by_address_single, volatile_atomic int32_t*, address)
```
**SRS_SYNC_WIN32_43_004: [** `wake_by_address_single` shall call `WakeByAddressSingle` from `windows.h` with `address` as `Address`. **]**
**SRS_SYNC_WIN32_43_004: [** `wake_by_address_single` shall call `WakeByAddressSingle` 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`. **]**

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

@ -19,11 +19,17 @@ 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_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, int32_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, int64_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_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_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);
```
### InterlockedHL_Add64WithCeiling
@ -74,6 +80,27 @@ MOCKABLE_FUNCTION_WITH_RETURNS(, INTERLOCKED_HL_RESULT, InterlockedHL_WaitForVal
**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);
```
`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]
**S_R_S_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`. **]**
**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`. **]**
**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`. **]**
**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`. **]**
**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
@ -98,6 +125,27 @@ MOCKABLE_FUNCTION_WITH_RETURNS(, INTERLOCKED_HL_RESULT, InterlockedHL_WaitForNot
**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);
```
`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]
**S_R_S_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`. **]**
**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`. **]**
**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`. **]**
**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`. **]**
**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
MOCKABLE_FUNCTION_WITH_RETURNS(, INTERLOCKED_HL_RESULT, InterlockedHL_CompareExchangeIf, int32_t volatile_atomic*, target, int32_t, exchange, INTERLOCKED_COMPARE_EXCHANGE_32_IF, compare, int32_t*, original_target)(INTERLOCKED_HL_OK, INTERLOCKED_HL_ERROR);
@ -165,7 +213,22 @@ MOCKABLE_FUNCTION_WITH_RETURNS(, INTERLOCKED_HL_RESULT, InterlockedHL_SetAndWake
**SRS_INTERLOCKED_HL_02_019: [** `InterlockedHL_SetAndWake` shall succeed and return `INTERLOCKED_HL_OK`. **]**
### InterlockedHL_SetAndWake
### InterlockedHL_SetAndWake64
```c
MOCKABLE_FUNCTION_WITH_RETURNS(, INTERLOCKED_HL_RESULT, InterlockedHL_SetAndWake64, int64_t volatile_atomic*, address, int64_t, value)(INTERLOCKED_HL_OK, INTERLOCKED_HL_ERROR);
```
`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`. **]**
**S_R_S_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`. **]**
**S_R_S_INTERLOCKED_HL_05_016: [** `InterlockedHL_SetAndWake64` shall succeed and return `INTERLOCKED_HL_OK`. **]**
### InterlockedHL_SetAndWakeAll
```c
MOCKABLE_FUNCTION_WITH_RETURNS(, INTERLOCKED_HL_RESULT, InterlockedHL_SetAndWakeAll, int32_t volatile_atomic*, address, int32_t, value)(INTERLOCKED_HL_OK, INTERLOCKED_HL_ERROR);
```
@ -180,6 +243,21 @@ MOCKABLE_FUNCTION_WITH_RETURNS(, INTERLOCKED_HL_RESULT, InterlockedHL_SetAndWake
**SRS_INTERLOCKED_HL_02_031: [** `InterlockedHL_SetAndWakeAll` shall succeed and return `INTERLOCKED_HL_OK`. **]**
### InterlockedHL_SetAndWakeAll64
```c
MOCKABLE_FUNCTION_WITH_RETURNS(, INTERLOCKED_HL_RESULT, InterlockedHL_SetAndWakeAll64, int64_t volatile_atomic*, address, int64_t, value)(INTERLOCKED_HL_OK, INTERLOCKED_HL_ERROR);
```
`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`. **]**
**S_R_S_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`. **]**
**S_R_S_INTERLOCKED_HL_05_020: [** `InterlockedHL_SetAndWakeAll64` shall succeed and return `INTERLOCKED_HL_OK`. **]**
### InterlockedHL_DecrementAndWake
```c
MOCKABLE_FUNCTION_WITH_RETURNS(, INTERLOCKED_HL_RESULT, InterlockedHL_DecrementAndWake, int32_t volatile_atomic*, address)(INTERLOCKED_HL_OK, INTERLOCKED_HL_ERROR);
@ -194,3 +272,18 @@ MOCKABLE_FUNCTION_WITH_RETURNS(, INTERLOCKED_HL_RESULT, InterlockedHL_DecrementA
**SRS_INTERLOCKED_HL_44_003: [** `InterlockedHL_DecrementAndWake` shall call `wake_by_address_single`. **]**
**SRS_INTERLOCKED_HL_44_004: [** `InterlockedHL_DecrementAndWake` shall succeed and return `INTERLOCKED_HL_OK`. **]**
### InterlockedHL_DecrementAndWake64
```c
MOCKABLE_FUNCTION_WITH_RETURNS(, INTERLOCKED_HL_RESULT, InterlockedHL_DecrementAndWake64, int64_t_ volatile_atomic*, address)(INTERLOCKED_HL_OK, INTERLOCKED_HL_ERROR);
```
`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`. **]**
**S_R_S_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`. **]**
**S_R_S_INTERLOCKED_HL_05_024: [** `InterlockedHL_DecrementAndWake64` shall succeed and return `INTERLOCKED_HL_OK`. **]**