Imported Upstream version 6.10.0.49

Former-commit-id: 1d6753294b2993e1fbf92de9366bb9544db4189b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2020-01-16 16:38:04 +00:00
parent d94e79959b
commit 468663ddbb
48518 changed files with 2789335 additions and 61176 deletions

View File

@ -0,0 +1,6 @@
LEVEL = ../../../make
CXXFLAGS += -std=c++11
CXX_SOURCES := ParallelTask.cpp
ENABLE_THREADS := YES
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,151 @@
#include <cstdint>
#include <thread>
#include <vector>
#include <queue>
#include <future>
#include <iostream>
#include <cassert>
class TaskPoolImpl
{
public:
TaskPoolImpl(uint32_t num_threads) :
m_stop(false)
{
for (uint32_t i = 0; i < num_threads; ++i)
m_threads.emplace_back(Worker, this);
}
~TaskPoolImpl()
{
Stop();
}
template<typename F, typename... Args>
std::future<typename std::result_of<F(Args...)>::type>
AddTask(F&& f, Args&&... args)
{
auto task = std::make_shared<std::packaged_task<typename std::result_of<F(Args...)>::type()>>(
std::bind(std::forward<F>(f), std::forward<Args>(args)...));
std::unique_lock<std::mutex> lock(m_tasks_mutex);
assert(!m_stop && "Can't add task to TaskPool after it is stopped");
m_tasks.emplace([task](){ (*task)(); });
lock.unlock();
m_tasks_cv.notify_one();
return task->get_future();
}
void
Stop()
{
std::unique_lock<std::mutex> lock(m_tasks_mutex);
m_stop = true;
m_tasks_mutex.unlock();
m_tasks_cv.notify_all();
for (auto& t : m_threads)
t.join();
}
private:
static void
Worker(TaskPoolImpl* pool)
{
while (true)
{
std::unique_lock<std::mutex> lock(pool->m_tasks_mutex);
if (pool->m_tasks.empty())
pool->m_tasks_cv.wait(lock, [pool](){ return !pool->m_tasks.empty() || pool->m_stop; });
if (pool->m_tasks.empty())
break;
std::function<void()> f = pool->m_tasks.front();
pool->m_tasks.pop();
lock.unlock();
f();
}
}
std::queue<std::function<void()>> m_tasks;
std::mutex m_tasks_mutex;
std::condition_variable m_tasks_cv;
bool m_stop;
std::vector<std::thread> m_threads;
};
class TaskPool
{
public:
// Add a new task to the thread pool and return a std::future belongs for the newly created task.
// The caller of this function have to wait on the future for this task to complete.
template<typename F, typename... Args>
static std::future<typename std::result_of<F(Args...)>::type>
AddTask(F&& f, Args&&... args)
{
return GetImplementation().AddTask(std::forward<F>(f), std::forward<Args>(args)...);
}
// Run all of the specified tasks on the thread pool and wait until all of them are finished
// before returning
template<typename... T>
static void
RunTasks(T&&... t)
{
RunTaskImpl<T...>::Run(std::forward<T>(t)...);
}
private:
static TaskPoolImpl&
GetImplementation()
{
static TaskPoolImpl g_task_pool_impl(std::thread::hardware_concurrency());
return g_task_pool_impl;
}
template<typename... T>
struct RunTaskImpl;
};
template<typename H, typename... T>
struct TaskPool::RunTaskImpl<H, T...>
{
static void
Run(H&& h, T&&... t)
{
auto f = AddTask(std::forward<H>(h));
RunTaskImpl<T...>::Run(std::forward<T>(t)...);
f.wait();
}
};
template<>
struct TaskPool::RunTaskImpl<>
{
static void
Run() {}
};
int main()
{
std::vector<std::future<uint32_t>> tasks;
for (int i = 0; i < 100000; ++i)
{
tasks.emplace_back(TaskPool::AddTask([](int i){
uint32_t s = 0;
for (int j = 0; j <= i; ++j)
s += j;
return s;
},
i));
}
for (auto& it : tasks) // Set breakpoint here
it.wait();
TaskPool::RunTasks(
[]() { return 1; },
[]() { return "aaaa"; }
);
}

View File

