Added a config.h to src/, and put all of the pthread things under
LIBCXXABI_SINGLE_THREADED. Also gave test/test_exception_storage.cpp the same
treatment (which I forgot to attach to the previous diff).
Hi mclow.lists,
http://reviews.llvm.org/D3386
CHANGE SINCE LAST DIFF
http://reviews.llvm.org/D3386?vs=8540&id=8583#toc
Files:
src/config.h
src/cxa_exception.cpp
src/cxa_exception_storage.cpp
src/cxa_guard.cpp
src/fallback_malloc.ipp
test/test_exception_storage.cpp
Index: src/config.h
===================================================================
--- src/config.h
+++ src/config.h
@@ -0,0 +1,25 @@
+//===----------------------------- config.h -------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//
+// Defines macros used within the libc++abi project.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LIBCXXABI_CONFIG_H
+#define LIBCXXABI_CONFIG_H
+
+#include <unistd.h>
+
+#if defined(_POSIX_THREADS) && _POSIX_THREADS > 0
+# define LIBCXXABI_SINGLE_THREADED 0
+#else
+# define LIBCXXABI_SINGLE_THREADED 1
+#endif
+
+#endif // LIBCXXABI_CONFIG_H
Index: src/cxa_exception.cpp
===================================================================
--- src/cxa_exception.cpp
+++ src/cxa_exception.cpp
@@ -11,13 +11,15 @@
//
//===----------------------------------------------------------------------===//
+#include "config.h"
#include "cxxabi.h"
#include <exception> // for std::terminate
#include <cstdlib> // for malloc, free
#include <cstring> // for memset
-#include <pthread.h>
-
+#if !LIBCXXABI_SINGLE_THREADED
+# include <pthread.h> // for fallback_malloc.ipp's mutexes
+#endif
#include "cxa_exception.hpp"
#include "cxa_handlers.hpp"
Index: src/cxa_exception_storage.cpp
===================================================================
--- src/cxa_exception_storage.cpp
+++ src/cxa_exception_storage.cpp
@@ -13,6 +13,8 @@
#include "cxa_exception.hpp"
+#include "config.h"
+
#ifdef HAS_THREAD_LOCAL
namespace __cxxabiv1 {
@@ -33,7 +35,7 @@
#else
#include <pthread.h>
-#include <cstdlib> // for calloc, free
+#include <cstdlib> // for calloc, free, atexit
#include "abort_message.h"
// In general, we treat all pthread errors as fatal.
@@ -42,26 +44,44 @@
namespace __cxxabiv1 {
namespace {
+#if LIBCXXABI_SINGLE_THREADED
+ __cxa_eh_globals * eh_globals_ = NULL;
+#else
pthread_key_t key_;
pthread_once_t flag_ = PTHREAD_ONCE_INIT;
+#endif
void destruct_ (void *p) {
std::free ( p );
- if ( 0 != ::pthread_setspecific ( key_, NULL ) )
+#if LIBCXXABI_SINGLE_THREADED
+ eh_globals_ = NULL;
+#else
+ if ( 0 != ::pthread_setspecific ( key_, NULL ) )
abort_message("cannot zero out thread value for __cxa_get_globals()");
+#endif
}
+#if LIBCXXABI_SINGLE_THREADED
+ void do_destruct_ () {
+ destruct_(eh_globals_);
+ }
+#endif
+
void construct_ () {
+#if LIBCXXABI_SINGLE_THREADED
+ atexit (do_destruct_);
+#else
if ( 0 != pthread_key_create ( &key_, destruct_ ) )
abort_message("cannot create pthread key for __cxa_get_globals()");
+#endif
}
-}
+}
extern "C" {
__cxa_eh_globals * __cxa_get_globals () {
// Try to get the globals for this thread
__cxa_eh_globals* retVal = __cxa_get_globals_fast ();
-
+
// If this is the first time we've been asked for these globals, create them
if ( NULL == retVal ) {
retVal = static_cast<__cxa_eh_globals*>
@@ -68,8 +88,12 @@
(std::calloc (1, sizeof (__cxa_eh_globals)));
if ( NULL == retVal )
abort_message("cannot allocate __cxa_eh_globals");
+#if LIBCXXABI_SINGLE_THREADED
+ eh_globals_ = retVal;
+#else
if ( 0 != pthread_setspecific ( key_, retVal ) )
abort_message("pthread_setspecific failure in __cxa_get_globals()");
+#endif
}
return retVal;
}
@@ -79,13 +103,16 @@
// to the Itanium ABI and is taken advantage of in several places in
// libc++abi.
__cxa_eh_globals * __cxa_get_globals_fast () {
+#if LIBCXXABI_SINGLE_THREADED
+ return eh_globals_;
+#else
// First time through, create the key.
if (0 != pthread_once(&flag_, construct_))
abort_message("pthread_once failure in __cxa_get_globals_fast()");
// static int init = construct_();
return static_cast<__cxa_eh_globals*>(::pthread_getspecific(key_));
+#endif
}
-
}
}
#endif
Index: src/cxa_guard.cpp
===================================================================
--- src/cxa_guard.cpp
+++ src/cxa_guard.cpp
@@ -8,8 +8,11 @@
//===----------------------------------------------------------------------===//
#include "abort_message.h"
+#include "config.h"
-#include <pthread.h>
+#if !LIBCXXABI_SINGLE_THREADED
+# include <pthread.h>
+#endif
#include <stdint.h>
/*
@@ -59,8 +62,10 @@
#endif
+#if !LIBCXXABI_SINGLE_THREADED
pthread_mutex_t guard_mut = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t guard_cv = PTHREAD_COND_INITIALIZER;
+#endif
#if defined(__APPLE__) && !defined(__arm__)
@@ -163,10 +168,13 @@
int __cxa_guard_acquire(guard_type* guard_object)
{
- char* initialized = (char*)guard_object;
+#if LIBCXXABI_SINGLE_THREADED
+ int result = !is_initialized(guard_object);
+ return result;
+#else // !LIBCXXABI_SINGLE_THREADED
if (pthread_mutex_lock(&guard_mut))
abort_message("__cxa_guard_acquire failed to acquire mutex");
- int result = *initialized == 0;
+ int result = !is_initialized(guard_object);
if (result)
{
#if defined(__APPLE__) && !defined(__arm__)
@@ -193,7 +201,7 @@
while (get_lock(*guard_object))
if (pthread_cond_wait(&guard_cv, &guard_mut))
abort_message("__cxa_guard_acquire condition variable wait failed");
- result = *initialized == 0;
+ result = !is_initialized(guard_object);
if (result)
set_lock(*guard_object, true);
#endif // !__APPLE__ || __arm__
@@ -201,29 +209,38 @@
if (pthread_mutex_unlock(&guard_mut))
abort_message("__cxa_guard_acquire failed to release mutex");
return result;
+#endif // !LIBCXXABI_SINGLE_THREADED
}
void __cxa_guard_release(guard_type* guard_object)
{
+#if !LIBCXXABI_SINGLE_THREADED
if (pthread_mutex_lock(&guard_mut))
abort_message("__cxa_guard_release failed to acquire mutex");
+#endif
*guard_object = 0;
set_initialized(guard_object);
+#if !LIBCXXABI_SINGLE_THREADED
if (pthread_mutex_unlock(&guard_mut))
abort_message("__cxa_guard_release failed to release mutex");
if (pthread_cond_broadcast(&guard_cv))
abort_message("__cxa_guard_release failed to broadcast condition variable");
+#endif
}
void __cxa_guard_abort(guard_type* guard_object)
{
+#if !LIBCXXABI_SINGLE_THREADED
if (pthread_mutex_lock(&guard_mut))
abort_message("__cxa_guard_abort failed to acquire mutex");
+#endif
*guard_object = 0;
+#if !LIBCXXABI_SINGLE_THREADED
if (pthread_mutex_unlock(&guard_mut))
abort_message("__cxa_guard_abort failed to release mutex");
if (pthread_cond_broadcast(&guard_cv))
abort_message("__cxa_guard_abort failed to broadcast condition variable");
+#endif
}
} // extern "C"
Index: src/fallback_malloc.ipp
===================================================================
--- src/fallback_malloc.ipp
+++ src/fallback_malloc.ipp
@@ -11,6 +11,8 @@
//
//===----------------------------------------------------------------------===//
+#include "config.h"
+
// A small, simple heap manager based (loosely) on
// the startup heap manager from FreeBSD, optimized for space.
//
@@ -23,16 +25,28 @@
namespace {
+// When POSIX threads are not available, make the mutex operations a nop
+#if LIBCXXABI_SINGLE_THREADED
+static void * heap_mutex = 0;
+#else
static pthread_mutex_t heap_mutex = PTHREAD_MUTEX_INITIALIZER;
+#endif
class mutexor {
public:
+#if LIBCXXABI_SINGLE_THREADED
+ mutexor ( void * ) {}
+ ~mutexor () {}
+#else
mutexor ( pthread_mutex_t *m ) : mtx_(m) { pthread_mutex_lock ( mtx_ ); }
~mutexor () { pthread_mutex_unlock ( mtx_ ); }
+#endif
private:
mutexor ( const mutexor &rhs );
mutexor & operator = ( const mutexor &rhs );
+#if !LIBCXXABI_SINGLE_THREADED
pthread_mutex_t *mtx_;
+#endif
};
Index: test/test_exception_storage.cpp
===================================================================
--- test/test_exception_storage.cpp
+++ test/test_exception_storage.cpp
@@ -7,10 +7,14 @@
//
//===----------------------------------------------------------------------===//
+#include "../src/config.h"
+
#include <cstdlib>
#include <algorithm>
#include <iostream>
-#include <pthread.h>
+#if !LIBCXXABI_SINGLE_THREADED
+# include <pthread.h>
+#endif
#include <unistd.h>
#include "../src/cxa_exception.hpp"
@@ -34,10 +38,11 @@
return parm;
}
-
+#if !LIBCXXABI_SINGLE_THREADED
#define NUMTHREADS 10
size_t thread_globals [ NUMTHREADS ] = { 0 };
pthread_t threads [ NUMTHREADS ];
+#endif
void print_sizes ( size_t *first, size_t *last ) {
std::cout << "{ " << std::hex;
@@ -49,6 +54,10 @@
int main ( int argc, char *argv [] ) {
int retVal = 0;
+#if LIBCXXABI_SINGLE_THREADED
+ size_t thread_globals;
+ retVal = thread_code(&thread_globals) != 0;
+#else
// Make the threads, let them run, and wait for them to finish
for ( int i = 0; i < NUMTHREADS; ++i )
pthread_create( threads + i, NULL, thread_code, (void *) (thread_globals + i));
@@ -69,6 +78,7 @@
retVal = 2;
}
// print_sizes ( thread_globals, thread_globals + NUMTHREADS );
-
+
+#endif
return retVal;
}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits