I understand that InterlockedExchange64 works to implement a 64-bit store. I also understand 32-bit builds use it for 64-bit atomic stores: because 32-bit code cannot otherwise store to 64-bit objects. I don't understand why 64-bit code would use it for 64-bit atomic stores; it does not make any sense for MSVC to convert such a store to two 32-bit instructions, and I doubt that it does.
Here's the code I'm talking about: /* MSVC converts 64 bit writes into two instructions. So there is * a possibility that an interrupt can make a 64 bit write non-atomic even * when 8 byte aligned. So use InterlockedExchange64(). * * For atomic stores, 'consume' and 'acquire' semantics are not valid. But we * are using 'Exchange' to get atomic stores here and we only have * InterlockedExchange64(), InterlockedExchangeNoFence64() and * InterlockedExchange64Acquire() available. So we are forced to use * InterlockedExchange64() which uses full memory barrier for everything * greater than 'memory_order_relaxed'. */ #define atomic_store64(DST, SRC, ORDER) \ if (ORDER == memory_order_relaxed) { \ InterlockedExchangeNoFence64((int64_t volatile *) (DST), \ (int64_t) (SRC)); \ } else { \ InterlockedExchange64((int64_t volatile *) (DST), (int64_t) (SRC));\ } Similarly for atomic_read64(): /* MSVC converts 64 bit reads into two instructions. So there is * a possibility that an interrupt can make a 64 bit read non-atomic even * when 8 byte aligned. So use fully memory barrier InterlockedOr64(). */ #define atomic_read64(SRC, DST, ORDER) \ __pragma (warning(push)) \ __pragma (warning(disable:4047)) \ *(DST) = InterlockedOr64((int64_t volatile *) (SRC), 0); \ __pragma (warning(pop)) On Tue, Mar 29, 2016 at 04:20:13PM +0000, Sorin Vinturis wrote: > Ben, ovs-atomic-msvc.h contains support for 8,16,32 and 64-bit arithmetic and > logical operations. > Regarding 64-bit operations, like read and write, they are performed using > specific 64-bit interlocked functions, i.e. InterlockedCompareExchange64 and, > respectivelly, InterlockedOr64. Both functions are performed atomically. > > All remaining 64-bit operations use, also, 64-bit interlocked functions, > which are executed atomically, except for logical AND operation. For the > latter operation, an intrinsic function is used, _InterlockedExchangeAdd64, > which means that is a faster function built in to the compiler. More details > about this is here: > https://msdn.microsoft.com/ro-ro/library/26td21ds(v=vs.80).aspx. > > > -----Original Message----- > From: Ben Pfaff [mailto:b...@ovn.org] > Sent: Tuesday, 29 March, 2016 00:25 > To: Sorin Vinturis > Cc: Guru Shetty; dev@openvswitch.org > Subject: Re: [ovs-dev] [PATCH] datapath-windows: Add Windows thread atomic > APIs for x64 binaries. > > On Mon, Mar 28, 2016 at 09:11:24PM +0000, Sorin Vinturis wrote: > > Hi Guru, > > > > I have verified the ovs-atomic-msvc.h header and all the defined > > macros and functions have 32-bit and 64-bit correspondent. All 64-bit > > macros use InterlockedXXX functions that are atomic: > > InterlockedExchangeNoFence64, InterlockedExchange64, > > InterlockedCompareExchange64, _InterlockedExchangeAdd64, > > InterlockedAnd64, InterlockedOr64, InterlockedXor64. I have ran > > test-atomic.c unit tests, on both 32-bit and 64-bit platforms, and all > > the tests are verified. > > > > I also tested the 64-bit build on Hyper-V and it is stable. > > > > Is there a reason why we should not use ovs-atomic-msvc APIs for 64-bit > > builds? > > ovs-atomic-msvc.h seems pretty oriented toward a 32-bit build. At least, I > really doubt MSVC would break 64-bit reads and writes into two 32-bit reads > and writes on 64-bit builds, which is what the code in the header currently > assumes. You don't want to update it to handle 64-bit builds differently? I > guess that these would be optimizations, but they seem straightforward. _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev