15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright © 2007  Chris Wilson
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright © 2009,2010  Red Hat, Inc.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright © 2011,2012  Google, Inc.
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  This is part of HarfBuzz, a text shaping library.
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Permission is hereby granted, without written agreement and without
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * license or royalty fees, to use, copy, modify, and distribute this
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * software and its documentation for any purpose, provided that the
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * above copyright notice and the following two paragraphs appear in
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * all copies of this software.
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * DAMAGE.
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Contributor(s):
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *	Chris Wilson <chris@chris-wilson.co.uk>
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Red Hat Author(s): Behdad Esfahbod
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Google Author(s): Behdad Esfahbod
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef HB_ATOMIC_PRIVATE_HH
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_ATOMIC_PRIVATE_HH
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "hb-private.hh"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* atomic_int */
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* We need external help for these */
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if 0
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#elif !defined(HB_NO_MT) && (defined(_WIN32) || defined(__CYGWIN__))
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h>
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)/* MinGW has a convoluted history of supporting MemoryBarrier
5023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) * properly.  As such, define a function to wrap the whole
5123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) * thing. */
527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)static inline void _HBMemoryBarrier (void) {
5323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#if !defined(MemoryBarrier)
547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  long dummy = 0;
557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  InterlockedExchange (&dummy, 1);
5623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#else
5723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  MemoryBarrier ();
587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
5923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef LONG hb_atomic_int_t;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define hb_atomic_int_add(AI, V)	InterlockedExchangeAdd (&(AI), (V))
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#define hb_atomic_ptr_get(P)		(_HBMemoryBarrier (), (void *) *(P))
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define hb_atomic_ptr_cmpexch(P,O,N)	(InterlockedCompareExchangePointer ((void **) (P), (void *) (N), (void *) (O)) == (void *) (O))
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif !defined(HB_NO_MT) && defined(__APPLE__)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libkern/OSAtomic.h>
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifdef __MAC_OS_X_MIN_REQUIRED
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <AvailabilityMacros.h>
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#elif defined(__IPHONE_OS_MIN_REQUIRED)
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <Availability.h>
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef int32_t hb_atomic_int_t;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define hb_atomic_int_add(AI, V)	(OSAtomicAdd32Barrier ((V), &(AI)) - (V))
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define hb_atomic_ptr_get(P)		(OSMemoryBarrier (), (void *) *(P))
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if (MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_4 || __IPHONE_VERSION_MIN_REQUIRED >= 20100)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define hb_atomic_ptr_cmpexch(P,O,N)	OSAtomicCompareAndSwapPtrBarrier ((void *) (O), (void *) (N), (void **) (P))
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if __ppc64__ || __x86_64__ || __aarch64__
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define hb_atomic_ptr_cmpexch(P,O,N)    OSAtomicCompareAndSwap64Barrier ((int64_t) (O), (int64_t) (N), (int64_t*) (P))
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define hb_atomic_ptr_cmpexch(P,O,N)    OSAtomicCompareAndSwap32Barrier ((int32_t) (O), (int32_t) (N), (int32_t*) (P))
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef int hb_atomic_int_t;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define hb_atomic_int_add(AI, V)	__sync_fetch_and_add (&(AI), (V))
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define hb_atomic_ptr_get(P)		(void *) (__sync_synchronize (), *(P))
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define hb_atomic_ptr_cmpexch(P,O,N)	__sync_bool_compare_and_swap ((P), (O), (N))
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#elif !defined(HB_NO_MT) && defined(HAVE_SOLARIS_ATOMIC_OPS)
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <atomic.h>
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <mbarrier.h>
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)typedef unsigned int hb_atomic_int_t;
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define hb_atomic_int_add(AI, V)	( ({__machine_rw_barrier ();}), atomic_add_int_nv (&(AI), (V)) - (V))
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define hb_atomic_ptr_get(P)		( ({__machine_rw_barrier ();}), (void *) *(P))
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define hb_atomic_ptr_cmpexch(P,O,N)	( ({__machine_rw_barrier ();}), atomic_cas_ptr ((void **) (P), (void *) (O), (void *) (N)) == (void *) (O) ? true : false)
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif !defined(HB_NO_MT)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_ATOMIC_INT_NIL 1 /* Warn that fallback implementation is in use. */
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef volatile int hb_atomic_int_t;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define hb_atomic_int_add(AI, V)	(((AI) += (V)) - (V))
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define hb_atomic_ptr_get(P)		((void *) *(P))
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define hb_atomic_ptr_cmpexch(P,O,N)	(* (void * volatile *) (P) == (void *) (O) ? (* (void * volatile *) (P) = (void *) (N), true) : false)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else /* HB_NO_MT */
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef int hb_atomic_int_t;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define hb_atomic_int_add(AI, V)	(((AI) += (V)) - (V))
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define hb_atomic_ptr_get(P)		((void *) *(P))
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define hb_atomic_ptr_cmpexch(P,O,N)	(* (void **) (P) == (void *) (O) ? (* (void **) (P) = (void *) (N), true) : false)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* TODO Add tracing. */
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* HB_ATOMIC_PRIVATE_HH */
136