192827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant//===---------------------------- cxa_guard.cpp ---------------------------===//
292827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant//
392827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant//                     The LLVM Compiler Infrastructure
492827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant//
592827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant// This file is dual licensed under the MIT and the University of Illinois Open
692827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant// Source Licenses. See LICENSE.TXT for details.
792827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant//
892827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant//===----------------------------------------------------------------------===//
992827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant
1041683112536848562f538ee20e16dcd86c84fed5Nick Kledzik#include "abort_message.h"
11e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#include "config.h"
1292827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant
13e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#if !LIBCXXABI_SINGLE_THREADED
14e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#  include <pthread.h>
15e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#endif
1692827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant#include <stdint.h>
17de34b3e7ee1bf1ecdc595c6117fde99f1a974dcdHoward Hinnant
18de34b3e7ee1bf1ecdc595c6117fde99f1a974dcdHoward Hinnant/*
19de34b3e7ee1bf1ecdc595c6117fde99f1a974dcdHoward Hinnant    This implementation must be careful to not call code external to this file
20de34b3e7ee1bf1ecdc595c6117fde99f1a974dcdHoward Hinnant    which will turn around and try to call __cxa_guard_acquire reentrantly.
21de34b3e7ee1bf1ecdc595c6117fde99f1a974dcdHoward Hinnant    For this reason, the headers of this file are as restricted as possible.
22de34b3e7ee1bf1ecdc595c6117fde99f1a974dcdHoward Hinnant    Previous implementations of this code for __APPLE__ have used
23de34b3e7ee1bf1ecdc595c6117fde99f1a974dcdHoward Hinnant    pthread_mutex_lock and the abort_message utility without problem.  This
24de34b3e7ee1bf1ecdc595c6117fde99f1a974dcdHoward Hinnant    implementation also uses pthread_cond_wait which has tested to not be a
25de34b3e7ee1bf1ecdc595c6117fde99f1a974dcdHoward Hinnant    problem.
26de34b3e7ee1bf1ecdc595c6117fde99f1a974dcdHoward Hinnant*/
2792827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant
2892827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnantnamespace __cxxabiv1
2992827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant{
3092827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant
3192827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnantnamespace
3292827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant{
3392827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant
34fcd21a1f59d1bc797464ca7f3cfe80281756031fHoward Hinnant#if __arm__
35d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky
36d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky// A 32-bit, 4-byte-aligned static data value. The least significant 2 bits must
37d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky// be statically initialized to 0.
38d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewyckytypedef uint32_t guard_type;
39d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky
40d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky// Test the lowest bit.
41d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewyckyinline bool is_initialized(guard_type* guard_object) {
42d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky    return (*guard_object) & 1;
43d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky}
44d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky
45d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewyckyinline void set_initialized(guard_type* guard_object) {
46d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky    *guard_object |= 1;
47d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky}
48d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky
49d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky#else
50d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky
51d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewyckytypedef uint64_t guard_type;
52d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky
53d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewyckybool is_initialized(guard_type* guard_object) {
54d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky    char* initialized = (char*)guard_object;
55d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky    return *initialized;
56d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky}
57d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky
58d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewyckyvoid set_initialized(guard_type* guard_object) {
59d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky    char* initialized = (char*)guard_object;
60d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky    *initialized = 1;
61d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky}
62d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky
63d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky#endif
64d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky
65e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#if !LIBCXXABI_SINGLE_THREADED
6692827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnantpthread_mutex_t guard_mut = PTHREAD_MUTEX_INITIALIZER;
6792827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnantpthread_cond_t  guard_cv  = PTHREAD_COND_INITIALIZER;
68e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#endif
6992827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant
704d590c39af9e199a45148da87f205c24ef52579cHoward Hinnant#if defined(__APPLE__) && !defined(__arm__)
7192827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant
7292827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnanttypedef uint32_t lock_type;
7392827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant
7492827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant#if __LITTLE_ENDIAN__
7592827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant
7692827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnantinline
7792827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnantlock_type
7892827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnantget_lock(uint64_t x)
7992827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant{
8092827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant    return static_cast<lock_type>(x >> 32);
8192827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant}
8292827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant
8392827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnantinline
8492827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnantvoid
8592827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnantset_lock(uint64_t& x, lock_type y)
8692827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant{
8792827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant    x = static_cast<uint64_t>(y) << 32;
8892827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant}
8992827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant
9092827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant#else  // __LITTLE_ENDIAN__
9192827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant
9292827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnantinline
9392827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnantlock_type
9492827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnantget_lock(uint64_t x)
9592827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant{
9692827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant    return static_cast<lock_type>(x);
9792827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant}
9892827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant
9992827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnantinline
10092827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnantvoid
10192827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnantset_lock(uint64_t& x, lock_type y)
10292827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant{
10392827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant    x = y;
10492827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant}
10592827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant
10692827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant#endif  // __LITTLE_ENDIAN__
10792827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant
108fcd21a1f59d1bc797464ca7f3cfe80281756031fHoward Hinnant#else  // !__APPLE__ || __arm__
10992827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant
11092827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnanttypedef bool lock_type;
11192827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant
11292827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnantinline
11392827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnantlock_type
11492827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnantget_lock(uint64_t x)
11592827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant{
11692827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant    union
11792827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant    {
11892827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant        uint64_t guard;
11992827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant        uint8_t lock[2];
12092827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant    } f = {x};
12192827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant    return f.lock[1] != 0;
12292827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant}
12392827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant
12492827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnantinline
12592827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnantvoid
12692827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnantset_lock(uint64_t& x, lock_type y)
12792827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant{
12892827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant    union
12992827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant    {
13092827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant        uint64_t guard;
13192827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant        uint8_t lock[2];
13292827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant    } f = {0};
13392827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant    f.lock[1] = y;
13492827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant    x = f.guard;
13592827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant}
13692827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant
137d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewyckyinline
138d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewyckylock_type
139d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewyckyget_lock(uint32_t x)
140d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky{
141d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky    union
142d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky    {
143d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky        uint32_t guard;
144d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky        uint8_t lock[2];
145d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky    } f = {x};
146d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky    return f.lock[1] != 0;
147d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky}
148d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky
149d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewyckyinline
150d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewyckyvoid
151d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewyckyset_lock(uint32_t& x, lock_type y)
152d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky{
153d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky    union
154d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky    {
155d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky        uint32_t guard;
156d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky        uint8_t lock[2];
157d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky    } f = {0};
158d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky    f.lock[1] = y;
159d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky    x = f.guard;
160d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky}
161d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky
16292827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant#endif  // __APPLE__
16392827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant
16492827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant}  // unnamed namespace
16592827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant
16692827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnantextern "C"
16792827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant{
16892827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant
169e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#if LIBCXXABI_SINGLE_THREADED
170e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertint __cxa_guard_acquire(guard_type* guard_object)
171e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert{
172e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    return !is_initialized(guard_object);
173e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert}
174e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert
175e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertvoid __cxa_guard_release(guard_type* guard_object)
176e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert{
177e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    *guard_object = 0;
178e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    set_initialized(guard_object);
179e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert}
180e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert
181e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertvoid __cxa_guard_abort(guard_type* guard_object)
182e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert{
183e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    *guard_object = 0;
184e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert}
185e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert
186e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#else // !LIBCXXABI_SINGLE_THREADED
187e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert
188d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewyckyint __cxa_guard_acquire(guard_type* guard_object)
18992827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant{
19092827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant    char* initialized = (char*)guard_object;
19192827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant    if (pthread_mutex_lock(&guard_mut))
19292827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant        abort_message("__cxa_guard_acquire failed to acquire mutex");
19392827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant    int result = *initialized == 0;
19492827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant    if (result)
19592827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant    {
1964d590c39af9e199a45148da87f205c24ef52579cHoward Hinnant#if defined(__APPLE__) && !defined(__arm__)
19792827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant        const lock_type id = pthread_mach_thread_np(pthread_self());
19892827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant        lock_type lock = get_lock(*guard_object);
19992827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant        if (lock)
20092827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant        {
20192827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant            // if this thread set lock for this same guard_object, abort
20292827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant            if (lock == id)
20392827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant                abort_message("__cxa_guard_acquire detected deadlock");
20492827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant            do
20592827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant            {
20692827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant                if (pthread_cond_wait(&guard_cv, &guard_mut))
20792827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant                    abort_message("__cxa_guard_acquire condition variable wait failed");
20892827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant                lock = get_lock(*guard_object);
20992827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant            } while (lock);
210d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky            result = !is_initialized(guard_object);
21192827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant            if (result)
21292827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant                set_lock(*guard_object, id);
21392827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant        }
21492827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant        else
21592827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant            set_lock(*guard_object, id);
216fcd21a1f59d1bc797464ca7f3cfe80281756031fHoward Hinnant#else  // !__APPLE__ || __arm__
21792827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant        while (get_lock(*guard_object))
21892827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant            if (pthread_cond_wait(&guard_cv, &guard_mut))
21992827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant                abort_message("__cxa_guard_acquire condition variable wait failed");
22092827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant        result = *initialized == 0;
22192827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant        if (result)
22292827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant            set_lock(*guard_object, true);
223fcd21a1f59d1bc797464ca7f3cfe80281756031fHoward Hinnant#endif  // !__APPLE__ || __arm__
22492827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant    }
22592827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant    if (pthread_mutex_unlock(&guard_mut))
22692827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant        abort_message("__cxa_guard_acquire failed to release mutex");
22792827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant    return result;
22892827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant}
22992827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant
230d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewyckyvoid __cxa_guard_release(guard_type* guard_object)
23192827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant{
23292827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant    if (pthread_mutex_lock(&guard_mut))
23392827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant        abort_message("__cxa_guard_release failed to acquire mutex");
23492827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant    *guard_object = 0;
235d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewycky    set_initialized(guard_object);
23692827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant    if (pthread_mutex_unlock(&guard_mut))
23792827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant        abort_message("__cxa_guard_release failed to release mutex");
23892827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant    if (pthread_cond_broadcast(&guard_cv))
23992827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant        abort_message("__cxa_guard_release failed to broadcast condition variable");
24092827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant}
24192827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant
242d8cfd659b70bcf65a9c810ebe525632af38726f0Nick Lewyckyvoid __cxa_guard_abort(guard_type* guard_object)
24392827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant{
24492827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant    if (pthread_mutex_lock(&guard_mut))
24592827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant        abort_message("__cxa_guard_abort failed to acquire mutex");
24692827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant    *guard_object = 0;
24792827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant    if (pthread_mutex_unlock(&guard_mut))
24892827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant        abort_message("__cxa_guard_abort failed to release mutex");
24992827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant    if (pthread_cond_broadcast(&guard_cv))
25092827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant        abort_message("__cxa_guard_abort failed to broadcast condition variable");
25192827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant}
25292827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant
253e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#endif // !LIBCXXABI_SINGLE_THREADED
254e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert
25592827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant}  // extern "C"
25692827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant
25792827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant}  // __cxxabiv1
258