@ -0,0 +1,67 @@
"""
Test regression for Bug 25251.
"""
import os
import time
import unittest2
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class BreakpointAfterJoinTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
# Find the line number for our breakpoint.
self.breakpoint = line_number(
'ParallelTask.cpp', '// Set breakpoint here')
# The android-arm compiler can't compile the inferior
@skipIfTargetAndroid(archs=["arm"])
# because of an issue around std::future.
# TODO: Change the test to don't depend on std::future<T>
def test(self):
"""Test breakpoint handling after a thread join."""
self.build(dictionary=self.getBuildFlags())
exe = os.path.join(os.getcwd(), "a.out")
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
# This should create a breakpoint
lldbutil.run_break_set_by_file_and_line(
self, "ParallelTask.cpp", self.breakpoint, num_expected_locations=-1)
# The breakpoint list should show 1 location.
self.expect(
"breakpoint list -f",
"Breakpoint location shown correctly",
substrs=[
"1: file = 'ParallelTask.cpp', line = %d, exact_match = 0" %
self.breakpoint])
# Run the program.
self.runCmd("run", RUN_SUCCEEDED)
# The stop reason of the thread should be breakpoint.
self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
substrs=['stopped',
'stop reason = breakpoint'])
# This should not result in a segmentation fault
self.expect("thread backtrace all", STOPPED_DUE_TO_BREAKPOINT,
substrs=["stop reason = breakpoint 1."])
# Run to completion
self.runCmd("continue")
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
atexit.register(lambda: lldb.SBDebugger.Terminate())
unittest2.main()

View File

@ -0,0 +1,5 @@
LEVEL = ../../../make
CXX_SOURCES := main.cpp
ENABLE_THREADS := YES
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,95 @@
"""
Test number of threads.
"""
from __future__ import print_function
import os
import time
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class BreakpointAfterJoinTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
# Find the line number for our breakpoint.
self.breakpoint = line_number('main.cpp', '// Set breakpoint here')
@expectedFailureAll(
oslist=["linux"],
bugnumber="llvm.org/pr15824 thread states not properly maintained")
@expectedFailureAll(
oslist=lldbplatformutil.getDarwinOSTriples(),
bugnumber="llvm.org/pr15824 thread states not properly maintained and <rdar://problem/28557237>")
@expectedFailureAll(
oslist=["freebsd"],
bugnumber="llvm.org/pr18190 thread states not properly maintained")
def test(self):
"""Test breakpoint handling after a thread join."""
self.build(dictionary=self.getBuildFlags())
exe = os.path.join(os.getcwd(), "a.out")
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
# This should create a breakpoint in the main thread.
lldbutil.run_break_set_by_file_and_line(
self, "main.cpp", self.breakpoint, num_expected_locations=1)
# The breakpoint list should show 1 location.
self.expect(
"breakpoint list -f",
"Breakpoint location shown correctly",
substrs=[
"1: file = 'main.cpp', line = %d, exact_match = 0, locations = 1" %
self.breakpoint])
# Run the program.
self.runCmd("run", RUN_SUCCEEDED)
# The stop reason of the thread should be breakpoint.
self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
substrs=['stopped',
'stop reason = breakpoint'])
# Get the target process
target = self.dbg.GetSelectedTarget()
process = target.GetProcess()
# The exit probably occurred during breakpoint handling, but it isn't
# guaranteed. The main thing we're testing here is that the debugger
# handles this cleanly is some way.
# Get the number of threads
num_threads = process.GetNumThreads()
# Make sure we see at least six threads
self.assertTrue(
num_threads >= 6,
'Number of expected threads and actual threads do not match.')
# Make sure all threads are stopped
for i in range(0, num_threads):
self.assertTrue(
process.GetThreadAtIndex(i).IsStopped(),
"Thread {0} didn't stop during breakpoint.".format(i))
# Run to completion
self.runCmd("continue")
# If the process hasn't exited, collect some information
if process.GetState() != lldb.eStateExited:
self.runCmd("thread list")
self.runCmd("process status")
# At this point, the inferior process should have exited.
self.assertTrue(
process.GetState() == lldb.eStateExited,
PROCESS_EXITED)

View File

