diff --git a/Sources/CNIOAtomics/include/CNIOAtomics.h b/Sources/CNIOAtomics/include/CNIOAtomics.h index 038d24a9..6cd3058a 100644 --- a/Sources/CNIOAtomics/include/CNIOAtomics.h +++ b/Sources/CNIOAtomics/include/CNIOAtomics.h @@ -2,7 +2,7 @@ // // This source file is part of the SwiftNIO open source project // -// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Copyright (c) 2017-2019 Apple Inc. and the SwiftNIO project authors // Licensed under Apache License v2.0 // // See LICENSE.txt for license information @@ -231,3 +231,267 @@ uint_least64_t catmc_atomic_uint_least64_t_sub(struct catmc_atomic_uint_least64_ uint_least64_t catmc_atomic_uint_least64_t_exchange(struct catmc_atomic_uint_least64_t * _Nonnull atomic, uint_least64_t value); uint_least64_t catmc_atomic_uint_least64_t_load(struct catmc_atomic_uint_least64_t * _Nonnull atomic); void catmc_atomic_uint_least64_t_store(struct catmc_atomic_uint_least64_t * _Nonnull atomic, uint_least64_t value); + +struct catmc_nio_atomic__Bool { + _Atomic _Bool value; +}; +void catmc_nio_atomic__Bool_create_with_existing_storage(struct catmc_nio_atomic__Bool * _Nonnull storage, bool value); +bool catmc_nio_atomic__Bool_compare_and_exchange(struct catmc_nio_atomic__Bool * _Nonnull atomic, bool expected, bool desired); +bool catmc_nio_atomic__Bool_add(struct catmc_nio_atomic__Bool * _Nonnull atomic, bool value); +bool catmc_nio_atomic__Bool_sub(struct catmc_nio_atomic__Bool * _Nonnull atomic, bool value); +bool catmc_nio_atomic__Bool_exchange(struct catmc_nio_atomic__Bool * _Nonnull atomic, bool value); +bool catmc_nio_atomic__Bool_load(struct catmc_nio_atomic__Bool * _Nonnull atomic); +void catmc_nio_atomic__Bool_store(struct catmc_nio_atomic__Bool * _Nonnull atomic, bool value); + +struct catmc_nio_atomic_char { + _Atomic char value; +}; +void catmc_nio_atomic_char_create_with_existing_storage(struct catmc_nio_atomic_char * _Nonnull storage, char value); +bool catmc_nio_atomic_char_compare_and_exchange(struct catmc_nio_atomic_char * _Nonnull atomic, char expected, char desired); +char catmc_nio_atomic_char_add(struct catmc_nio_atomic_char * _Nonnull atomic, char value); +char catmc_nio_atomic_char_sub(struct catmc_nio_atomic_char * _Nonnull atomic, char value); +char catmc_nio_atomic_char_exchange(struct catmc_nio_atomic_char * _Nonnull atomic, char value); +char catmc_nio_atomic_char_load(struct catmc_nio_atomic_char * _Nonnull atomic); +void catmc_nio_atomic_char_store(struct catmc_nio_atomic_char * _Nonnull atomic, char value); + +struct catmc_nio_atomic_short { + _Atomic short value; +}; +void catmc_nio_atomic_short_create_with_existing_storage(struct catmc_nio_atomic_short * _Nonnull storage, short value); +bool catmc_nio_atomic_short_compare_and_exchange(struct catmc_nio_atomic_short * _Nonnull atomic, short expected, short desired); +short catmc_nio_atomic_short_add(struct catmc_nio_atomic_short * _Nonnull atomic, short value); +short catmc_nio_atomic_short_sub(struct catmc_nio_atomic_short * _Nonnull atomic, short value); +short catmc_nio_atomic_short_exchange(struct catmc_nio_atomic_short * _Nonnull atomic, short value); +short catmc_nio_atomic_short_load(struct catmc_nio_atomic_short * _Nonnull atomic); +void catmc_nio_atomic_short_store(struct catmc_nio_atomic_short * _Nonnull atomic, short value); + +struct catmc_nio_atomic_int { + _Atomic int value; +}; +void catmc_nio_atomic_int_create_with_existing_storage(struct catmc_nio_atomic_int * _Nonnull storage, int value); +bool catmc_nio_atomic_int_compare_and_exchange(struct catmc_nio_atomic_int * _Nonnull atomic, int expected, int desired); +int catmc_nio_atomic_int_add(struct catmc_nio_atomic_int * _Nonnull atomic, int value); +int catmc_nio_atomic_int_sub(struct catmc_nio_atomic_int * _Nonnull atomic, int value); +int catmc_nio_atomic_int_exchange(struct catmc_nio_atomic_int * _Nonnull atomic, int value); +int catmc_nio_atomic_int_load(struct catmc_nio_atomic_int * _Nonnull atomic); +void catmc_nio_atomic_int_store(struct catmc_nio_atomic_int * _Nonnull atomic, int value); + +struct catmc_nio_atomic_long { + _Atomic long value; +}; +void catmc_nio_atomic_long_create_with_existing_storage(struct catmc_nio_atomic_long * _Nonnull storage, long value); +bool catmc_nio_atomic_long_compare_and_exchange(struct catmc_nio_atomic_long * _Nonnull atomic, long expected, long desired); +long catmc_nio_atomic_long_add(struct catmc_nio_atomic_long * _Nonnull atomic, long value); +long catmc_nio_atomic_long_sub(struct catmc_nio_atomic_long * _Nonnull atomic, long value); +long catmc_nio_atomic_long_exchange(struct catmc_nio_atomic_long * _Nonnull atomic, long value); +long catmc_nio_atomic_long_load(struct catmc_nio_atomic_long * _Nonnull atomic); +void catmc_nio_atomic_long_store(struct catmc_nio_atomic_long * _Nonnull atomic, long value); + +struct catmc_nio_atomic_long_long { + _Atomic long long value; +}; +void catmc_nio_atomic_long_long_create_with_existing_storage(struct catmc_nio_atomic_long_long * _Nonnull storage, long long value); +bool catmc_nio_atomic_long_long_compare_and_exchange(struct catmc_nio_atomic_long_long * _Nonnull atomic, long long expected, long long desired); +long long catmc_nio_atomic_long_long_add(struct catmc_nio_atomic_long_long * _Nonnull atomic, long long value); +long long catmc_nio_atomic_long_long_sub(struct catmc_nio_atomic_long_long * _Nonnull atomic, long long value); +long long catmc_nio_atomic_long_long_exchange(struct catmc_nio_atomic_long_long * _Nonnull atomic, long long value); +long long catmc_nio_atomic_long_long_load(struct catmc_nio_atomic_long_long * _Nonnull atomic); +void catmc_nio_atomic_long_long_store(struct catmc_nio_atomic_long_long * _Nonnull atomic, long long value); + +struct catmc_nio_atomic_signed_char { + _Atomic signed char value; +}; +void catmc_nio_atomic_signed_char_create_with_existing_storage(struct catmc_nio_atomic_signed_char * _Nonnull storage, signed char value); +bool catmc_nio_atomic_signed_char_compare_and_exchange(struct catmc_nio_atomic_signed_char * _Nonnull atomic, signed char expected, signed char desired); +signed char catmc_nio_atomic_signed_char_add(struct catmc_nio_atomic_signed_char * _Nonnull atomic, signed char value); +signed char catmc_nio_atomic_signed_char_sub(struct catmc_nio_atomic_signed_char * _Nonnull atomic, signed char value); +signed char catmc_nio_atomic_signed_char_exchange(struct catmc_nio_atomic_signed_char * _Nonnull atomic, signed char value); +signed char catmc_nio_atomic_signed_char_load(struct catmc_nio_atomic_signed_char * _Nonnull atomic); +void catmc_nio_atomic_signed_char_store(struct catmc_nio_atomic_signed_char * _Nonnull atomic, signed char value); + +struct catmc_nio_atomic_signed_short { + _Atomic signed short value; +}; +void catmc_nio_atomic_signed_short_create_with_existing_storage(struct catmc_nio_atomic_signed_short * _Nonnull storage, signed short value); +bool catmc_nio_atomic_signed_short_compare_and_exchange(struct catmc_nio_atomic_signed_short * _Nonnull atomic, signed short expected, signed short desired); +signed short catmc_nio_atomic_signed_short_add(struct catmc_nio_atomic_signed_short * _Nonnull atomic, signed short value); +signed short catmc_nio_atomic_signed_short_sub(struct catmc_nio_atomic_signed_short * _Nonnull atomic, signed short value); +signed short catmc_nio_atomic_signed_short_exchange(struct catmc_nio_atomic_signed_short * _Nonnull atomic, signed short value); +signed short catmc_nio_atomic_signed_short_load(struct catmc_nio_atomic_signed_short * _Nonnull atomic); +void catmc_nio_atomic_signed_short_store(struct catmc_nio_atomic_signed_short * _Nonnull atomic, signed short value); + +struct catmc_nio_atomic_signed_int { + _Atomic signed int value; +}; +void catmc_nio_atomic_signed_int_create_with_existing_storage(struct catmc_nio_atomic_signed_int * _Nonnull storage, signed int value); +bool catmc_nio_atomic_signed_int_compare_and_exchange(struct catmc_nio_atomic_signed_int * _Nonnull atomic, signed int expected, signed int desired); +signed int catmc_nio_atomic_signed_int_add(struct catmc_nio_atomic_signed_int * _Nonnull atomic, signed int value); +signed int catmc_nio_atomic_signed_int_sub(struct catmc_nio_atomic_signed_int * _Nonnull atomic, signed int value); +signed int catmc_nio_atomic_signed_int_exchange(struct catmc_nio_atomic_signed_int * _Nonnull atomic, signed int value); +signed int catmc_nio_atomic_signed_int_load(struct catmc_nio_atomic_signed_int * _Nonnull atomic); +void catmc_nio_atomic_signed_int_store(struct catmc_nio_atomic_signed_int * _Nonnull atomic, signed int value); + +struct catmc_nio_atomic_signed_long { + _Atomic signed long value; +}; +void catmc_nio_atomic_signed_long_create_with_existing_storage(struct catmc_nio_atomic_signed_long * _Nonnull storage, signed long value); +bool catmc_nio_atomic_signed_long_compare_and_exchange(struct catmc_nio_atomic_signed_long * _Nonnull atomic, signed long expected, signed long desired); +signed long catmc_nio_atomic_signed_long_add(struct catmc_nio_atomic_signed_long * _Nonnull atomic, signed long value); +signed long catmc_nio_atomic_signed_long_sub(struct catmc_nio_atomic_signed_long * _Nonnull atomic, signed long value); +signed long catmc_nio_atomic_signed_long_exchange(struct catmc_nio_atomic_signed_long * _Nonnull atomic, signed long value); +signed long catmc_nio_atomic_signed_long_load(struct catmc_nio_atomic_signed_long * _Nonnull atomic); +void catmc_nio_atomic_signed_long_store(struct catmc_nio_atomic_signed_long * _Nonnull atomic, signed long value); + +struct catmc_nio_atomic_signed_long_long { + _Atomic signed long long value; +}; +void catmc_nio_atomic_signed_long_long_create_with_existing_storage(struct catmc_nio_atomic_signed_long_long * _Nonnull storage, signed long long value); +bool catmc_nio_atomic_signed_long_long_compare_and_exchange(struct catmc_nio_atomic_signed_long_long * _Nonnull atomic, signed long long expected, signed long long desired); +signed long long catmc_nio_atomic_signed_long_long_add(struct catmc_nio_atomic_signed_long_long * _Nonnull atomic, signed long long value); +signed long long catmc_nio_atomic_signed_long_long_sub(struct catmc_nio_atomic_signed_long_long * _Nonnull atomic, signed long long value); +signed long long catmc_nio_atomic_signed_long_long_exchange(struct catmc_nio_atomic_signed_long_long * _Nonnull atomic, signed long long value); +signed long long catmc_nio_atomic_signed_long_long_load(struct catmc_nio_atomic_signed_long_long * _Nonnull atomic); +void catmc_nio_atomic_signed_long_long_store(struct catmc_nio_atomic_signed_long_long * _Nonnull atomic, signed long long value); + +struct catmc_nio_atomic_unsigned_char { + _Atomic unsigned char value; +}; +void catmc_nio_atomic_unsigned_char_create_with_existing_storage(struct catmc_nio_atomic_unsigned_char * _Nonnull storage, unsigned char value); +bool catmc_nio_atomic_unsigned_char_compare_and_exchange(struct catmc_nio_atomic_unsigned_char * _Nonnull atomic, unsigned char expected, unsigned char desired); +unsigned char catmc_nio_atomic_unsigned_char_add(struct catmc_nio_atomic_unsigned_char * _Nonnull atomic, unsigned char value); +unsigned char catmc_nio_atomic_unsigned_char_sub(struct catmc_nio_atomic_unsigned_char * _Nonnull atomic, unsigned char value); +unsigned char catmc_nio_atomic_unsigned_char_exchange(struct catmc_nio_atomic_unsigned_char * _Nonnull atomic, unsigned char value); +unsigned char catmc_nio_atomic_unsigned_char_load(struct catmc_nio_atomic_unsigned_char * _Nonnull atomic); +void catmc_nio_atomic_unsigned_char_store(struct catmc_nio_atomic_unsigned_char * _Nonnull atomic, unsigned char value); + +struct catmc_nio_atomic_unsigned_short { + _Atomic unsigned short value; +}; +void catmc_nio_atomic_unsigned_short_create_with_existing_storage(struct catmc_nio_atomic_unsigned_short * _Nonnull storage, unsigned short value); +bool catmc_nio_atomic_unsigned_short_compare_and_exchange(struct catmc_nio_atomic_unsigned_short * _Nonnull atomic, unsigned short expected, unsigned short desired); +unsigned short catmc_nio_atomic_unsigned_short_add(struct catmc_nio_atomic_unsigned_short * _Nonnull atomic, unsigned short value); +unsigned short catmc_nio_atomic_unsigned_short_sub(struct catmc_nio_atomic_unsigned_short * _Nonnull atomic, unsigned short value); +unsigned short catmc_nio_atomic_unsigned_short_exchange(struct catmc_nio_atomic_unsigned_short * _Nonnull atomic, unsigned short value); +unsigned short catmc_nio_atomic_unsigned_short_load(struct catmc_nio_atomic_unsigned_short * _Nonnull atomic); +void catmc_nio_atomic_unsigned_short_store(struct catmc_nio_atomic_unsigned_short * _Nonnull atomic, unsigned short value); + +struct catmc_nio_atomic_unsigned_int { + _Atomic unsigned int value; +}; +void catmc_nio_atomic_unsigned_int_create_with_existing_storage(struct catmc_nio_atomic_unsigned_int * _Nonnull storage, unsigned int value); +bool catmc_nio_atomic_unsigned_int_compare_and_exchange(struct catmc_nio_atomic_unsigned_int * _Nonnull atomic, unsigned int expected, unsigned int desired); +unsigned int catmc_nio_atomic_unsigned_int_add(struct catmc_nio_atomic_unsigned_int * _Nonnull atomic, unsigned int value); +unsigned int catmc_nio_atomic_unsigned_int_sub(struct catmc_nio_atomic_unsigned_int * _Nonnull atomic, unsigned int value); +unsigned int catmc_nio_atomic_unsigned_int_exchange(struct catmc_nio_atomic_unsigned_int * _Nonnull atomic, unsigned int value); +unsigned int catmc_nio_atomic_unsigned_int_load(struct catmc_nio_atomic_unsigned_int * _Nonnull atomic); +void catmc_nio_atomic_unsigned_int_store(struct catmc_nio_atomic_unsigned_int * _Nonnull atomic, unsigned int value); + +struct catmc_nio_atomic_unsigned_long { + _Atomic unsigned long value; +}; +void catmc_nio_atomic_unsigned_long_create_with_existing_storage(struct catmc_nio_atomic_unsigned_long * _Nonnull storage, unsigned long value); +bool catmc_nio_atomic_unsigned_long_compare_and_exchange(struct catmc_nio_atomic_unsigned_long * _Nonnull atomic, unsigned long expected, unsigned long desired); +unsigned long catmc_nio_atomic_unsigned_long_add(struct catmc_nio_atomic_unsigned_long * _Nonnull atomic, unsigned long value); +unsigned long catmc_nio_atomic_unsigned_long_sub(struct catmc_nio_atomic_unsigned_long * _Nonnull atomic, unsigned long value); +unsigned long catmc_nio_atomic_unsigned_long_exchange(struct catmc_nio_atomic_unsigned_long * _Nonnull atomic, unsigned long value); +unsigned long catmc_nio_atomic_unsigned_long_load(struct catmc_nio_atomic_unsigned_long * _Nonnull atomic); +void catmc_nio_atomic_unsigned_long_store(struct catmc_nio_atomic_unsigned_long * _Nonnull atomic, unsigned long value); + +struct catmc_nio_atomic_unsigned_long_long { + _Atomic unsigned long long value; +}; +void catmc_nio_atomic_unsigned_long_long_create_with_existing_storage(struct catmc_nio_atomic_unsigned_long_long * _Nonnull storage, unsigned long long value); +bool catmc_nio_atomic_unsigned_long_long_compare_and_exchange(struct catmc_nio_atomic_unsigned_long_long * _Nonnull atomic, unsigned long long expected, unsigned long long desired); +unsigned long long catmc_nio_atomic_unsigned_long_long_add(struct catmc_nio_atomic_unsigned_long_long * _Nonnull atomic, unsigned long long value); +unsigned long long catmc_nio_atomic_unsigned_long_long_sub(struct catmc_nio_atomic_unsigned_long_long * _Nonnull atomic, unsigned long long value); +unsigned long long catmc_nio_atomic_unsigned_long_long_exchange(struct catmc_nio_atomic_unsigned_long_long * _Nonnull atomic, unsigned long long value); +unsigned long long catmc_nio_atomic_unsigned_long_long_load(struct catmc_nio_atomic_unsigned_long_long * _Nonnull atomic); +void catmc_nio_atomic_unsigned_long_long_store(struct catmc_nio_atomic_unsigned_long_long * _Nonnull atomic, unsigned long long value); + +struct catmc_nio_atomic_int_least8_t { + _Atomic int_least8_t value; +}; +void catmc_nio_atomic_int_least8_t_create_with_existing_storage(struct catmc_nio_atomic_int_least8_t * _Nonnull storage, int_least8_t value); +bool catmc_nio_atomic_int_least8_t_compare_and_exchange(struct catmc_nio_atomic_int_least8_t * _Nonnull atomic, int_least8_t expected, int_least8_t desired); +int_least8_t catmc_nio_atomic_int_least8_t_add(struct catmc_nio_atomic_int_least8_t * _Nonnull atomic, int_least8_t value); +int_least8_t catmc_nio_atomic_int_least8_t_sub(struct catmc_nio_atomic_int_least8_t * _Nonnull atomic, int_least8_t value); +int_least8_t catmc_nio_atomic_int_least8_t_exchange(struct catmc_nio_atomic_int_least8_t * _Nonnull atomic, int_least8_t value); +int_least8_t catmc_nio_atomic_int_least8_t_load(struct catmc_nio_atomic_int_least8_t * _Nonnull atomic); +void catmc_nio_atomic_int_least8_t_store(struct catmc_nio_atomic_int_least8_t * _Nonnull atomic, int_least8_t value); + +struct catmc_nio_atomic_uint_least8_t { + _Atomic uint_least8_t value; +}; +void catmc_nio_atomic_uint_least8_t_create_with_existing_storage(struct catmc_nio_atomic_uint_least8_t * _Nonnull storage, uint_least8_t value); +bool catmc_nio_atomic_uint_least8_t_compare_and_exchange(struct catmc_nio_atomic_uint_least8_t * _Nonnull atomic, uint_least8_t expected, uint_least8_t desired); +uint_least8_t catmc_nio_atomic_uint_least8_t_add(struct catmc_nio_atomic_uint_least8_t * _Nonnull atomic, uint_least8_t value); +uint_least8_t catmc_nio_atomic_uint_least8_t_sub(struct catmc_nio_atomic_uint_least8_t * _Nonnull atomic, uint_least8_t value); +uint_least8_t catmc_nio_atomic_uint_least8_t_exchange(struct catmc_nio_atomic_uint_least8_t * _Nonnull atomic, uint_least8_t value); +uint_least8_t catmc_nio_atomic_uint_least8_t_load(struct catmc_nio_atomic_uint_least8_t * _Nonnull atomic); +void catmc_nio_atomic_uint_least8_t_store(struct catmc_nio_atomic_uint_least8_t * _Nonnull atomic, uint_least8_t value); + +struct catmc_nio_atomic_int_least16_t { + _Atomic int_least16_t value; +}; +void catmc_nio_atomic_int_least16_t_create_with_existing_storage(struct catmc_nio_atomic_int_least16_t * _Nonnull storage, int_least16_t value); +bool catmc_nio_atomic_int_least16_t_compare_and_exchange(struct catmc_nio_atomic_int_least16_t * _Nonnull atomic, int_least16_t expected, int_least16_t desired); +int_least16_t catmc_nio_atomic_int_least16_t_add(struct catmc_nio_atomic_int_least16_t * _Nonnull atomic, int_least16_t value); +int_least16_t catmc_nio_atomic_int_least16_t_sub(struct catmc_nio_atomic_int_least16_t * _Nonnull atomic, int_least16_t value); +int_least16_t catmc_nio_atomic_int_least16_t_exchange(struct catmc_nio_atomic_int_least16_t * _Nonnull atomic, int_least16_t value); +int_least16_t catmc_nio_atomic_int_least16_t_load(struct catmc_nio_atomic_int_least16_t * _Nonnull atomic); +void catmc_nio_atomic_int_least16_t_store(struct catmc_nio_atomic_int_least16_t * _Nonnull atomic, int_least16_t value); + +struct catmc_nio_atomic_uint_least16_t { + _Atomic uint_least16_t value; +}; +void catmc_nio_atomic_uint_least16_t_create_with_existing_storage(struct catmc_nio_atomic_uint_least16_t * _Nonnull storage, uint_least16_t value); +bool catmc_nio_atomic_uint_least16_t_compare_and_exchange(struct catmc_nio_atomic_uint_least16_t * _Nonnull atomic, uint_least16_t expected, uint_least16_t desired); +uint_least16_t catmc_nio_atomic_uint_least16_t_add(struct catmc_nio_atomic_uint_least16_t * _Nonnull atomic, uint_least16_t value); +uint_least16_t catmc_nio_atomic_uint_least16_t_sub(struct catmc_nio_atomic_uint_least16_t * _Nonnull atomic, uint_least16_t value); +uint_least16_t catmc_nio_atomic_uint_least16_t_exchange(struct catmc_nio_atomic_uint_least16_t * _Nonnull atomic, uint_least16_t value); +uint_least16_t catmc_nio_atomic_uint_least16_t_load(struct catmc_nio_atomic_uint_least16_t * _Nonnull atomic); +void catmc_nio_atomic_uint_least16_t_store(struct catmc_nio_atomic_uint_least16_t * _Nonnull atomic, uint_least16_t value); + +struct catmc_nio_atomic_int_least32_t { + _Atomic int_least32_t value; +}; +void catmc_nio_atomic_int_least32_t_create_with_existing_storage(struct catmc_nio_atomic_int_least32_t * _Nonnull storage, int_least32_t value); +bool catmc_nio_atomic_int_least32_t_compare_and_exchange(struct catmc_nio_atomic_int_least32_t * _Nonnull atomic, int_least32_t expected, int_least32_t desired); +int_least32_t catmc_nio_atomic_int_least32_t_add(struct catmc_nio_atomic_int_least32_t * _Nonnull atomic, int_least32_t value); +int_least32_t catmc_nio_atomic_int_least32_t_sub(struct catmc_nio_atomic_int_least32_t * _Nonnull atomic, int_least32_t value); +int_least32_t catmc_nio_atomic_int_least32_t_exchange(struct catmc_nio_atomic_int_least32_t * _Nonnull atomic, int_least32_t value); +int_least32_t catmc_nio_atomic_int_least32_t_load(struct catmc_nio_atomic_int_least32_t * _Nonnull atomic); +void catmc_nio_atomic_int_least32_t_store(struct catmc_nio_atomic_int_least32_t * _Nonnull atomic, int_least32_t value); + +struct catmc_nio_atomic_uint_least32_t { + _Atomic uint_least32_t value; +}; +void catmc_nio_atomic_uint_least32_t_create_with_existing_storage(struct catmc_nio_atomic_uint_least32_t * _Nonnull storage, uint_least32_t value); +bool catmc_nio_atomic_uint_least32_t_compare_and_exchange(struct catmc_nio_atomic_uint_least32_t * _Nonnull atomic, uint_least32_t expected, uint_least32_t desired); +uint_least32_t catmc_nio_atomic_uint_least32_t_add(struct catmc_nio_atomic_uint_least32_t * _Nonnull atomic, uint_least32_t value); +uint_least32_t catmc_nio_atomic_uint_least32_t_sub(struct catmc_nio_atomic_uint_least32_t * _Nonnull atomic, uint_least32_t value); +uint_least32_t catmc_nio_atomic_uint_least32_t_exchange(struct catmc_nio_atomic_uint_least32_t * _Nonnull atomic, uint_least32_t value); +uint_least32_t catmc_nio_atomic_uint_least32_t_load(struct catmc_nio_atomic_uint_least32_t * _Nonnull atomic); +void catmc_nio_atomic_uint_least32_t_store(struct catmc_nio_atomic_uint_least32_t * _Nonnull atomic, uint_least32_t value); + +struct catmc_nio_atomic_int_least64_t { + _Atomic int_least64_t value; +}; +void catmc_nio_atomic_int_least64_t_create_with_existing_storage(struct catmc_nio_atomic_int_least64_t * _Nonnull storage, int_least64_t value); +bool catmc_nio_atomic_int_least64_t_compare_and_exchange(struct catmc_nio_atomic_int_least64_t * _Nonnull atomic, int_least64_t expected, int_least64_t desired); +int_least64_t catmc_nio_atomic_int_least64_t_add(struct catmc_nio_atomic_int_least64_t * _Nonnull atomic, int_least64_t value); +int_least64_t catmc_nio_atomic_int_least64_t_sub(struct catmc_nio_atomic_int_least64_t * _Nonnull atomic, int_least64_t value); +int_least64_t catmc_nio_atomic_int_least64_t_exchange(struct catmc_nio_atomic_int_least64_t * _Nonnull atomic, int_least64_t value); +int_least64_t catmc_nio_atomic_int_least64_t_load(struct catmc_nio_atomic_int_least64_t * _Nonnull atomic); +void catmc_nio_atomic_int_least64_t_store(struct catmc_nio_atomic_int_least64_t * _Nonnull atomic, int_least64_t value); + +struct catmc_nio_atomic_uint_least64_t { + _Atomic uint_least64_t value; +}; +void catmc_nio_atomic_uint_least64_t_create_with_existing_storage(struct catmc_nio_atomic_uint_least64_t * _Nonnull storage, uint_least64_t value); +bool catmc_nio_atomic_uint_least64_t_compare_and_exchange(struct catmc_nio_atomic_uint_least64_t * _Nonnull atomic, uint_least64_t expected, uint_least64_t desired); +uint_least64_t catmc_nio_atomic_uint_least64_t_add(struct catmc_nio_atomic_uint_least64_t * _Nonnull atomic, uint_least64_t value); +uint_least64_t catmc_nio_atomic_uint_least64_t_sub(struct catmc_nio_atomic_uint_least64_t * _Nonnull atomic, uint_least64_t value); +uint_least64_t catmc_nio_atomic_uint_least64_t_exchange(struct catmc_nio_atomic_uint_least64_t * _Nonnull atomic, uint_least64_t value); +uint_least64_t catmc_nio_atomic_uint_least64_t_load(struct catmc_nio_atomic_uint_least64_t * _Nonnull atomic); +void catmc_nio_atomic_uint_least64_t_store(struct catmc_nio_atomic_uint_least64_t * _Nonnull atomic, uint_least64_t value); diff --git a/Sources/CNIOAtomics/src/c-nioatomics.c b/Sources/CNIOAtomics/src/c-nioatomics.c new file mode 100644 index 00000000..22402434 --- /dev/null +++ b/Sources/CNIOAtomics/src/c-nioatomics.c @@ -0,0 +1,75 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2019 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#include +#include +#include +#include +#include + +#include "../include/CNIOAtomics.h" +#include "cpp_magic.h" + +#define MAKE(type) /* +*/ void catmc_nio_atomic_##type##_create_with_existing_storage(struct catmc_nio_atomic_##type *storage, type value) { /* +*/ atomic_init(&storage->value, value); /* +*/ } /* +*/ /* +*/ bool catmc_nio_atomic_##type##_compare_and_exchange(struct catmc_nio_atomic_##type *wrapper, type expected, type desired) { /* +*/ type expected_copy = expected; /* +*/ return atomic_compare_exchange_strong(&wrapper->value, &expected_copy, desired); /* +*/ } /* +*/ /* +*/ type catmc_nio_atomic_##type##_add(struct catmc_nio_atomic_##type *wrapper, type value) { /* +*/ return atomic_fetch_add_explicit(&wrapper->value, value, memory_order_relaxed); /* +*/ } /* +*/ /* +*/ type catmc_nio_atomic_##type##_sub(struct catmc_nio_atomic_##type *wrapper, type value) { /* +*/ return atomic_fetch_sub_explicit(&wrapper->value, value, memory_order_relaxed); /* +*/ } /* +*/ /* +*/ type catmc_nio_atomic_##type##_exchange(struct catmc_nio_atomic_##type *wrapper, type value) { /* +*/ return atomic_exchange_explicit(&wrapper->value, value, memory_order_relaxed); /* +*/ } /* +*/ /* +*/ type catmc_nio_atomic_##type##_load(struct catmc_nio_atomic_##type *wrapper) { /* +*/ return atomic_load_explicit(&wrapper->value, memory_order_relaxed); /* +*/ } /* +*/ /* +*/ void catmc_nio_atomic_##type##_store(struct catmc_nio_atomic_##type *wrapper, type value) { /* +*/ atomic_store_explicit(&wrapper->value, value, memory_order_relaxed); /* +*/ } + +typedef signed char signed_char; +typedef signed short signed_short; +typedef signed int signed_int; +typedef signed long signed_long; +typedef signed long long signed_long_long; +typedef unsigned char unsigned_char; +typedef unsigned short unsigned_short; +typedef unsigned int unsigned_int; +typedef unsigned long unsigned_long; +typedef unsigned long long unsigned_long_long; +typedef long long long_long; + +MAP(MAKE,EMPTY, + bool, + char, short, int, long, long_long, + signed_char, signed_short, signed_int, signed_long, signed_long_long, + unsigned_char, unsigned_short, unsigned_int, unsigned_long, unsigned_long_long, + int_least8_t, uint_least8_t, + int_least16_t, uint_least16_t, + int_least32_t, uint_least32_t, + int_least64_t, uint_least64_t + ) diff --git a/Sources/NIO/BaseSocketChannel.swift b/Sources/NIO/BaseSocketChannel.swift index a138407a..21b547cc 100644 --- a/Sources/NIO/BaseSocketChannel.swift +++ b/Sources/NIO/BaseSocketChannel.swift @@ -34,7 +34,7 @@ private struct SocketChannelLifecycleManager { // MARK: properties private let eventLoop: EventLoop // this is queried from the Channel, ie. must be thread-safe - internal let isActiveAtomic: Atomic + internal let isActiveAtomic: NIOAtomic // these are only to be accessed on the EventLoop // have we seen the `.readEOF` notification @@ -57,7 +57,7 @@ private struct SocketChannelLifecycleManager { // MARK: API // isActiveAtomic needs to be injected as it's accessed from arbitrary threads and `SocketChannelLifecycleManager` is usually held mutable - internal init(eventLoop: EventLoop, isActiveAtomic: Atomic) { + internal init(eventLoop: EventLoop, isActiveAtomic: NIOAtomic) { self.eventLoop = eventLoop self.isActiveAtomic = isActiveAtomic } @@ -213,7 +213,7 @@ class BaseSocketChannel: SelectableChannel, Chan internal let selectableEventLoop: SelectableEventLoop private let addressesCached: AtomicBox> = AtomicBox(value: Box((local: nil, remote: nil))) private let bufferAllocatorCached: AtomicBox> - private let isActiveAtomic: Atomic = Atomic(value: false) + private let isActiveAtomic: NIOAtomic = .makeAtomic(value: false) private var _pipeline: ChannelPipeline! = nil // this is really a constant (set in .init) but needs `self` to be constructed and therefore a `var`. Do not change as this needs to accessed from arbitrary threads // just a thread-safe way of having something to print about the socket from any thread internal let socketDescription: String diff --git a/Sources/NIO/EventLoop.swift b/Sources/NIO/EventLoop.swift index a272a337..b379b6dc 100644 --- a/Sources/NIO/EventLoop.swift +++ b/Sources/NIO/EventLoop.swift @@ -1128,7 +1128,7 @@ extension EventLoopGroup { } } -private let nextEventLoopGroupID = Atomic(value: 0) +private let nextEventLoopGroupID = NIOAtomic.makeAtomic(value: 0) /// Called per `NIOThread` that is created for an EventLoop to do custom initialization of the `NIOThread` before the actual `EventLoop` is run on it. typealias ThreadInitializer = (NIOThread) -> Void @@ -1156,7 +1156,7 @@ public final class MultiThreadedEventLoopGroup: EventLoopGroup { private static let threadSpecificEventLoop = ThreadSpecificVariable() - private let index = Atomic(value: 0) + private let index = NIOAtomic.makeAtomic(value: 0) private let eventLoops: [SelectableEventLoop] private let shutdownLock: Lock = Lock() private var runState: RunState = .running diff --git a/Sources/NIO/PendingDatagramWritesManager.swift b/Sources/NIO/PendingDatagramWritesManager.swift index db1e323d..a1cb1fb9 100644 --- a/Sources/NIO/PendingDatagramWritesManager.swift +++ b/Sources/NIO/PendingDatagramWritesManager.swift @@ -360,7 +360,7 @@ final class PendingDatagramWritesManager: PendingWritesManager { private var state = PendingDatagramWritesState() internal var waterMark: ChannelOptions.Types.WriteBufferWaterMark = ChannelOptions.Types.WriteBufferWaterMark(low: 32 * 1024, high: 64 * 1024) - internal let channelWritabilityFlag: Atomic = Atomic(value: true) + internal let channelWritabilityFlag: NIOAtomic = .makeAtomic(value: true) internal var writeSpinCount: UInt = 16 private(set) var isOpen = true diff --git a/Sources/NIO/PendingWritesManager.swift b/Sources/NIO/PendingWritesManager.swift index a29592d6..b69d3560 100644 --- a/Sources/NIO/PendingWritesManager.swift +++ b/Sources/NIO/PendingWritesManager.swift @@ -277,7 +277,7 @@ final class PendingStreamWritesManager: PendingWritesManager { private var storageRefs: UnsafeMutableBufferPointer> internal var waterMark: ChannelOptions.Types.WriteBufferWaterMark = ChannelOptions.Types.WriteBufferWaterMark(low: 32 * 1024, high: 64 * 1024) - internal let channelWritabilityFlag: Atomic = Atomic(value: true) + internal let channelWritabilityFlag: NIOAtomic = .makeAtomic(value: true) internal var writeSpinCount: UInt = 16 @@ -451,7 +451,7 @@ internal protocol PendingWritesManager { var isFlushPending: Bool { get } var writeSpinCount: UInt { get } var currentBestWriteMechanism: WriteMechanism { get } - var channelWritabilityFlag: Atomic { get } + var channelWritabilityFlag: NIOAtomic { get } } extension PendingWritesManager { diff --git a/Sources/NIOConcurrencyHelpers/NIOAtomic.swift b/Sources/NIOConcurrencyHelpers/NIOAtomic.swift new file mode 100644 index 00000000..a43904fa --- /dev/null +++ b/Sources/NIOConcurrencyHelpers/NIOAtomic.swift @@ -0,0 +1,287 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import CNIOAtomics + +/// The protocol that all types that can be made atomic must conform to. +/// +/// **Do not add conformance to this protocol for arbitrary types**. Only a small range +/// of types have appropriate atomic operations supported by the CPU, and those types +/// already have conformances implemented. +public protocol NIOAtomicPrimitive { + associatedtype AtomicWrapper + static var nio_atomic_create_with_existing_storage: (UnsafeMutablePointer, Self) -> Void { get } + static var nio_atomic_compare_and_exchange: (UnsafeMutablePointer, Self, Self) -> Bool { get } + static var nio_atomic_add: (UnsafeMutablePointer, Self) -> Self { get } + static var nio_atomic_sub: (UnsafeMutablePointer, Self) -> Self { get } + static var nio_atomic_exchange: (UnsafeMutablePointer, Self) -> Self { get } + static var nio_atomic_load: (UnsafeMutablePointer) -> Self { get } + static var nio_atomic_store: (UnsafeMutablePointer, Self) -> Void { get } +} + +extension Bool: NIOAtomicPrimitive { + public typealias AtomicWrapper = catmc_nio_atomic__Bool + public static let nio_atomic_create_with_existing_storage = catmc_nio_atomic__Bool_create_with_existing_storage + public static let nio_atomic_compare_and_exchange = catmc_nio_atomic__Bool_compare_and_exchange + public static let nio_atomic_add = catmc_nio_atomic__Bool_add + public static let nio_atomic_sub = catmc_nio_atomic__Bool_sub + public static let nio_atomic_exchange = catmc_nio_atomic__Bool_exchange + public static let nio_atomic_load = catmc_nio_atomic__Bool_load + public static let nio_atomic_store = catmc_nio_atomic__Bool_store +} + +extension Int8: NIOAtomicPrimitive { + public typealias AtomicWrapper = catmc_nio_atomic_int_least8_t + public static let nio_atomic_create_with_existing_storage = catmc_nio_atomic_int_least8_t_create_with_existing_storage + public static let nio_atomic_compare_and_exchange = catmc_nio_atomic_int_least8_t_compare_and_exchange + public static let nio_atomic_add = catmc_nio_atomic_int_least8_t_add + public static let nio_atomic_sub = catmc_nio_atomic_int_least8_t_sub + public static let nio_atomic_exchange = catmc_nio_atomic_int_least8_t_exchange + public static let nio_atomic_load = catmc_nio_atomic_int_least8_t_load + public static let nio_atomic_store = catmc_nio_atomic_int_least8_t_store +} + +extension UInt8: NIOAtomicPrimitive { + public typealias AtomicWrapper = catmc_nio_atomic_uint_least8_t + public static let nio_atomic_create_with_existing_storage = catmc_nio_atomic_uint_least8_t_create_with_existing_storage + public static let nio_atomic_compare_and_exchange = catmc_nio_atomic_uint_least8_t_compare_and_exchange + public static let nio_atomic_add = catmc_nio_atomic_uint_least8_t_add + public static let nio_atomic_sub = catmc_nio_atomic_uint_least8_t_sub + public static let nio_atomic_exchange = catmc_nio_atomic_uint_least8_t_exchange + public static let nio_atomic_load = catmc_nio_atomic_uint_least8_t_load + public static let nio_atomic_store = catmc_nio_atomic_uint_least8_t_store +} + +extension Int16: NIOAtomicPrimitive { + public typealias AtomicWrapper = catmc_nio_atomic_int_least16_t + public static let nio_atomic_create_with_existing_storage = catmc_nio_atomic_int_least16_t_create_with_existing_storage + public static let nio_atomic_compare_and_exchange = catmc_nio_atomic_int_least16_t_compare_and_exchange + public static let nio_atomic_add = catmc_nio_atomic_int_least16_t_add + public static let nio_atomic_sub = catmc_nio_atomic_int_least16_t_sub + public static let nio_atomic_exchange = catmc_nio_atomic_int_least16_t_exchange + public static let nio_atomic_load = catmc_nio_atomic_int_least16_t_load + public static let nio_atomic_store = catmc_nio_atomic_int_least16_t_store +} + +extension UInt16: NIOAtomicPrimitive { + public typealias AtomicWrapper = catmc_nio_atomic_uint_least16_t + public static let nio_atomic_create_with_existing_storage = catmc_nio_atomic_uint_least16_t_create_with_existing_storage + public static let nio_atomic_compare_and_exchange = catmc_nio_atomic_uint_least16_t_compare_and_exchange + public static let nio_atomic_add = catmc_nio_atomic_uint_least16_t_add + public static let nio_atomic_sub = catmc_nio_atomic_uint_least16_t_sub + public static let nio_atomic_exchange = catmc_nio_atomic_uint_least16_t_exchange + public static let nio_atomic_load = catmc_nio_atomic_uint_least16_t_load + public static let nio_atomic_store = catmc_nio_atomic_uint_least16_t_store +} + +extension Int32: NIOAtomicPrimitive { + public typealias AtomicWrapper = catmc_nio_atomic_int_least32_t + public static let nio_atomic_create_with_existing_storage = catmc_nio_atomic_int_least32_t_create_with_existing_storage + public static let nio_atomic_compare_and_exchange = catmc_nio_atomic_int_least32_t_compare_and_exchange + public static let nio_atomic_add = catmc_nio_atomic_int_least32_t_add + public static let nio_atomic_sub = catmc_nio_atomic_int_least32_t_sub + public static let nio_atomic_exchange = catmc_nio_atomic_int_least32_t_exchange + public static let nio_atomic_load = catmc_nio_atomic_int_least32_t_load + public static let nio_atomic_store = catmc_nio_atomic_int_least32_t_store +} + +extension UInt32: NIOAtomicPrimitive { + public typealias AtomicWrapper = catmc_nio_atomic_uint_least32_t + public static let nio_atomic_create_with_existing_storage = catmc_nio_atomic_uint_least32_t_create_with_existing_storage + public static let nio_atomic_compare_and_exchange = catmc_nio_atomic_uint_least32_t_compare_and_exchange + public static let nio_atomic_add = catmc_nio_atomic_uint_least32_t_add + public static let nio_atomic_sub = catmc_nio_atomic_uint_least32_t_sub + public static let nio_atomic_exchange = catmc_nio_atomic_uint_least32_t_exchange + public static let nio_atomic_load = catmc_nio_atomic_uint_least32_t_load + public static let nio_atomic_store = catmc_nio_atomic_uint_least32_t_store +} + +extension Int64: NIOAtomicPrimitive { + public typealias AtomicWrapper = catmc_nio_atomic_long_long + public static let nio_atomic_create_with_existing_storage = catmc_nio_atomic_long_long_create_with_existing_storage + public static let nio_atomic_compare_and_exchange = catmc_nio_atomic_long_long_compare_and_exchange + public static let nio_atomic_add = catmc_nio_atomic_long_long_add + public static let nio_atomic_sub = catmc_nio_atomic_long_long_sub + public static let nio_atomic_exchange = catmc_nio_atomic_long_long_exchange + public static let nio_atomic_load = catmc_nio_atomic_long_long_load + public static let nio_atomic_store = catmc_nio_atomic_long_long_store +} + +extension UInt64: NIOAtomicPrimitive { + public typealias AtomicWrapper = catmc_nio_atomic_unsigned_long_long + public static let nio_atomic_create_with_existing_storage = catmc_nio_atomic_unsigned_long_long_create_with_existing_storage + public static let nio_atomic_compare_and_exchange = catmc_nio_atomic_unsigned_long_long_compare_and_exchange + public static let nio_atomic_add = catmc_nio_atomic_unsigned_long_long_add + public static let nio_atomic_sub = catmc_nio_atomic_unsigned_long_long_sub + public static let nio_atomic_exchange = catmc_nio_atomic_unsigned_long_long_exchange + public static let nio_atomic_load = catmc_nio_atomic_unsigned_long_long_load + public static let nio_atomic_store = catmc_nio_atomic_unsigned_long_long_store +} + +extension Int: NIOAtomicPrimitive { + public typealias AtomicWrapper = catmc_nio_atomic_long + public static let nio_atomic_create_with_existing_storage = catmc_nio_atomic_long_create_with_existing_storage + public static let nio_atomic_compare_and_exchange = catmc_nio_atomic_long_compare_and_exchange + public static let nio_atomic_add = catmc_nio_atomic_long_add + public static let nio_atomic_sub = catmc_nio_atomic_long_sub + public static let nio_atomic_exchange = catmc_nio_atomic_long_exchange + public static let nio_atomic_load = catmc_nio_atomic_long_load + public static let nio_atomic_store = catmc_nio_atomic_long_store +} + +extension UInt: NIOAtomicPrimitive { + public typealias AtomicWrapper = catmc_nio_atomic_unsigned_long + public static let nio_atomic_create_with_existing_storage = catmc_nio_atomic_unsigned_long_create_with_existing_storage + public static let nio_atomic_compare_and_exchange = catmc_nio_atomic_unsigned_long_compare_and_exchange + public static let nio_atomic_add = catmc_nio_atomic_unsigned_long_add + public static let nio_atomic_sub = catmc_nio_atomic_unsigned_long_sub + public static let nio_atomic_exchange = catmc_nio_atomic_unsigned_long_exchange + public static let nio_atomic_load = catmc_nio_atomic_unsigned_long_load + public static let nio_atomic_store = catmc_nio_atomic_unsigned_long_store +} + +/// An encapsulation of an atomic primitive object. +/// +/// Atomic objects support a wide range of atomic operations: +/// +/// - Compare and swap +/// - Add +/// - Subtract +/// - Exchange +/// - Load current value +/// - Store current value +/// +/// Atomic primitives are useful when building constructs that need to +/// communicate or cooperate across multiple threads. In the case of +/// SwiftNIO this usually involves communicating across multiple event loops. +/// +/// By necessity, all atomic values are references: after all, it makes no +/// sense to talk about managing an atomic value when each time it's modified +/// the thread that modified it gets a local copy! +public final class NIOAtomic { + @usableFromInline + typealias Manager = ManagedBufferPointer + + /// Create an atomic object with `value` + @inlinable + public static func makeAtomic(value: T) -> NIOAtomic { + let manager = Manager(bufferClass: self, minimumCapacity: 1) { _, _ in } + manager.withUnsafeMutablePointerToElements { + T.nio_atomic_create_with_existing_storage($0, value) + } + return manager.buffer as! NIOAtomic + } + + /// Atomically compares the value against `expected` and, if they are equal, + /// replaces the value with `desired`. + /// + /// This implementation conforms to C11's `atomic_compare_exchange_strong`. This + /// means that the compare-and-swap will always succeed if `expected` is equal to + /// value. Additionally, it uses a *sequentially consistent ordering*. For more + /// details on atomic memory models, check the documentation for C11's + /// `stdatomic.h`. + /// + /// - Parameter expected: The value that this object must currently hold for the + /// compare-and-swap to succeed. + /// - Parameter desired: The new value that this object will hold if the compare + /// succeeds. + /// - Returns: `True` if the exchange occurred, or `False` if `expected` did not + /// match the current value and so no exchange occurred. + @inlinable + public func compareAndExchange(expected: T, desired: T) -> Bool { + return Manager(unsafeBufferObject: self).withUnsafeMutablePointerToElements { + return T.nio_atomic_compare_and_exchange($0, expected, desired) + } + } + + /// Atomically adds `rhs` to this object. + /// + /// This implementation uses a *relaxed* memory ordering. This guarantees nothing + /// more than that this operation is atomic: there is no guarantee that any other + /// event will be ordered before or after this one. + /// + /// - Parameter rhs: The value to add to this object. + /// - Returns: The previous value of this object, before the addition occurred. + @inlinable + public func add(_ rhs: T) -> T { + return Manager(unsafeBufferObject: self).withUnsafeMutablePointerToElements { + return T.nio_atomic_add($0, rhs) + } + } + + /// Atomically subtracts `rhs` from this object. + /// + /// This implementation uses a *relaxed* memory ordering. This guarantees nothing + /// more than that this operation is atomic: there is no guarantee that any other + /// event will be ordered before or after this one. + /// + /// - Parameter rhs: The value to subtract from this object. + /// - Returns: The previous value of this object, before the subtraction occurred. + @inlinable + public func sub(_ rhs: T) -> T { + return Manager(unsafeBufferObject: self).withUnsafeMutablePointerToElements { + return T.nio_atomic_sub($0, rhs) + } + } + + /// Atomically exchanges `value` for the current value of this object. + /// + /// This implementation uses a *relaxed* memory ordering. This guarantees nothing + /// more than that this operation is atomic: there is no guarantee that any other + /// event will be ordered before or after this one. + /// + /// - Parameter value: The new value to set this object to. + /// - Returns: The value previously held by this object. + @inlinable + public func exchange(with value: T) -> T { + return Manager(unsafeBufferObject: self).withUnsafeMutablePointerToElements { + return T.nio_atomic_exchange($0, value) + } + } + + /// Atomically loads and returns the value of this object. + /// + /// This implementation uses a *relaxed* memory ordering. This guarantees nothing + /// more than that this operation is atomic: there is no guarantee that any other + /// event will be ordered before or after this one. + /// + /// - Returns: The value of this object + @inlinable + public func load() -> T { + return Manager(unsafeBufferObject: self).withUnsafeMutablePointerToElements { + return T.nio_atomic_load($0) + } + } + + /// Atomically replaces the value of this object with `value`. + /// + /// This implementation uses a *relaxed* memory ordering. This guarantees nothing + /// more than that this operation is atomic: there is no guarantee that any other + /// event will be ordered before or after this one. + /// + /// - Parameter value: The new value to set the object to. + @inlinable + public func store(_ value: T) -> Void { + return Manager(unsafeBufferObject: self).withUnsafeMutablePointerToElements { + return T.nio_atomic_store($0, value) + } + } + + deinit { + Manager(unsafeBufferObject: self).withUnsafeMutablePointers { headerPtr, elementsPtr in + elementsPtr.deinitialize(count: 1) + headerPtr.deinitialize(count: 1) + } + } +} diff --git a/Sources/NIOConcurrencyHelpers/atomics.swift b/Sources/NIOConcurrencyHelpers/atomics.swift index 38dd180f..6d9fb1f9 100644 --- a/Sources/NIOConcurrencyHelpers/atomics.swift +++ b/Sources/NIOConcurrencyHelpers/atomics.swift @@ -153,6 +153,7 @@ public struct UnsafeEmbeddedAtomic { /// By necessity, all atomic values are references: after all, it makes no /// sense to talk about managing an atomic value when each time it's modified /// the thread that modified it gets a local copy! +@available(*, deprecated, message:"please use NIOAtomic instead") public final class Atomic { @usableFromInline internal let embedded: UnsafeEmbeddedAtomic @@ -392,11 +393,11 @@ extension UInt: AtomicPrimitive { /// /// It behaves very much like `Atomic` but for objects, maintaining the correct retain counts. public final class AtomicBox { - private let storage: Atomic + private let storage: NIOAtomic public init(value: T) { let ptr = Unmanaged.passRetained(value) - self.storage = Atomic(value: UInt(bitPattern: ptr.toOpaque())) + self.storage = NIOAtomic.makeAtomic(value: UInt(bitPattern: ptr.toOpaque())) } deinit { diff --git a/Sources/NIOTestUtils/EventCounterHandler.swift b/Sources/NIOTestUtils/EventCounterHandler.swift index df604706..1907d450 100644 --- a/Sources/NIOTestUtils/EventCounterHandler.swift +++ b/Sources/NIOTestUtils/EventCounterHandler.swift @@ -24,23 +24,23 @@ import NIOConcurrencyHelpers /// - note: Contrary to most `ChannelHandler`s, all of `EventCounterHandler`'s API is thread-safe meaning that you can /// query the events received from any thread. public final class EventCounterHandler { - private let _channelRegisteredCalls = Atomic(value: 0) - private let _channelUnregisteredCalls = Atomic(value: 0) - private let _channelActiveCalls = Atomic(value: 0) - private let _channelInactiveCalls = Atomic(value: 0) - private let _channelReadCalls = Atomic(value: 0) - private let _channelReadCompleteCalls = Atomic(value: 0) - private let _channelWritabilityChangedCalls = Atomic(value: 0) - private let _userInboundEventTriggeredCalls = Atomic(value: 0) - private let _errorCaughtCalls = Atomic(value: 0) - private let _registerCalls = Atomic(value: 0) - private let _bindCalls = Atomic(value: 0) - private let _connectCalls = Atomic(value: 0) - private let _writeCalls = Atomic(value: 0) - private let _flushCalls = Atomic(value: 0) - private let _readCalls = Atomic(value: 0) - private let _closeCalls = Atomic(value: 0) - private let _triggerUserOutboundEventCalls = Atomic(value: 0) + private let _channelRegisteredCalls = NIOAtomic.makeAtomic(value: 0) + private let _channelUnregisteredCalls = NIOAtomic.makeAtomic(value: 0) + private let _channelActiveCalls = NIOAtomic.makeAtomic(value: 0) + private let _channelInactiveCalls = NIOAtomic.makeAtomic(value: 0) + private let _channelReadCalls = NIOAtomic.makeAtomic(value: 0) + private let _channelReadCompleteCalls = NIOAtomic.makeAtomic(value: 0) + private let _channelWritabilityChangedCalls = NIOAtomic.makeAtomic(value: 0) + private let _userInboundEventTriggeredCalls = NIOAtomic.makeAtomic(value: 0) + private let _errorCaughtCalls = NIOAtomic.makeAtomic(value: 0) + private let _registerCalls = NIOAtomic.makeAtomic(value: 0) + private let _bindCalls = NIOAtomic.makeAtomic(value: 0) + private let _connectCalls = NIOAtomic.makeAtomic(value: 0) + private let _writeCalls = NIOAtomic.makeAtomic(value: 0) + private let _flushCalls = NIOAtomic.makeAtomic(value: 0) + private let _readCalls = NIOAtomic.makeAtomic(value: 0) + private let _closeCalls = NIOAtomic.makeAtomic(value: 0) + private let _triggerUserOutboundEventCalls = NIOAtomic.makeAtomic(value: 0) public init() {} } diff --git a/Tests/NIOConcurrencyHelpersTests/NIOConcurrencyHelpersTests+XCTest.swift b/Tests/NIOConcurrencyHelpersTests/NIOConcurrencyHelpersTests+XCTest.swift index bbe9292f..3660ecb4 100644 --- a/Tests/NIOConcurrencyHelpersTests/NIOConcurrencyHelpersTests+XCTest.swift +++ b/Tests/NIOConcurrencyHelpersTests/NIOConcurrencyHelpersTests+XCTest.swift @@ -35,6 +35,14 @@ extension NIOConcurrencyHelpersTests { ("testAddSub", testAddSub), ("testExchange", testExchange), ("testLoadStore", testLoadStore), + ("testLargeContendedNIOAtomicSum", testLargeContendedNIOAtomicSum), + ("testCompareAndExchangeBoolNIOAtomic", testCompareAndExchangeBoolNIOAtomic), + ("testAllOperationsBoolNIOAtomic", testAllOperationsBoolNIOAtomic), + ("testCompareAndExchangeUIntsNIOAtomic", testCompareAndExchangeUIntsNIOAtomic), + ("testCompareAndExchangeIntsNIOAtomic", testCompareAndExchangeIntsNIOAtomic), + ("testAddSubNIOAtomic", testAddSubNIOAtomic), + ("testExchangeNIOAtomic", testExchangeNIOAtomic), + ("testLoadStoreNIOAtomic", testLoadStoreNIOAtomic), ("testLockMutualExclusion", testLockMutualExclusion), ("testWithLockMutualExclusion", testWithLockMutualExclusion), ("testConditionLockMutualExclusion", testConditionLockMutualExclusion), diff --git a/Tests/NIOConcurrencyHelpersTests/NIOConcurrencyHelpersTests.swift b/Tests/NIOConcurrencyHelpersTests/NIOConcurrencyHelpersTests.swift index f0f898bd..e629a379 100644 --- a/Tests/NIOConcurrencyHelpersTests/NIOConcurrencyHelpersTests.swift +++ b/Tests/NIOConcurrencyHelpersTests/NIOConcurrencyHelpersTests.swift @@ -25,6 +25,7 @@ class NIOConcurrencyHelpersTests: XCTestCase { return n*(n+1)/2 } + @available(*, deprecated, message: "deprecated because it tests deprecated functionality") func testLargeContendedAtomicSum() { let noAsyncs: UInt64 = 64 let noCounts: UInt64 = 200_000 @@ -43,6 +44,7 @@ class NIOConcurrencyHelpersTests: XCTestCase { XCTAssertEqual(sumOfIntegers(until: noAsyncs) * noCounts, ai.load()) } + @available(*, deprecated, message: "deprecated because it tests deprecated functionality") func testCompareAndExchangeBool() { let ab = Atomic(value: true) @@ -56,6 +58,7 @@ class NIOConcurrencyHelpersTests: XCTestCase { XCTAssertTrue(ab.compareAndExchange(expected: false, desired: true)) } + @available(*, deprecated, message: "deprecated because it tests deprecated functionality") func testAllOperationsBool() { let ab = Atomic(value: false) XCTAssertEqual(false, ab.load()) @@ -72,6 +75,7 @@ class NIOConcurrencyHelpersTests: XCTestCase { XCTAssertFalse(ab.compareAndExchange(expected: false, desired: true)) } + @available(*, deprecated, message: "deprecated because it tests deprecated functionality") func testCompareAndExchangeUInts() { func testFor(_ value: T.Type) { let zero: T = 0 @@ -102,6 +106,7 @@ class NIOConcurrencyHelpersTests: XCTestCase { testFor(UInt.self) } + @available(*, deprecated, message: "deprecated because it tests deprecated functionality") func testCompareAndExchangeInts() { func testFor(_ value: T.Type) { let zero: T = 0 @@ -133,6 +138,7 @@ class NIOConcurrencyHelpersTests: XCTestCase { testFor(Int.self) } + @available(*, deprecated, message: "deprecated because it tests deprecated functionality") func testAddSub() { func testFor(_ value: T.Type) { let zero: T = 0 @@ -164,6 +170,7 @@ class NIOConcurrencyHelpersTests: XCTestCase { testFor(UInt.self) } + @available(*, deprecated, message: "deprecated because it tests deprecated functionality") func testExchange() { func testFor(_ value: T.Type) { let zero: T = 0 @@ -195,6 +202,7 @@ class NIOConcurrencyHelpersTests: XCTestCase { testFor(UInt.self) } + @available(*, deprecated, message: "deprecated because it tests deprecated functionality") func testLoadStore() { func testFor(_ value: T.Type) { let zero: T = 0 @@ -220,6 +228,202 @@ class NIOConcurrencyHelpersTests: XCTestCase { testFor(UInt.self) } + func testLargeContendedNIOAtomicSum() { + let noAsyncs: UInt64 = 64 + let noCounts: UInt64 = 200_000 + + let q = DispatchQueue(label: "q", attributes: .concurrent) + let g = DispatchGroup() + let ai = NIOConcurrencyHelpers.NIOAtomic.makeAtomic(value: 0) + for thread in 1...noAsyncs { + q.async(group: g) { + for _ in 0...makeAtomic(value: true) + + XCTAssertFalse(ab.compareAndExchange(expected: false, desired: false)) + XCTAssertTrue(ab.compareAndExchange(expected: true, desired: true)) + + XCTAssertFalse(ab.compareAndExchange(expected: false, desired: false)) + XCTAssertTrue(ab.compareAndExchange(expected: true, desired: false)) + + XCTAssertTrue(ab.compareAndExchange(expected: false, desired: false)) + XCTAssertTrue(ab.compareAndExchange(expected: false, desired: true)) + } + + func testAllOperationsBoolNIOAtomic() { + let ab = NIOAtomic.makeAtomic(value: false) + XCTAssertEqual(false, ab.load()) + ab.store(false) + XCTAssertEqual(false, ab.load()) + ab.store(true) + XCTAssertEqual(true, ab.load()) + ab.store(true) + XCTAssertEqual(true, ab.load()) + XCTAssertEqual(true, ab.exchange(with: true)) + XCTAssertEqual(true, ab.exchange(with: false)) + XCTAssertEqual(false, ab.exchange(with: false)) + XCTAssertTrue(ab.compareAndExchange(expected: false, desired: true)) + XCTAssertFalse(ab.compareAndExchange(expected: false, desired: true)) + } + + func testCompareAndExchangeUIntsNIOAtomic() { + func testFor(_ value: T.Type) { + let zero: T = 0 + let max = ~zero + + let ab = NIOAtomic.makeAtomic(value: max) + + XCTAssertFalse(ab.compareAndExchange(expected: zero, desired: zero)) + XCTAssertTrue(ab.compareAndExchange(expected: max, desired: max)) + + XCTAssertFalse(ab.compareAndExchange(expected: zero, desired: zero)) + XCTAssertTrue(ab.compareAndExchange(expected: max, desired: zero)) + + XCTAssertTrue(ab.compareAndExchange(expected: zero, desired: zero)) + XCTAssertTrue(ab.compareAndExchange(expected: zero, desired: max)) + + var counter = max + for _ in 0..<255 { + XCTAssertTrue(ab.compareAndExchange(expected: counter, desired: counter-1)) + counter = counter - 1 + } + } + + testFor(UInt8.self) + testFor(UInt16.self) + testFor(UInt32.self) + testFor(UInt64.self) + testFor(UInt.self) + } + + func testCompareAndExchangeIntsNIOAtomic() { + func testFor(_ value: T.Type) { + let zero: T = 0 + let upperBound: T = 127 + + let ab = NIOAtomic.makeAtomic(value: upperBound) + + XCTAssertFalse(ab.compareAndExchange(expected: zero, desired: zero)) + XCTAssertTrue(ab.compareAndExchange(expected: upperBound, desired: upperBound)) + + XCTAssertFalse(ab.compareAndExchange(expected: zero, desired: zero)) + XCTAssertTrue(ab.compareAndExchange(expected: upperBound, desired: zero)) + + XCTAssertTrue(ab.compareAndExchange(expected: zero, desired: zero)) + XCTAssertTrue(ab.compareAndExchange(expected: zero, desired: upperBound)) + + var counter = upperBound + for _ in 0..<255 { + XCTAssertTrue(ab.compareAndExchange(expected: counter, desired: counter-1)) + XCTAssertFalse(ab.compareAndExchange(expected: counter, desired: counter)) + counter = counter - 1 + } + } + + testFor(Int8.self) + testFor(Int16.self) + testFor(Int32.self) + testFor(Int64.self) + testFor(Int.self) + } + + func testAddSubNIOAtomic() { + func testFor(_ value: T.Type) { + let zero: T = 0 + + let ab = NIOAtomic.makeAtomic(value: zero) + + XCTAssertEqual(0, ab.add(1)) + XCTAssertEqual(1, ab.add(41)) + XCTAssertEqual(42, ab.add(23)) + + XCTAssertEqual(65, ab.load()) + + XCTAssertEqual(65, ab.sub(23)) + XCTAssertEqual(42, ab.sub(41)) + XCTAssertEqual(1, ab.sub(1)) + + XCTAssertEqual(0, ab.load()) + } + + testFor(Int8.self) + testFor(Int16.self) + testFor(Int32.self) + testFor(Int64.self) + testFor(Int.self) + testFor(UInt8.self) + testFor(UInt16.self) + testFor(UInt32.self) + testFor(UInt64.self) + testFor(UInt.self) + } + + func testExchangeNIOAtomic() { + func testFor(_ value: T.Type) { + let zero: T = 0 + + let ab = NIOAtomic.makeAtomic(value: zero) + + XCTAssertEqual(0, ab.exchange(with: 1)) + XCTAssertEqual(1, ab.exchange(with: 42)) + XCTAssertEqual(42, ab.exchange(with: 65)) + + XCTAssertEqual(65, ab.load()) + + XCTAssertEqual(65, ab.exchange(with: 42)) + XCTAssertEqual(42, ab.exchange(with: 1)) + XCTAssertEqual(1, ab.exchange(with: 0)) + + XCTAssertEqual(0, ab.load()) + } + + testFor(Int8.self) + testFor(Int16.self) + testFor(Int32.self) + testFor(Int64.self) + testFor(Int.self) + testFor(UInt8.self) + testFor(UInt16.self) + testFor(UInt32.self) + testFor(UInt64.self) + testFor(UInt.self) + } + + func testLoadStoreNIOAtomic() { + func testFor(_ value: T.Type) { + let zero: T = 0 + + let ab = NIOAtomic.makeAtomic(value: zero) + + XCTAssertEqual(0, ab.load()) + ab.store(42) + XCTAssertEqual(42, ab.load()) + ab.store(0) + XCTAssertEqual(0, ab.load()) + } + + testFor(Int8.self) + testFor(Int16.self) + testFor(Int32.self) + testFor(Int64.self) + testFor(Int.self) + testFor(UInt8.self) + testFor(UInt16.self) + testFor(UInt32.self) + testFor(UInt64.self) + testFor(UInt.self) + } + + func testLockMutualExclusion() { let l = Lock() diff --git a/Tests/NIOTests/AcceptBackoffHandlerTest.swift b/Tests/NIOTests/AcceptBackoffHandlerTest.swift index 4a536088..5b7531ff 100644 --- a/Tests/NIOTests/AcceptBackoffHandlerTest.swift +++ b/Tests/NIOTests/AcceptBackoffHandlerTest.swift @@ -200,7 +200,7 @@ public final class AcceptBackoffHandlerTest: XCTestCase { let readCountHandler = ReadCountHandler() - let backoffProviderCalled = Atomic(value: 0) + let backoffProviderCalled = NIOAtomic.makeAtomic(value: 0) let serverChannel = try setupChannel(group: group, readCountHandler: readCountHandler, backoffProvider: { err in if backoffProviderCalled.add(1) == 0 { return .seconds(1) diff --git a/Tests/NIOTests/ChannelPipelineTest.swift b/Tests/NIOTests/ChannelPipelineTest.swift index a2061ff4..9bb7b9e8 100644 --- a/Tests/NIOTests/ChannelPipelineTest.swift +++ b/Tests/NIOTests/ChannelPipelineTest.swift @@ -163,8 +163,8 @@ class ChannelPipelineTest: XCTestCase { } private final class DummyHandler: ChannelHandler { - let handlerAddedCalled = Atomic(value: false) - let handlerRemovedCalled = Atomic(value: false) + let handlerAddedCalled = NIOAtomic.makeAtomic(value: false) + let handlerRemovedCalled = NIOAtomic.makeAtomic(value: false) public func handlerAdded(context: ChannelHandlerContext) { handlerAddedCalled.store(true) diff --git a/Tests/NIOTests/EchoServerClientTest.swift b/Tests/NIOTests/EchoServerClientTest.swift index 4108bdc1..1b893058 100644 --- a/Tests/NIOTests/EchoServerClientTest.swift +++ b/Tests/NIOTests/EchoServerClientTest.swift @@ -313,8 +313,8 @@ class EchoServerClientTest : XCTestCase { private final class CloseInInActiveAndUnregisteredChannelHandler: ChannelInboundHandler { typealias InboundIn = Never - let alreadyClosedInChannelInactive = Atomic(value: false) - let alreadyClosedInChannelUnregistered = Atomic(value: false) + let alreadyClosedInChannelInactive = NIOAtomic.makeAtomic(value: false) + let alreadyClosedInChannelUnregistered = NIOAtomic.makeAtomic(value: false) let channelUnregisteredPromise: EventLoopPromise let channelInactivePromise: EventLoopPromise @@ -723,8 +723,8 @@ class EchoServerClientTest : XCTestCase { defer { XCTAssertNoThrow(try group.syncShutdownGracefully()) } - let acceptedRemotePort: Atomic = Atomic(value: -1) - let acceptedLocalPort: Atomic = Atomic(value: -2) + let acceptedRemotePort: NIOAtomic = .makeAtomic(value: -1) + let acceptedLocalPort: NIOAtomic = .makeAtomic(value: -2) let sem = DispatchSemaphore(value: 0) let serverChannel: Channel diff --git a/Tests/NIOTests/EventLoopTest.swift b/Tests/NIOTests/EventLoopTest.swift index 86a9d7e0..91e71b90 100644 --- a/Tests/NIOTests/EventLoopTest.swift +++ b/Tests/NIOTests/EventLoopTest.swift @@ -73,7 +73,7 @@ public final class EventLoopTest : XCTestCase { defer { XCTAssertNoThrow(try eventLoopGroup.syncShutdownGracefully()) } - let ran = Atomic(value: false) + let ran = NIOAtomic.makeAtomic(value: false) let scheduled = eventLoopGroup.next().scheduleTask(in: .seconds(2)) { ran.store(true) } @@ -102,7 +102,7 @@ public final class EventLoopTest : XCTestCase { } let expect = expectation(description: "Is cancelling RepatedTask") - let counter = Atomic(value: 0) + let counter = NIOAtomic.makeAtomic(value: 0) let loop = eventLoopGroup.next() loop.scheduleRepeatedTask(initialDelay: initialDelay, delay: delay) { repeatedTask -> Void in XCTAssertTrue(loop.inEventLoop) @@ -592,8 +592,8 @@ public final class EventLoopTest : XCTestCase { class AssertHandler: ChannelInboundHandler { typealias InboundIn = Any - let groupIsShutdown = Atomic(value: false) - let removed = Atomic(value: false) + let groupIsShutdown = NIOAtomic.makeAtomic(value: false) + let removed = NIOAtomic.makeAtomic(value: false) public func handlerRemoved(context: ChannelHandlerContext) { XCTAssertFalse(groupIsShutdown.load()) @@ -614,7 +614,7 @@ public final class EventLoopTest : XCTestCase { channel.connect(to: serverSocket.localAddress!) } }.wait() as Void) - let closeFutureFulfilledEventually = Atomic(value: false) + let closeFutureFulfilledEventually = NIOAtomic.makeAtomic(value: false) XCTAssertFalse(channel.closeFuture.isFulfilled) channel.closeFuture.whenSuccess { XCTAssertTrue(closeFutureFulfilledEventually.compareAndExchange(expected: false, desired: true)) diff --git a/Tests/NIOTests/SelectorTest.swift b/Tests/NIOTests/SelectorTest.swift index e5ca694c..b5ddd87f 100644 --- a/Tests/NIOTests/SelectorTest.swift +++ b/Tests/NIOTests/SelectorTest.swift @@ -391,7 +391,7 @@ class SelectorTest: XCTestCase { protocol: 0, socketVector: &socketFDs)) - let numberFires = Atomic(value: 0) + let numberFires = NIOAtomic.makeAtomic(value: 0) let el = group.next() as! SelectableEventLoop let channelHasBeenClosedPromise = el.makePromise(of: Void.self) let channel = try SocketChannel(socket: FakeSocket(hasBeenClosedPromise: channelHasBeenClosedPromise, diff --git a/Tests/NIOTests/SocketChannelTest.swift b/Tests/NIOTests/SocketChannelTest.swift index 2ead3bcd..c4de6822 100644 --- a/Tests/NIOTests/SocketChannelTest.swift +++ b/Tests/NIOTests/SocketChannelTest.swift @@ -51,7 +51,7 @@ public final class SocketChannelTest : XCTestCase { // Ensure we can dispatch two concurrent set option's on each others // event loops. - let condition = Atomic(value: 0) + let condition = NIOAtomic.makeAtomic(value: 0) let futureA = channelA.eventLoop.submit { _ = condition.add(1) while condition.load() < 2 { } @@ -684,7 +684,7 @@ public final class SocketChannelTest : XCTestCase { func testServerChannelDoesNotBreakIfAcceptingFailsWithEINVAL() throws { // regression test for https://github.com/apple/swift-nio/issues/1030 class HandsOutMoodySocketsServerSocket: ServerSocket { - let shouldAcceptsFail: Atomic = .init(value: true) + let shouldAcceptsFail: NIOAtomic = .makeAtomic(value: true) override func accept(setNonBlocking: Bool = false) throws -> Socket? { XCTAssertTrue(setNonBlocking) if self.shouldAcceptsFail.load() { diff --git a/docker/docker-compose.1604.51.yaml b/docker/docker-compose.1604.51.yaml index 10b5a846..f7186d13 100644 --- a/docker/docker-compose.1604.51.yaml +++ b/docker/docker-compose.1604.51.yaml @@ -18,9 +18,9 @@ services: test: image: swift-nio:16.04-5.1 environment: - - MAX_ALLOCS_ALLOWED_1000_reqs_1_conn=30550 - - MAX_ALLOCS_ALLOWED_1_reqs_1000_conn=533050 - - MAX_ALLOCS_ALLOWED_ping_pong_1000_reqs_1_conn=4450 + - MAX_ALLOCS_ALLOWED_1000_reqs_1_conn=30540 + - MAX_ALLOCS_ALLOWED_1_reqs_1000_conn=522050 + - MAX_ALLOCS_ALLOWED_ping_pong_1000_reqs_1_conn=4440 - MAX_ALLOCS_ALLOWED_bytebuffer_lots_of_rw=2100 - MAX_ALLOCS_ALLOWED_future_lots_of_callbacks=75010 - MAX_ALLOCS_ALLOWED_creating_10000_headers=10100 diff --git a/docker/docker-compose.1804.50.yaml b/docker/docker-compose.1804.50.yaml index 6f0af55e..711db419 100644 --- a/docker/docker-compose.1804.50.yaml +++ b/docker/docker-compose.1804.50.yaml @@ -18,9 +18,9 @@ services: test: image: swift-nio:18.04-5.0 environment: - - MAX_ALLOCS_ALLOWED_1000_reqs_1_conn=30970 - - MAX_ALLOCS_ALLOWED_1_reqs_1000_conn=994050 - - MAX_ALLOCS_ALLOWED_ping_pong_1000_reqs_1_conn=4480 + - MAX_ALLOCS_ALLOWED_1000_reqs_1_conn=30990 + - MAX_ALLOCS_ALLOWED_1_reqs_1000_conn=1005050 + - MAX_ALLOCS_ALLOWED_ping_pong_1000_reqs_1_conn=4500 - MAX_ALLOCS_ALLOWED_bytebuffer_lots_of_rw=2100 - MAX_ALLOCS_ALLOWED_future_lots_of_callbacks=75010 - MAX_ALLOCS_ALLOWED_scheduling_10000_executions=20150