156eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod/*
256eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod * Copyright © 2007  Chris Wilson
356eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod * Copyright © 2009,2010  Red Hat, Inc.
4cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbod * Copyright © 2011,2012  Google, Inc.
556eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod *
656eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod *  This is part of HarfBuzz, a text shaping library.
756eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod *
856eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod * Permission is hereby granted, without written agreement and without
956eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod * license or royalty fees, to use, copy, modify, and distribute this
1056eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod * software and its documentation for any purpose, provided that the
1156eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod * above copyright notice and the following two paragraphs appear in
1256eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod * all copies of this software.
1356eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod *
1456eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
1556eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
1656eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
1756eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
1856eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod * DAMAGE.
1956eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod *
2056eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
2156eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
2256eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
2356eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
2456eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
2556eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod *
2656eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod * Contributor(s):
2756eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod *	Chris Wilson <chris@chris-wilson.co.uk>
2856eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod * Red Hat Author(s): Behdad Esfahbod
2956eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod * Google Author(s): Behdad Esfahbod
3056eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod */
3156eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod
3256eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod#ifndef HB_MUTEX_PRIVATE_HH
3356eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod#define HB_MUTEX_PRIVATE_HH
3456eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod
3556eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod#include "hb-private.hh"
3656eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod
3756eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod
3856eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod/* mutex */
3956eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod
4056eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod/* We need external help for these */
4156eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod
42022a05ae90f30bcddff413022e0cd801809b5390Behdad Esfahbod#if 0
4356eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod
44022a05ae90f30bcddff413022e0cd801809b5390Behdad Esfahbod
45a6c1e040e594faeefd61b456ef995c7886cdea78Behdad Esfahbod#elif !defined(HB_NO_MT) && (defined(_WIN32) || defined(__CYGWIN__))
4656eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod
47f60271c0c2b0101e7b2725f9a9ad950c277a616cBehdad Esfahbod#include <windows.h>
48831886a9b4073cfe27f7e1db0e957cbd5913fd31Behdad Esfahbodtypedef CRITICAL_SECTION hb_mutex_impl_t;
49831886a9b4073cfe27f7e1db0e957cbd5913fd31Behdad Esfahbod#define HB_MUTEX_IMPL_INIT	{ NULL, 0, 0, NULL, NULL, 0 }
50831886a9b4073cfe27f7e1db0e957cbd5913fd31Behdad Esfahbod#define hb_mutex_impl_init(M)	InitializeCriticalSection (M)
51831886a9b4073cfe27f7e1db0e957cbd5913fd31Behdad Esfahbod#define hb_mutex_impl_lock(M)	EnterCriticalSection (M)
52831886a9b4073cfe27f7e1db0e957cbd5913fd31Behdad Esfahbod#define hb_mutex_impl_unlock(M)	LeaveCriticalSection (M)
530e253e97af71e2a7ead153589f61fd579a247502Behdad Esfahbod#define hb_mutex_impl_finish(M)	DeleteCriticalSection (M)
5456eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod
5534961e3198e27fa37fd4cfdad12ef86a2e9e51c2Behdad Esfahbod
56cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbod#elif !defined(HB_NO_MT) && (defined(HAVE_PTHREAD) || defined(__APPLE__))
57a1970d9afc15b2c6b7513b923019bb223bd95154Behdad Esfahbod
58a1970d9afc15b2c6b7513b923019bb223bd95154Behdad Esfahbod#include <pthread.h>
59a1970d9afc15b2c6b7513b923019bb223bd95154Behdad Esfahbodtypedef pthread_mutex_t hb_mutex_impl_t;
60a1970d9afc15b2c6b7513b923019bb223bd95154Behdad Esfahbod#define HB_MUTEX_IMPL_INIT	PTHREAD_MUTEX_INITIALIZER
61a1970d9afc15b2c6b7513b923019bb223bd95154Behdad Esfahbod#define hb_mutex_impl_init(M)	pthread_mutex_init (M, NULL)
62a1970d9afc15b2c6b7513b923019bb223bd95154Behdad Esfahbod#define hb_mutex_impl_lock(M)	pthread_mutex_lock (M)
63a1970d9afc15b2c6b7513b923019bb223bd95154Behdad Esfahbod#define hb_mutex_impl_unlock(M)	pthread_mutex_unlock (M)
640e253e97af71e2a7ead153589f61fd579a247502Behdad Esfahbod#define hb_mutex_impl_finish(M)	pthread_mutex_destroy (M)
6556eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod
6634961e3198e27fa37fd4cfdad12ef86a2e9e51c2Behdad Esfahbod
6704bc1eebe7a304c0e6f86ab6814c65889f152602Behdad Esfahbod#elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES)
68cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbod
69cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbod#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_YIELD)
70cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbod# include <sched.h>
71cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbod# define HB_SCHED_YIELD() sched_yield ()
7256eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod#else
73cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbod# define HB_SCHED_YIELD() HB_STMT_START {} HB_STMT_END
74cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbod#endif
7556eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod
76cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbod/* This actually is not a totally awful implementation. */
77daa446f184fa27c9764ff7f8a2444d47cf34d986Behdad Esfahbodtypedef volatile int hb_mutex_impl_t;
78831886a9b4073cfe27f7e1db0e957cbd5913fd31Behdad Esfahbod#define HB_MUTEX_IMPL_INIT	0
79cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbod#define hb_mutex_impl_init(M)	*(M) = 0
80cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbod#define hb_mutex_impl_lock(M)	HB_STMT_START { while (__sync_lock_test_and_set((M), 1)) HB_SCHED_YIELD (); } HB_STMT_END
81cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbod#define hb_mutex_impl_unlock(M)	__sync_lock_release (M)
82cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbod#define hb_mutex_impl_finish(M)	HB_STMT_START {} HB_STMT_END
83cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbod
84cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbod
85cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbod#elif !defined(HB_NO_MT)
86cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbod
87cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbod#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_YIELD)
88cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbod# include <sched.h>
89cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbod# define HB_SCHED_YIELD() sched_yield ()
90cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbod#else
91cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbod# define HB_SCHED_YIELD() HB_STMT_START {} HB_STMT_END
92cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbod#endif
93cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbod
94cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbod#define HB_MUTEX_INT_NIL 1 /* Warn that fallback implementation is in use. */
95cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbodtypedef volatile int hb_mutex_impl_t;
96cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbod#define HB_MUTEX_IMPL_INIT	0
97cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbod#define hb_mutex_impl_init(M)	*(M) = 0
98cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbod#define hb_mutex_impl_lock(M)	HB_STMT_START { while (*(M)) HB_SCHED_YIELD (); (*(M))++; } HB_STMT_END
99cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbod#define hb_mutex_impl_unlock(M)	(*(M))--;
100cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbod#define hb_mutex_impl_finish(M)	HB_STMT_START {} HB_STMT_END
101cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbod
102cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbod
103cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbod#else /* HB_NO_MT */
104cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbod
105cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbodtypedef int hb_mutex_impl_t;
106cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbod#define HB_MUTEX_IMPL_INIT	0
107cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbod#define hb_mutex_impl_init(M)	HB_STMT_START {} HB_STMT_END
108cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbod#define hb_mutex_impl_lock(M)	HB_STMT_START {} HB_STMT_END
109cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbod#define hb_mutex_impl_unlock(M)	HB_STMT_START {} HB_STMT_END
110cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbod#define hb_mutex_impl_finish(M)	HB_STMT_START {} HB_STMT_END
11156eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod
11256eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod#endif
11356eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod
11456eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod
1150e253e97af71e2a7ead153589f61fd579a247502Behdad Esfahbod#define HB_MUTEX_INIT		{HB_MUTEX_IMPL_INIT}
116831886a9b4073cfe27f7e1db0e957cbd5913fd31Behdad Esfahbodstruct hb_mutex_t
117831886a9b4073cfe27f7e1db0e957cbd5913fd31Behdad Esfahbod{
118cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbod  /* TODO Add tracing. */
119cdafe3a7d8483ac586e2c16487e2a09164e0f65cBehdad Esfahbod
120831886a9b4073cfe27f7e1db0e957cbd5913fd31Behdad Esfahbod  hb_mutex_impl_t m;
121831886a9b4073cfe27f7e1db0e957cbd5913fd31Behdad Esfahbod
122831886a9b4073cfe27f7e1db0e957cbd5913fd31Behdad Esfahbod  inline void init   (void) { hb_mutex_impl_init   (&m); }
123831886a9b4073cfe27f7e1db0e957cbd5913fd31Behdad Esfahbod  inline void lock   (void) { hb_mutex_impl_lock   (&m); }
124831886a9b4073cfe27f7e1db0e957cbd5913fd31Behdad Esfahbod  inline void unlock (void) { hb_mutex_impl_unlock (&m); }
1250e253e97af71e2a7ead153589f61fd579a247502Behdad Esfahbod  inline void finish (void) { hb_mutex_impl_finish (&m); }
126831886a9b4073cfe27f7e1db0e957cbd5913fd31Behdad Esfahbod};
127831886a9b4073cfe27f7e1db0e957cbd5913fd31Behdad Esfahbod
128831886a9b4073cfe27f7e1db0e957cbd5913fd31Behdad Esfahbod
12956eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod#endif /* HB_MUTEX_PRIVATE_HH */
130