@ -0,0 +1,106 @@
//===-- main.cpp ------------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// This test is intended to create a situation in which one thread will exit
// while a breakpoint is being handled in another thread. This may not always
// happen because it's possible that the exiting thread will exit before the
// breakpoint is hit. The test case should be flexible enough to treat that
// as success.
#include "pseudo_barrier.h"
#include <chrono>
#include <thread>
volatile int g_test = 0;
// A barrier to synchronize all the threads.
pseudo_barrier_t g_barrier1;
// A barrier to keep the threads from exiting until after the breakpoint has
// been passed.
pseudo_barrier_t g_barrier2;
void *
break_thread_func ()
{
// Wait until all the threads are running
pseudo_barrier_wait(g_barrier1);
// Wait for the join thread to join
std::this_thread::sleep_for(std::chrono::microseconds(50));
// Do something
g_test++; // Set breakpoint here
// Synchronize after the breakpoint
pseudo_barrier_wait(g_barrier2);
// Return
return NULL;
}
void *
wait_thread_func ()
{
// Wait until the entire first group of threads is running
pseudo_barrier_wait(g_barrier1);
// Wait until the breakpoint has been passed
pseudo_barrier_wait(g_barrier2);
// Return
return NULL;
}
void *
join_thread_func (void *input)
{
std::thread *thread_to_join = (std::thread *)input;
// Sync up with the rest of the threads.
pseudo_barrier_wait(g_barrier1);
// Join the other thread
thread_to_join->join();
// Return
return NULL;
}
int main ()
{
// The first barrier waits for the non-joining threads to start.
// This thread will also participate in that barrier.
// The idea here is to guarantee that the joining thread will be
// last in the internal list maintained by the debugger.
pseudo_barrier_init(g_barrier1, 5);
// The second barrier keeps the waiting threads around until the breakpoint
// has been passed.
pseudo_barrier_init(g_barrier2, 4);
// Create a thread to hit the breakpoint
std::thread thread_1(break_thread_func);
// Create more threads to slow the debugger down during processing.
std::thread thread_2(wait_thread_func);
std::thread thread_3(wait_thread_func);
std::thread thread_4(wait_thread_func);
// Create a thread to join the breakpoint thread
std::thread thread_5(join_thread_func, &thread_1);
// Wait for the threads to finish
thread_5.join(); // implies thread_1 is already finished
thread_4.join();
thread_3.join();
thread_2.join();
return 0;
}

View File

@ -0,0 +1,9 @@
LEVEL = ../../../../make
CXX_SOURCES := main.cpp
ENABLE_THREADS := YES
VPATH = ..
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,23 @@
from __future__ import print_function
import unittest2
from lldbsuite.test.decorators import *
from lldbsuite.test.concurrent_base import ConcurrentEventsBase
from lldbsuite.test.lldbtest import TestBase
@skipIfWindows
class ConcurrentBreakpointDelayBreakpointOneSignal(ConcurrentEventsBase):
mydir = ConcurrentEventsBase.compute_mydir(__file__)
@skipIfFreeBSD # timing out on buildbot
# Atomic sequences are not supported yet for MIPS in LLDB.
@skipIf(triple='^mips')
def test(self):
"""Test two threads that trigger a breakpoint (one with a 1 second delay) and one signal thread. """
self.build(dictionary=self.getBuildFlags())
self.do_thread_actions(num_breakpoint_threads=1,
num_delay_breakpoint_threads=1,
num_signal_threads=1)

View File

@ -0,0 +1,9 @@
LEVEL = ../../../../make
CXX_SOURCES := main.cpp
ENABLE_THREADS := YES
VPATH = ..
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,22 @@
from __future__ import print_function
import unittest2
from lldbsuite.test.decorators import *
from lldbsuite.test.concurrent_base import ConcurrentEventsBase
from lldbsuite.test.lldbtest import TestBase
@skipIfWindows
class ConcurrentBreakpointOneDelayBreakpointThreads(ConcurrentEventsBase):
mydir = ConcurrentEventsBase.compute_mydir(__file__)
@skipIfFreeBSD # timing out on buildbot
# Atomic sequences are not supported yet for MIPS in LLDB.
@skipIf(triple='^mips')
def test(self):
"""Test threads that trigger a breakpoint where one thread has a 1 second delay. """
self.build(dictionary=self.getBuildFlags())
self.do_thread_actions(num_breakpoint_threads=1,
num_delay_breakpoint_threads=1)

View File

