Hi mclow.lists,

This is one of several pieces needed for bare-metal ARM support.

http://reviews.llvm.org/D3386

Files:
  src/cxa_exception_storage.cpp
  src/cxa_guard.cpp
  src/fallback_malloc.ipp
  test/test_exception_storage.cpp
Index: src/cxa_exception_storage.cpp
===================================================================
--- src/cxa_exception_storage.cpp
+++ src/cxa_exception_storage.cpp
@@ -33,43 +33,65 @@
 #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.
 //  We cannot call std::terminate() because that will in turn
 //  call __cxa_get_globals() and cause infinite recursion.
 
 namespace __cxxabiv1 {
 namespace {
+#if defined(_POSIX_THREADS) && _POSIX_THREADS > 0
     pthread_key_t  key_;
     pthread_once_t flag_ = PTHREAD_ONCE_INIT;
+#else
+    __cxa_eh_globals * eh_globals_ = NULL;
+#endif
 
     void destruct_ (void *p) {
         std::free ( p );
-        if ( 0 != ::pthread_setspecific ( key_, NULL ) ) 
+#if defined(_POSIX_THREADS) && _POSIX_THREADS > 0
+        if ( 0 != ::pthread_setspecific ( key_, NULL ) )
             abort_message("cannot zero out thread value for __cxa_get_globals()");
+#else
+        eh_globals_ = NULL;
+#endif
         }
 
+#if !(defined(_POSIX_THREADS) && _POSIX_THREADS > 0)
+    void do_destruct_ () {
+        destruct_(eh_globals_);
+        }
+#endif
+
     void construct_ () {
+#if defined(_POSIX_THREADS) && _POSIX_THREADS > 0
         if ( 0 != pthread_key_create ( &key_, destruct_ ) )
             abort_message("cannot create pthread key for __cxa_get_globals()");
+#else
+        atexit (do_destruct_);
+#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*>
                         (std::calloc (1, sizeof (__cxa_eh_globals)));
             if ( NULL == retVal )
                 abort_message("cannot allocate __cxa_eh_globals");
+#if defined(_POSIX_THREADS) && _POSIX_THREADS > 0
             if ( 0 != pthread_setspecific ( key_, retVal ) )
                abort_message("pthread_setspecific failure in __cxa_get_globals()");
+#else
+            eh_globals_ = retVal;
+#endif
            }
         return retVal;
         }
@@ -79,13 +101,16 @@
     // to the Itanium ABI and is taken advantage of in several places in
     // libc++abi.
     __cxa_eh_globals * __cxa_get_globals_fast () {
+#if defined(_POSIX_THREADS) && _POSIX_THREADS > 0
     //  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_));
+#else
+        return eh_globals_;
+#endif
         }
-    
 }
 }
 #endif
Index: src/cxa_guard.cpp
===================================================================
--- src/cxa_guard.cpp
+++ src/cxa_guard.cpp
@@ -59,8 +59,10 @@
 
 #endif
 
+#if defined(_POSIX_THREADS) && _POSIX_THREADS > 0
 pthread_mutex_t guard_mut = PTHREAD_MUTEX_INITIALIZER;
 pthread_cond_t  guard_cv  = PTHREAD_COND_INITIALIZER;
+#endif
 
 #if defined(__APPLE__) && !defined(__arm__)
 
@@ -163,10 +165,11 @@
 
 int __cxa_guard_acquire(guard_type* guard_object)
 {
+#if defined(_POSIX_THREADS) && _POSIX_THREADS > 0
     char* initialized = (char*)guard_object;
     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,37 +196,49 @@
         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__
     }
     if (pthread_mutex_unlock(&guard_mut))
         abort_message("__cxa_guard_acquire failed to release mutex");
     return result;
+#else // !_POSIX_THREADS || _POSIX_THREADS <= 0
+    int result = !is_initialized(guard_object);
+    return result;
+#endif // !_POSIX_THREADS || _POSIX_THREADS <= 0
 }
 
 void __cxa_guard_release(guard_type* guard_object)
 {
+#if defined(_POSIX_THREADS) && _POSIX_THREADS > 0
     if (pthread_mutex_lock(&guard_mut))
         abort_message("__cxa_guard_release failed to acquire mutex");
+#endif
     *guard_object = 0;
     set_initialized(guard_object);
+#if defined(_POSIX_THREADS) && _POSIX_THREADS > 0
     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 defined(_POSIX_THREADS) && _POSIX_THREADS > 0
     if (pthread_mutex_lock(&guard_mut))
         abort_message("__cxa_guard_abort failed to acquire mutex");
+#endif
     *guard_object = 0;
+#if defined(_POSIX_THREADS) && _POSIX_THREADS > 0
     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
@@ -23,16 +23,28 @@
 
 namespace {
 
+// When POSIX threads are not available, make the mutex operations a nop
+#if defined(_POSIX_THREADS) && _POSIX_THREADS > 0
 static pthread_mutex_t heap_mutex = PTHREAD_MUTEX_INITIALIZER;
+#else
+static void * heap_mutex = 0;
+#endif
 
 class mutexor {
 public:
+#if defined(_POSIX_THREADS) && _POSIX_THREADS > 0
     mutexor ( pthread_mutex_t *m ) : mtx_(m) { pthread_mutex_lock ( mtx_ ); }
     ~mutexor () { pthread_mutex_unlock ( mtx_ ); }
+#else
+    mutexor ( void * ) {}
+    ~mutexor () {}
+#endif
 private:
     mutexor ( const mutexor &rhs );
     mutexor & operator = ( const mutexor &rhs );
+#if defined(_POSIX_THREADS) && _POSIX_THREADS > 0
     pthread_mutex_t *mtx_;
+#endif
     };
 
         
Index: test/test_exception_storage.cpp
===================================================================
--- test/test_exception_storage.cpp
+++ test/test_exception_storage.cpp
@@ -34,10 +34,11 @@
     return parm;
     }
 
-
+#if defined(__POSIX_THREADS) && __POSIX_THREADS > 0
 #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 +50,7 @@
 int main ( int argc, char *argv [] ) {
     int retVal = 0;
 
+#if defined(__POSIX_THREADS) && __POSIX_THREADS > 0
 //  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 +71,9 @@
             retVal = 2;
             }
 //  print_sizes ( thread_globals, thread_globals + NUMTHREADS );
-    
+#else
+    size_t thread_globals;
+    retVal = thread_code(&thread_globals) != 0;
+#endif
     return retVal;
     }
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to