Currently, there is no formal introduction of the atomic type corresponding to the basic type in Swift 3.0. In MacOS and iOS, we can use the system's own Osatomic API for atomic manipulation processing. But this set of APIs can only be used on Apple's own platforms and we can't use them in Linux/freebsd, so I've encapsulated a set of atomic types and atomic operations that conform to the C11 standard to the SWIFT programming language.
Currently in Swift, if we declare a global object such as atomic_int type in the C language header file, then the object cannot be imported in swift, because atomic_int The type cannot be converted to the appropriate type that it can recognize in Swift. So, my idea here is to encapsulate the atomic types supported in the C11 standard through the structure. I encapsulated 3 atomic types in the following code: Atomic_int, Atomic_bool, and atomic_uint_fast64_t, respectively, representing the int atomic type, the Boolean atom type, and the unsigned 64-bit integer atomic type. The project I am building here is named Swifttest, so the bridge header file required by Swift is named swifttest-bridging-header.h. The complete source code for this header file is given below:
#include <stdint.h> #include <stdbool.h> #include <stdatomic.h>/** atomicint atom type for swift */struct at
omicintswift {volatile atomic_int atom;}; /** * Initialize Atomic objects * @param Patom point to an Atomic object of type Atomicint in Swift, and does not allow NULL * @param value to specify the values to initialize for atomic objects */extern void __attribut
e__ ((overloadable)) atomicswiftinit (struct atomicintswift* __nonnull patom, int value); /** * Loading an Atomic object * @param patom points to an atomic object of type Atomicint in swift and does not allow NULL * @return Specifies the value stored by the Atomic object */extern int __attribute__ (ov
erloadable)) atomicswiftload (struct atomicintswift* __nonnull patom); /** * Storing operations on atomic objects * @param patom to an Atomic object of type Atomicint in Swift, and does not allow NULL * @param value to store to the specified atomic object */extern void __attrib
ute__ ((overloadable)) atomicswiftstore (struct atomicintswift* __nonnull patom, int value);
/** * Swaps the values stored in an atomic object with the values of the specified base type. * That is, the value of the base type is stored in an atomic object, and the original value of the atomic object is returned * @param patom points to an atomic object of type Atomicint in swift and does not allow the value of the base type specified by the null * @param value * @ret The original value of the urn Atom object */extern int __attribute__ ((overloadable)) atomicswiftexchange (struct atomicintswift* __nonnull patom, int value); /** * Atomic comparison and Exchange * * Compares the value in an atomic object to the value of expected and, if the same, writes the value of desired to an atomic object and returns true; * Otherwise, writes the value in the current atomic object to expected and returns false * @p
Aram Patom points to an atomic object of type Atomicint in swift and does not allow NULL * @param expected to hold a pointer to a value that is compared to an atomic object.
* This pointer generally points to a variable with the value obtained by the atomic load operation and cannot be null. * @param desired The value to be deposited into the atomic object * @return Returns True if the value in the expected is the same as the value stored in the Atomic object, otherwise false */extern bool __attribute__ (Overlo
adable)) Atomicswiftcas (struct atomicintswift* __nonnull patom, int* __nonnull expected, int desired); /** * Atomic addition operation * @param patom pointer to an atomic object of type Atomicint in swift and does not allow the value of the base type specified by the null * @param value * @return The original value of the Atomic object */extern int
__attribute__ ((overloadable)) atomicswiftfetchadd (struct atomicintswift* __nonnull patom, int value); /** * Atomic Subtraction operation * @param patom points to an atomic object of type Atomicint in swift and does not allow the value of the base type specified by the null * @param value * @return The original value of the Atomic object */extern int __attribute__ ((overloadable)) atomicswiftfetchsub (struct atomicintswift* __nonnull patom, int value); /** * Atom Bitwise OR Operation * @param patom points to an atomic object of type Atomicint in swift and does not allow the value of the base type specified by the null * @param value * @return The original value of the Atomic object */extern in
T __attribute__ ((overloadable)) atomicswiftfetchor (struct atomicintswift* __nonnull patom, int value); /** * Atomic Bitwise XOR OR Operation * @param patom points to an atomic object of type Atomicint in swift and does not allow the value of the base type specified by the null * @param value * @return The original value of the Atomic object */extern I
NT __attribute__ ((overloadable)) atomicswiftfetchxor (struct atomicintswift* __nonnull patom, int value); /** * Atomic Bitwise AND Operation * @param patom points to an atomic object of type Atomicint in swift and does not allow the value of the base type specified by the null * @param value * @return The original value of the Atomic object */extern in
T __attribute__ ((overloadable)) Atomicswiftfetchand (struct atomicintswift* __nonnull patom, int value);
/** atomicbool Atomic type for Swift */struct Atomicboolswift {volatile atomic_bool atom;}; /** * Initialize Atomic objects * @param Patom point to an Atomic object of type Atomicbool in Swift, and does not allow NULL * @param value to specify the values to initialize for atomic objects */extern void __attribu
te__ ((overloadable)) atomicswiftinit (struct atomicboolswift* __nonnull patom, bool value); /** * on the originalChild Object Loading operation * @param patom points to an atomic object of type Atomicbool in Swift, and does not allow NULL * @return Specifies the value stored by the Atomic object */extern bool __attribute__ (Overloada
ble)) atomicswiftload (struct atomicboolswift* __nonnull patom); /** * Storing operations on atomic objects * @param patom to an Atomic object of type Atomicbool in Swift, and does not allow NULL * @param value to store to the specified atomic object */extern void __attri
bute__ ((overloadable)) atomicswiftstore (struct atomicboolswift* __nonnull patom, bool value);
/** * Swaps the values stored in an atomic object with the values of the specified base type. * That is, the value of the base type is stored in an atomic object, and the original value of the atomic object is returned * @param patom points to an atomic object of type Atomicbool in swift and does not allow the value of the base type specified by the null * @param value * @re Turn atomic object's original value */extern bool __attribute__ ((overloadable)) atomicswiftexchange (struct atomicboolswift* __nonnull patom,
bool value); /** * Atomic comparison and Exchange * * Compares the value in an atomic object to the value of expected and, if the same, writes the value of desired to an atomic object and returns true; * Otherwise, writes the value in the current atomic object to expected and returns false * @p
Aram Patom points to an atomic object of type Atomicbool in swift and does not allow NULL * @param expected to hold a pointer to a value that is compared to an atomic object.
* This pointer generally points to a variable with the value obtained by the atomic load operation and cannot be null. * @param desired The value to be deposited into the atomic object * @return if the expectedReturns True if the value is the same as the value stored in the Atomic object, or FALSE */extern bool __attribute__ ((overloadable)) Atomicswiftcas (struct atomicboolswift
* __nonnull Patom, bool* __nonnull expected, BOOL desired);
/** Atomiculong Atomic type for Swift */struct Atomiculongswift {volatile atomic_uint_fast64_t atom;}; /** * Initialize Atomic objects * @param Patom point to an Atomic object of type Atomiculong in Swift, and does not allow NULL * @param value to specify the values to initialize for atomic objects */extern void __attrib
ute__ ((overloadable)) atomicswiftinit (struct atomiculongswift* __nonnull patom, uint64_t value); /** * Loading an Atomic object * @param patom points to an atomic object of type Atomiculong in swift and does not allow NULL * @return Specifies the value stored by the Atomic object */extern uint64_t __attribut
e__ ((overloadable)) atomicswiftload (struct atomiculongswift* __nonnull patom); /** * Storing operations on atomic objects * @param patom to an Atomic object of type Atomiculong in Swift, and does not allow NULL * @param value to store to the specified atomic object */extern void __attri
bute__ ((overloadable)) atomicswiftstore (struct atomiculongswift* __nonnull patom, uint64_t value);
/** * Swaps the values stored in an atomic object with the values of the specified base type. * That is, the value of the base type is stored in the atomic object and the original value of the atomic object is returned * @param Patom points to an atomic object of type Atomiculong in swift and does not allow the value of the base type specified by the null * @param value * @return The original value of the Atomic object */extern uint64_t __attrib
ute__ ((overloadable)) atomicswiftexchange (struct atomiculongswift* __nonnull patom, uint64_t value); /** * Atomic comparison and Exchange * * Compares the value in an atomic object to the value of expected and, if the same, writes the value of desired to an atomic object and returns true; * Otherwise, writes the value in the current atomic object to expected and returns false * @p
Aram Patom points to an atomic object of type Atomiculong in swift and does not allow NULL * @param expected to hold a pointer to a value that is compared to an atomic object.
* This pointer generally points to a variable with the value obtained by the atomic load operation and cannot be null. * @param desired The value to be deposited into the atomic object * @return Returns True if the value in the expected is the same as the value stored in the Atomic object, otherwise false */extern bool __attribute__ (Overlo
adable) Atomicswiftcas (struct atomiculongswift* __nonnull patom, uint64_t* __nonnull expected, uint64_t desired); /** * Atomic addition operation * @param patom points to an atomic object of type Atomiculong in swift and does not allow the value of the base type specified by the null * @param value * @return The original value of the Atomic object */extern u
int64_t __attribute__ ((overloadable)) atomicswiftfetchadd (struct atomiculongswift* __nonnull pAtom, uint64_t value); /** * Atomic Subtraction operation * @param Patom point to Swift AtomicAn atomic object of type ulong and does not allow the value of the base type specified by the null * @param value * @return The original value of the Atomic object */extern uint64_t __attribute__ ((overloadable)) Atomic
Swiftfetchsub (struct atomiculongswift* __nonnull patom, uint64_t value); /** * Atom Bitwise OR Operation * @param patom points to an atomic object of type Atomiculong in Swift, and does not allow the value of the base type specified by the null * @param value * @return The original value of the Atomic object */extern
uint64_t __attribute__ ((overloadable)) atomicswiftfetchor (struct atomiculongswift* __nonnull pAtom, uint64_t value); /** * Atomic Bitwise XOR OR Operation * @param patom points to an atomic object of type Atomiculong in swift and does not allow the value of the base type specified by the null * @param value * @return The original value of the Atomic object */extern
uint64_t __attribute__ ((overloadable)) atomicswiftfetchxor (struct atomiculongswift* __nonnull pAtom, uint64_t value); /** * Atomic Bitwise AND Operation * @param patom points to an atomic object of type Atomiculong in Swift, and does not allow the value of the base type specified by the null * @param value * @return The original value of the Atomic object */extern
uint64_t __attribute__ ((overloadable)) Atomicswiftfetchand (struct atomiculongswift* __nonnull pAtom, uint64_t value);
The above code lists the package implementations of the C language underlying C11 standard atomic operations that we need later in Swift. Below we can implement these declared function interfaces in a C source file (. c file).
#include <stdio.h> #include "swifttest-bridging-header.h" #pragma mark-atomic int void __attribute__ (Overloadab
Le)) atomicswiftinit (struct atomicintswift* __nonnull patom, int value) {if (Patom = = NULL) return;
Atomic_init (&patom->atom, value);
} int __attribute__ ((overloadable)) atomicswiftload (struct atomicintswift* __nonnull patom) {if (Patom = = NULL)
return 0;
Return Atomic_load (&patom->atom); } void __attribute__ ((overloadable)) atomicswiftstore (struct atomicintswift* __nonnull patom, int value) {if (Patom =
= NULL) return;
Atomic_store (&patom->atom, value); } int __attribute__ ((overloadable)) atomicswiftexchange (struct atomicintswift* __nonnull patom, int value) {if (patom
= = NULL) return 0;
Return Atomic_exchange (&patom->atom, value); } bool __attribute__ ((overloadable)) Atomicswiftcas (struct atomicintswift* __nonnull patom, int* __nonnull expected, int Desired) {if (Patom = = NULL | | expected = = NULL) return false;
Return Atomic_compare_exchange_weak (&patom->atom, expected, desired); } int __attribute__ ((overloadable)) atomicswiftfetchadd (struct atomicintswift* __nonnull patom, int value) {if (patom
= = NULL) return 0;
Return Atomic_fetch_add (&patom->atom, value); } int __attribute__ ((overloadable)) atomicswiftfetchsub (struct atomicintswift* __nonnull patom, int value) {if (patom
= = NULL) return 0;
Return Atomic_fetch_sub (&patom->atom, value); } int __attribute__ ((overloadable)) atomicswiftfetchor (struct atomicintswift* __nonnull patom, int value) {if (patom
= = NULL) return 0;
Return Atomic_fetch_or (&patom->atom, value); } int __attribute__ ((overloadable)) atomicswiftfetchxor (struct atomicintswift* __nonnull patom, int value) {if (patom
= = NULL) return 0; Return Atomic_fetch_xor (&patom->atom, VALue); } int __attribute__ ((overloadable)) Atomicswiftfetchand (struct atomicintswift* __nonnull patom, int value) {if (patom
= = NULL) return 0;
Return Atomic_fetch_and (&patom->atom, value); } #pragma mark-atomic bool void __attribute__ ((overloadable)) atomicswiftinit (struct atomicboolswift* __nonnull pAtom
, bool value) {if (Patom = = NULL) return;
Atomic_init (&patom->atom, value);
} bool __attribute__ ((overloadable)) atomicswiftload (struct atomicboolswift* __nonnull patom) {if (Patom = = NULL)
return false;
Return Atomic_load (&patom->atom); } void __attribute__ ((overloadable)) atomicswiftstore (struct atomicboolswift* __nonnull patom, bool value) {if (patom
= = NULL) return;
Atomic_store (&patom->atom, value); } bool __attribute__ ((overloadable)) atomicswiftexchange (struct atomicboolswift* __nonnull patom, bool value) {if (PA
Tom = = NULL) return false;Return Atomic_exchange (&patom->atom, value); } bool __attribute__ ((overloadable)) Atomicswiftcas (struct atomicboolswift* __nonnull patom, bool* __nonnull expected, b
Ool desired) {if (Patom = = NULL | | expected = = NULL) return false;
Return Atomic_compare_exchange_weak (&patom->atom, expected, desired); } #pragma mark-atomic uint64_t void __attribute__ ((overloadable)) atomicswiftinit (struct atomiculongswift* __nonnull
Patom, uint64_t value) {if (Patom = = NULL) return;
Atomic_init (&patom->atom, value); } uint64_t __attribute__ ((overloadable)) atomicswiftload (struct atomiculongswift* __nonnull patom) {if (PAtom = = NULL
) return 0;
Return Atomic_load (&patom->atom); } void __attribute__ ((overloadable)) atomicswiftstore (struct atomiculongswift* __nonnull patom, uint64_t value) {if (
Patom = = NULL) return;
Atomic_store (&patom->atom, value); } uint64_t __attribute__ ((Overloadable)) atomicswiftexchange (struct atomiculongswift* __nonnull patom, uint64_t value) {if (Patom = = NULL) r
Eturn 0;
Return Atomic_exchange (&patom->atom, value); } bool __attribute__ ((overloadable)) Atomicswiftcas (struct atomiculongswift* __nonnull patom, uint64_t* __nonnull
expected, uint64_t desired) {if (Patom = = NULL | | expected = NULL) return false;
Return Atomic_compare_exchange_weak (&patom->atom, expected, desired);
} uint64_t __attribute__ ((overloadable)) atomicswiftfetchadd (struct atomiculongswift* __nonnull pAtom, uint64_t value)
{if (Patom = = NULL) return 0;
Return Atomic_fetch_add (&patom->atom, value);
} uint64_t __attribute__ ((overloadable)) atomicswiftfetchsub (struct atomiculongswift* __nonnull pAtom, uint64_t value)
{if (Patom = = NULL) return 0;
Return Atomic_fetch_sub (&patom->atom, value); } uint64_t __attribute__ ((overloadable)) Atomicswiftfetchor (StruCT atomiculongswift* __nonnull patom, uint64_t value) {if (Patom = NULL) return 0;
Return Atomic_fetch_or (&patom->atom, value);
} uint64_t __attribute__ ((overloadable)) atomicswiftfetchxor (struct atomiculongswift* __nonnull pAtom, uint64_t value)
{if (Patom = = NULL) return 0;
Return Atomic_fetch_xor (&patom->atom, value);
} uint64_t __attribute__ ((overloadable)) Atomicswiftfetchand (struct atomiculongswift* __nonnull pAtom, uint64_t value)
{if (Patom = = NULL) return 0;
Return Atomic_fetch_and (&patom->atom, value);
}
We see that this package implementation is not very complex. In order for atomic operations to be more oo in swift, I abstracted each atomic type into a struct in swift. Let's look at the swift source file:
/** Atomic type protocol to be followed for all atomic types */
Public protocol Atomictype {
/** the base type that corresponds to the current atomic type */
Associatedtype Rawtype
/** initializes the current atomic object to a value of 0. It does not have atomicity */
Init ()
/**
The initializer that initializes the current atomic object to the value specified by the parameter. It has no atomicity.
-Parameters:
-Value: The initial value initialized for the current atomic object
*/
Init (Value:rawtype)
/**
Loads the current atomic object's value and returns it.
-Returns: The value of the base type that corresponds to the current atomic object
*/
Mutatingfunc load (), Rawtype
/**
Holds a specified base type value into the current atomic object
-Parameters:
-value: Specifies the values of the base type to hold
*/
Mutatingfunc Store (by Value:rawtype)
/**
Stores the value of the specified base type in the current atomic object and returns the original value of the atomic object before it is deposited
-Parameters:
-Value: The values of the specified base type
-Returns: The original value of the atomic object before the specified value is deposited
*/
Mutatingfunc Exchange (with Value:rawtype), Rawtype
/**
Atomic comparison and exchange.
The value of the current atomic object is compared to the value of expected, and if the same, the value of desired is stored in the current atomic object and returns true;
Otherwise, the value of the current atomic object is stored in expected and then returned false.
-Parameters:
-expected: Pointer to the primitive type object.
This primitive type object typically loads the value of the current atomic object in the Load method before calling the function.
-Desired: The final value to write
-Returns: Returns True if the value of the current atomic object is the same as the value in expected, otherwise false
*/
Mutatingfunc cas (expected:unsafemutablepointer<rawtype>, Desired:rawtype)->bool
/**
Atomic addition operations
-Parameters:
-Operand: addition operand
-Returns: The original value of the atomic object before the addition operation
*/
Mutatingfunc Fetch_add (operand:rawtype), Rawtype
/**
Atomic subtraction Operations
-Parameters:
-Operand: subtraction operand
-Returns: The original value of the atomic object before the subtraction operation
*/
Mutatingfunc fetch_sub (operand:rawtype), Rawtype