@ -0,0 +1,9 @@
LEVEL = ../../../../make
CXX_SOURCES := main.cpp
ENABLE_THREADS := YES
VPATH = ..
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,9 @@
LEVEL = ../../../../make
CXX_SOURCES := main.cpp
ENABLE_THREADS := YES
VPATH = ..
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,21 @@
from __future__ import print_function
import unittest2
from lldbsuite.test.decorators import *
from lldbsuite.test.concurrent_base import ConcurrentEventsBase
from lldbsuite.test.lldbtest import TestBase
@skipIfWindows
class ConcurrentCrashWithBreak(ConcurrentEventsBase):
mydir = ConcurrentEventsBase.compute_mydir(__file__)
@skipIfFreeBSD # timing out on buildbot
# Atomic sequences are not supported yet for MIPS in LLDB.
@skipIf(triple='^mips')
def test(self):
""" Test a thread that crashes while another thread hits a breakpoint."""
self.build(dictionary=self.getBuildFlags())
self.do_thread_actions(num_crash_threads=1, num_breakpoint_threads=1)

View File

@ -0,0 +1,9 @@
LEVEL = ../../../../make
CXX_SOURCES := main.cpp
ENABLE_THREADS := YES
VPATH = ..
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,21 @@
from __future__ import print_function
import unittest2
from lldbsuite.test.decorators import *
from lldbsuite.test.concurrent_base import ConcurrentEventsBase
from lldbsuite.test.lldbtest import TestBase
@skipIfWindows
class ConcurrentCrashWithSignal(ConcurrentEventsBase):
mydir = ConcurrentEventsBase.compute_mydir(__file__)
@skipIfFreeBSD # timing out on buildbot
# Atomic sequences are not supported yet for MIPS in LLDB.
@skipIf(triple='^mips')
def test(self):
""" Test a thread that crashes while another thread generates a signal."""
self.build(dictionary=self.getBuildFlags())
self.do_thread_actions(num_crash_threads=1, num_signal_threads=1)

View File

@ -0,0 +1,9 @@
LEVEL = ../../../../make
CXX_SOURCES := main.cpp
ENABLE_THREADS := YES
VPATH = ..
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,22 @@
from __future__ import print_function
import unittest2
from lldbsuite.test.decorators import *
from lldbsuite.test.concurrent_base import ConcurrentEventsBase
from lldbsuite.test.lldbtest import TestBase
@skipIfWindows
class ConcurrentCrashWithWatchpoint(ConcurrentEventsBase):
mydir = ConcurrentEventsBase.compute_mydir(__file__)
@skipIfFreeBSD # timing out on buildbot
# Atomic sequences are not supported yet for MIPS in LLDB.
@skipIf(triple='^mips')
@add_test_categories(["watchpoint"])
def test(self):
""" Test a thread that crashes while another thread hits a watchpoint."""
self.build(dictionary=self.getBuildFlags())
self.do_thread_actions(num_crash_threads=1, num_watchpoint_threads=1)

View File

@ -0,0 +1,9 @@
LEVEL = ../../../../make
CXX_SOURCES := main.cpp
ENABLE_THREADS := YES
VPATH = ..
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,25 @@
from __future__ import print_function
import unittest2
from lldbsuite.test.decorators import *
from lldbsuite.test.concurrent_base import ConcurrentEventsBase
from lldbsuite.test.lldbtest import TestBase
@skipIfWindows
class ConcurrentCrashWithWatchpointBreakpointSignal(ConcurrentEventsBase):
mydir = ConcurrentEventsBase.compute_mydir(__file__)
@skipIfFreeBSD # timing out on buildbot
# Atomic sequences are not supported yet for MIPS in LLDB.
@skipIf(triple='^mips')
@add_test_categories(["watchpoint"])
def test(self):
""" Test a thread that crashes while other threads generate a signal and hit a watchpoint and breakpoint. """
self.build(dictionary=self.getBuildFlags())
self.do_thread_actions(num_crash_threads=1,
num_breakpoint_threads=1,
num_signal_threads=1,
num_watchpoint_threads=1)

View File

@ -0,0 +1,9 @@
LEVEL = ../../../../make
CXX_SOURCES := main.cpp
ENABLE_THREADS := YES
VPATH = ..
include $(LEVEL)/Makefile.rules

Some files were not shown because too many files have changed in this diff Show More