Revert "Revert "Update aosp/master libcxx rebase to r263688""

This reverts commit 1d4a1edbc7.

Change-Id: I2909937fe582f2c5552bc86e7f4d2d5cff0de0aa
This commit is contained in:
Dan Austin
2016-06-08 22:25:43 +00:00
parent 1d4a1edbc7
commit ee226c05af
1396 changed files with 38992 additions and 11535 deletions

View File

@@ -7,6 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
// XFAIL: libcpp-no-exceptions
// UNSUPPORTED: libcpp-has-no-threads
// <thread>
@@ -19,21 +20,28 @@
#include <thread>
#include <new>
#include <atomic>
#include <cstdlib>
#include <cassert>
unsigned throw_one = 0xFFFF;
#include "test_macros.h"
std::atomic<unsigned> throw_one(0xFFFF);
std::atomic<unsigned> outstanding_new(0);
void* operator new(std::size_t s) throw(std::bad_alloc)
{
if (throw_one == 0)
throw std::bad_alloc();
--throw_one;
++outstanding_new;
return std::malloc(s);
}
void operator delete(void* p) throw()
{
--outstanding_new;
std::free(p);
}
@@ -75,7 +83,7 @@ public:
int G::n_alive = 0;
bool G::op_run = false;
#ifndef _LIBCPP_HAS_NO_VARIADICS
#if TEST_STD_VER >= 11
class MoveOnly
{
@@ -91,27 +99,58 @@ public:
#endif
// Test throwing std::bad_alloc
//-----------------------------
// Concerns:
// A Each allocation performed during thread construction should be performed
// in the parent thread so that std::terminate is not called if
// std::bad_alloc is thrown by new.
// B std::threads constructor should properly handle exceptions and not leak
// memory.
// Plan:
// 1 Create a thread and count the number of allocations, 'N', it performs.
// 2 For each allocation performed run a test where that allocation throws.
// 2.1 check that the exception can be caught in the parent thread.
// 2.2 Check that the functor has not been called.
// 2.3 Check that no memory allocated by the creation of the thread is leaked.
// 3 Finally check that a thread runs successfully if we throw after 'N+1'
// allocations.
void test_throwing_new_during_thread_creation() {
throw_one = 0xFFF;
{
std::thread t(f);
t.join();
}
const int numAllocs = 0xFFF - throw_one;
// i <= numAllocs means the last iteration is expected not to throw.
for (int i=0; i <= numAllocs; ++i) {
throw_one = i;
f_run = false;
unsigned old_outstanding = outstanding_new;
try {
std::thread t(f);
assert(i == numAllocs); // Only final iteration will not throw.
t.join();
assert(f_run);
} catch (std::bad_alloc const&) {
assert(i < numAllocs);
assert(!f_run); // (2.2)
}
assert(old_outstanding == outstanding_new); // (2.3)
}
f_run = false;
throw_one = 0xFFF;
}
int main()
{
test_throwing_new_during_thread_creation();
{
std::thread t(f);
t.join();
assert(f_run == true);
}
f_run = false;
{
try
{
throw_one = 0;
std::thread t(f);
assert(false);
}
catch (...)
{
throw_one = 0xFFFF;
assert(!f_run);
}
}
{
assert(G::n_alive == 0);
assert(!G::op_run);
@@ -137,7 +176,7 @@ int main()
assert(!G::op_run);
}
}
#ifndef _LIBCPP_HAS_NO_VARIADICS
#if TEST_STD_VER >= 11
{
assert(G::n_alive == 0);
assert(!G::op_run);
@@ -150,5 +189,5 @@ int main()
std::thread t = std::thread(MoveOnly(), MoveOnly());
t.join();
}
#endif // _LIBCPP_HAS_NO_VARIADICS
#endif
}