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
C_SOURCES := locking.c
ENABLE_THREADS := YES
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,63 @@
"""
Test that expr will time out and allow other threads to run if it blocks.
"""
from __future__ import print_function
import os
import time
import re
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class ExprDoesntDeadlockTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
@expectedFailureAll(oslist=['freebsd'], bugnumber='llvm.org/pr17946')
@expectedFailureAll(
oslist=["windows"],
bugnumber="Windows doesn't have pthreads, test needs to be ported")
@add_test_categories(["basic_process"])
def test_with_run_command(self):
"""Test that expr will time out and allow other threads to run if it blocks."""
self.build()
exe = os.path.join(os.getcwd(), "a.out")
# Create a target by the debugger.
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
# Now create a breakpoint at source line before call_me_to_get_lock
# gets called.
main_file_spec = lldb.SBFileSpec("locking.c")
breakpoint = target.BreakpointCreateBySourceRegex(
'Break here', main_file_spec)
if self.TraceOn():
print("breakpoint:", breakpoint)
self.assertTrue(breakpoint and
breakpoint.GetNumLocations() == 1,
VALID_BREAKPOINT)
# Now launch the process, and do not stop at entry point.
process = target.LaunchSimple(
None, None, self.get_process_working_directory())
self.assertTrue(process, PROCESS_IS_VALID)
# Frame #0 should be on self.line1 and the break condition should hold.
from lldbsuite.test.lldbutil import get_stopped_thread
thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
self.assertTrue(
thread.IsValid(),
"There should be a thread stopped due to breakpoint condition")
frame0 = thread.GetFrameAtIndex(0)
var = frame0.EvaluateExpression("call_me_to_get_lock()")
self.assertTrue(var.IsValid())
self.assertTrue(var.GetValueAsSigned(0) == 567)

View File

@ -0,0 +1,80 @@
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
pthread_mutex_t contended_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t control_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t control_condition;
pthread_mutex_t thread_started_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t thread_started_condition;
// This function runs in a thread. The locking dance is to make sure that
// by the time the main thread reaches the pthread_join below, this thread
// has for sure acquired the contended_mutex. So then the call_me_to_get_lock
// function will block trying to get the mutex, and only succeed once it
// signals this thread, then lets it run to wake up from the cond_wait and
// release the mutex.
void *
lock_acquirer_1 (void *input)
{
pthread_mutex_lock (&contended_mutex);
// Grab this mutex, that will ensure that the main thread
// is in its cond_wait for it (since that's when it drops the mutex.
pthread_mutex_lock (&thread_started_mutex);
pthread_mutex_unlock(&thread_started_mutex);
// Now signal the main thread that it can continue, we have the contended lock
// so the call to call_me_to_get_lock won't make any progress till this
// thread gets a chance to run.
pthread_mutex_lock (&control_mutex);
pthread_cond_signal (&thread_started_condition);
pthread_cond_wait (&control_condition, &control_mutex);
pthread_mutex_unlock (&contended_mutex);
return NULL;
}
int
call_me_to_get_lock ()
{
pthread_cond_signal (&control_condition);
pthread_mutex_lock (&contended_mutex);
return 567;
}
int main ()
{
pthread_t thread_1;
pthread_cond_init (&control_condition, NULL);
pthread_cond_init (&thread_started_condition, NULL);
pthread_mutex_lock (&thread_started_mutex);
pthread_create (&thread_1, NULL, lock_acquirer_1, NULL);
pthread_cond_wait (&thread_started_condition, &thread_started_mutex);
pthread_mutex_lock (&control_mutex);
pthread_mutex_unlock (&control_mutex);
// Break here. At this point the other thread will have the contended_mutex,
// and be sitting in its cond_wait for the control condition. So there is
// no way that our by-hand calling of call_me_to_get_lock will proceed
// without running the first thread at least somewhat.
call_me_to_get_lock();
pthread_join (thread_1, NULL);
return 0;
}