forked from OSchip/llvm-project
Get test executables compiling on Windows.
Many of the test executables use pthreads directly. This isn't portable on Windows, so this patch converts these test to use C++11 threads and mutexes. Since Windows' implementation of std::thread classes throw and catch from header files, this patch also disables exceptions when compiling with clang on Windows. Reviewed by: Todd Fiala, Ed Maste Differential Revision: http://reviews.llvm.org/D4816 llvm-svn: 215562
This commit is contained in:
parent
d3d657ca0f
commit
c7826524ac
|
@ -29,6 +29,9 @@
|
|||
#include <lldb/API/SBDebugger.h>
|
||||
#endif
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
#define NUMBER_OF_SIMULTANEOUS_DEBUG_SESSIONS 50
|
||||
|
||||
#define DEBUG 0
|
||||
|
@ -233,10 +236,10 @@ int main (int argc, char **argv)
|
|||
inferior_process_name = argv[1];
|
||||
}
|
||||
|
||||
std::thread threads[NUMBER_OF_SIMULTANEOUS_DEBUG_SESSIONS];
|
||||
for (uint64_t i = 0; i< NUMBER_OF_SIMULTANEOUS_DEBUG_SESSIONS; i++)
|
||||
{
|
||||
pthread_t thread;
|
||||
pthread_create (&thread, NULL, do_one_debugger, (void*) i);
|
||||
threads[i] = std::move(std::thread(do_one_debugger, (void*)i));
|
||||
}
|
||||
|
||||
|
||||
|
@ -244,7 +247,7 @@ int main (int argc, char **argv)
|
|||
int iter = 0;
|
||||
while (1)
|
||||
{
|
||||
sleep (3);
|
||||
std::this_thread::sleep_for(std::chrono::seconds(3));
|
||||
bool all_done = true;
|
||||
int successful_threads = 0;
|
||||
int total_completed_threads = 0;
|
||||
|
|
|
@ -30,6 +30,7 @@ class ExprCommandThatRestartsTestCase(TestBase):
|
|||
@dwarf_test
|
||||
@skipIfLinux # llvm.org/pr19246: intermittent failure
|
||||
@skipIfDarwin # llvm.org/pr19246: intermittent failure
|
||||
@skipIfWindows # Test relies on signals, unsupported on Windows
|
||||
def test_with_dwarf(self):
|
||||
"""Test calling std::String member function."""
|
||||
self.buildDwarf()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
LEVEL = ../../make
|
||||
|
||||
C_SOURCES := wait-a-while.c
|
||||
CXX_SOURCES := wait-a-while.cpp
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
||||
|
|
|
@ -15,7 +15,7 @@ class ExprCommandWithTimeoutsTestCase(TestBase):
|
|||
# Call super's setUp().
|
||||
TestBase.setUp(self)
|
||||
|
||||
self.main_source = "wait-a-while.c"
|
||||
self.main_source = "wait-a-while.cpp"
|
||||
self.main_source_spec = lldb.SBFileSpec (self.main_source)
|
||||
|
||||
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <stdint.h>
|
||||
|
||||
int
|
||||
wait_a_while (useconds_t interval)
|
||||
{
|
||||
int num_times = 0;
|
||||
int return_value = 1;
|
||||
|
||||
struct timeval start_time;
|
||||
gettimeofday(&start_time, NULL);
|
||||
uint64_t target = start_time.tv_sec * 1000000 + start_time.tv_usec + interval;
|
||||
|
||||
while (1)
|
||||
{
|
||||
num_times++;
|
||||
return_value = usleep (interval);
|
||||
if (return_value != 0)
|
||||
{
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
interval = target - (now.tv_sec * 1000000 + now.tv_usec);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
return num_times;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
printf ("stop here in main.\n");
|
||||
int num_times = wait_a_while (argc * 1000);
|
||||
printf ("Done, took %d times.\n", num_times);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
|
||||
int
|
||||
wait_a_while (int microseconds)
|
||||
{
|
||||
int num_times = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
num_times++;
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(microseconds));
|
||||
break;
|
||||
}
|
||||
return num_times;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
printf ("stop here in main.\n");
|
||||
int num_times = wait_a_while (argc * 1000);
|
||||
printf ("Done, took %d times.\n", num_times);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
|
@ -1,8 +1,7 @@
|
|||
LEVEL = ../../make
|
||||
|
||||
C_SOURCES := main.c
|
||||
LD_EXTRAS := -lpthread
|
||||
|
||||
CXX_SOURCES := main.cpp
|
||||
ENABLE_THREADS := Yes
|
||||
EXE := AttachResume
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
||||
|
|
|
@ -70,7 +70,7 @@ class AttachResumeTestCase(TestBase):
|
|||
'Process not stopped after interrupt')
|
||||
|
||||
# check that this breakpoint is auto-cleared on detach (r204752)
|
||||
self.runCmd("br set -f main.c -l 12")
|
||||
self.runCmd("br set -f main.cpp -l 12")
|
||||
|
||||
self.runCmd("c")
|
||||
self.assertTrue(wait_for_state(lldb.eStateRunning),
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
void *start(void *data)
|
||||
{
|
||||
|
@ -10,8 +11,8 @@ void *start(void *data)
|
|||
for (i=0; i<30; i++)
|
||||
{
|
||||
if ( idx == 0 )
|
||||
usleep(1);
|
||||
sleep(1);
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(1));
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -19,14 +20,12 @@ void *start(void *data)
|
|||
int main(int argc, char const *argv[])
|
||||
{
|
||||
static const size_t nthreads = 16;
|
||||
pthread_attr_t attr;
|
||||
pthread_t threads[nthreads];
|
||||
std::thread threads[nthreads];
|
||||
size_t i;
|
||||
|
||||
pthread_attr_init(&attr);
|
||||
for (i=0; i<nthreads; i++)
|
||||
pthread_create(&threads[i], &attr, &start, (void *)i);
|
||||
threads[i] = std::move(std::thread(start, (void*)i));
|
||||
|
||||
for (i=0; i<nthreads; i++)
|
||||
pthread_join(threads[i], 0);
|
||||
threads[i].join();
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
LEVEL = ../../make
|
||||
|
||||
CFLAGS_EXTRAS := -lpthread
|
||||
C_SOURCES := locking.c
|
||||
ENABLE_THREADS := YES
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
LD_EXTRAS := -lpthread
|
||||
CXX_SOURCES := main.cpp
|
||||
ENABLE_THREADS := YES
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
LEVEL = ../../make
|
||||
|
||||
C_SOURCES := main.c
|
||||
LD_EXTRAS := -lpthread
|
||||
ENABLE_THREADS := YES
|
||||
include $(LEVEL)/Makefile.rules
|
||||
|
|
|
@ -2,7 +2,6 @@ LEVEL = ../../../make
|
|||
|
||||
CXX_SOURCES := main.cpp
|
||||
|
||||
CFLAGS_EXTRAS += -std=c++11 -lpthread
|
||||
LD_EXTRAS += -lpthread
|
||||
ENABLE_THREADS := YES
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
LEVEL = ../../../make
|
||||
CXX_SOURCES := main.cpp
|
||||
LD_EXTRAS := -lpthread
|
||||
|
||||
CFLAGS_EXTRAS += -std=c++11
|
||||
CXX_SOURCES := main.cpp
|
||||
ENABLE_THREADS := YES
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
C_SOURCES := main.c
|
||||
LD_EXTRAS := -lpthread
|
||||
ENABLE_THREADS := YES
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
LD_EXTRAS := -lpthread
|
||||
ENABLE_THREADS := YES
|
||||
CXX_SOURCES := main.cpp
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
LD_EXTRAS := -lpthread
|
||||
ENABLE_THREADS := YES
|
||||
CXX_SOURCES := main.cpp
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
LD_EXTRAS := -lpthread
|
||||
ENABLE_THREADS := YES
|
||||
CXX_SOURCES := main.cpp
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
||||
|
|
|
@ -6,6 +6,6 @@ CFLAGS_EXTRAS += -fPIC
|
|||
DYLIB_NAME := a
|
||||
DYLIB_C_SOURCES := a.c
|
||||
|
||||
LD_EXTRAS += -lpthread
|
||||
ENABLE_THREADS := YES
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
||||
|
|
|
@ -554,6 +554,21 @@ def skipIfLinux(func):
|
|||
func(*args, **kwargs)
|
||||
return wrapper
|
||||
|
||||
def skipIfWindows(func):
|
||||
"""Decorate the item to skip tests that should be skipped on Windows."""
|
||||
if isinstance(func, type) and issubclass(func, unittest2.TestCase):
|
||||
raise Exception("@skipIfWindows can only be used to decorate a test method")
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
from unittest2 import case
|
||||
self = args[0]
|
||||
platform = sys.platform
|
||||
if "win32" in platform:
|
||||
self.skipTest("skip on Windows")
|
||||
else:
|
||||
func(*args, **kwargs)
|
||||
return wrapper
|
||||
|
||||
def skipIfDarwin(func):
|
||||
"""Decorate the item to skip tests that should be skipped on Darwin."""
|
||||
if isinstance(func, type) and issubclass(func, unittest2.TestCase):
|
||||
|
|
|
@ -26,6 +26,9 @@
|
|||
# Uncomment line below for debugging shell commands
|
||||
# SHELL = /bin/sh -x
|
||||
|
||||
THIS_FILE_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))/
|
||||
LLDB_BASE_DIR := $(THIS_FILE_DIR)../../
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# If ARCH is not defined, default to x86_64.
|
||||
# If OS is not defined, use 'uname -s' to determine the OS name.
|
||||
|
@ -73,7 +76,7 @@ else
|
|||
# On non-Apple platforms, -arch becomes -m
|
||||
ARCHFLAG := -m
|
||||
|
||||
# i386,i686 -> 32
|
||||
# i386, i686, x86 -> 32
|
||||
# amd64, x86_64, x64 -> 64
|
||||
ifeq "$(ARCH)" "amd64"
|
||||
override ARCH := $(subst amd64,64,$(ARCH))
|
||||
|
@ -84,6 +87,9 @@ else
|
|||
ifeq "$(ARCH)" "x64"
|
||||
override ARCH := $(subst x64,64,$(ARCH))
|
||||
endif
|
||||
ifeq "$(ARCH)" "x86"
|
||||
override ARCH := $(subst x86,32,$(ARCH))
|
||||
endif
|
||||
ifeq "$(ARCH)" "i386"
|
||||
override ARCH := $(subst i386,32,$(ARCH))
|
||||
endif
|
||||
|
@ -97,15 +103,21 @@ else
|
|||
endif
|
||||
|
||||
CFLAGS ?= -g -O0
|
||||
CFLAGS += $(ARCHFLAG)$(ARCH) $(FRAMEWORK_INCLUDES) $(CFLAGS_EXTRAS)
|
||||
CFLAGS += $(ARCHFLAG)$(ARCH) $(FRAMEWORK_INCLUDES) $(CFLAGS_EXTRAS) -I$(LLDB_BASE_DIR)include
|
||||
|
||||
# Use this one if you want to build one part of the result without debug information:
|
||||
CFLAGS_NO_DEBUG = -O0 $(ARCHFLAG)$(ARCH) $(FRAMEWORK_INCLUDES) $(CFLAGS_EXTRAS)
|
||||
|
||||
CXXFLAGS +=$(CFLAGS)
|
||||
CXXFLAGS += -std=c++11
|
||||
CXXFLAGS += $(CFLAGS)
|
||||
LD = $(CC)
|
||||
LDFLAGS ?= $(CFLAGS)
|
||||
LDFLAGS += $(LD_EXTRAS)
|
||||
ifneq "$(OS)" "Windows_NT"
|
||||
ifeq "$(ENABLE_THREADS)" "Yes"
|
||||
LDFLAGS += -lpthread
|
||||
endif
|
||||
endif
|
||||
OBJECTS =
|
||||
EXE ?= a.out
|
||||
|
||||
|
@ -125,6 +137,17 @@ cxx_compiler = $(if $(findstring /,$(1)),$(join $(dir $(1)), $(call cxx_compiler
|
|||
cxx_linker_notdir = $(if $(findstring clang,$(1)), $(subst clang,clang++,$(1)), $(if $(findstring icc,$(1)), $(subst icc,icpc,$(1)), $(if $(findstring llvm-gcc,$(1)), $(subst llvm-gcc,llvm-g++,$(1)), $(subst gcc,g++,$(1)))))
|
||||
cxx_linker = $(if $(findstring /,$(1)),$(join $(dir $(1)), $(call cxx_linker_notdir,$(notdir $(1)))),$(call cxx_linker_notdir,$(1)))
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# Clang for Windows doesn't yet support exceptions
|
||||
#----------------------------------------------------------------------
|
||||
ifeq "$(OS)" "Windows_NT"
|
||||
ifneq (,$(findstring clang,$(CC)))
|
||||
CXXFLAGS += -fno-exceptions
|
||||
CXXFLAGS += -include $(THIS_FILE_DIR)uncaught_exception.h
|
||||
CXXFLAGS += -D_HAS_EXCEPTIONS=0
|
||||
endif
|
||||
endif
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# C++ standard library options
|
||||
#----------------------------------------------------------------------
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
// MSVC header files have compilation issues when compiling with exceptions disabled. Notably,
|
||||
// this function is compiled out when _HAS_EXCEPTIONS=0, but this function is called from another
|
||||
// place even when _HAS_EXCEPTIONS=0. So we define a dummy implementation as a workaround and
|
||||
// force include this header file.
|
||||
static void *__uncaught_exception() { return nullptr; }
|
|
@ -1,8 +1,8 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
CFLAGS_EXTRAS := -D__STDC_LIMIT_MACROS
|
||||
LD_EXTRAS := -lpthread
|
||||
ENABLE_THREADS := YES
|
||||
CXX_SOURCES := main.cpp
|
||||
MAKE_DSYM :=NO
|
||||
MAKE_DSYM := NO
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
||||
|
|
|
@ -8,15 +8,20 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// C includes
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
pthread_t g_thread_1 = NULL;
|
||||
pthread_t g_thread_2 = NULL;
|
||||
pthread_t g_thread_3 = NULL;
|
||||
// C++ includes
|
||||
#include <chrono>
|
||||
#include <mutex>
|
||||
#include <random>
|
||||
#include <thread>
|
||||
|
||||
std::thread g_thread_1;
|
||||
std::thread g_thread_2;
|
||||
std::thread g_thread_3;
|
||||
std::mutex g_mask_mutex;
|
||||
|
||||
typedef enum {
|
||||
eGet,
|
||||
|
@ -29,9 +34,9 @@ uint32_t mask_access (MaskAction action, uint32_t mask = 0);
|
|||
uint32_t
|
||||
mask_access (MaskAction action, uint32_t mask)
|
||||
{
|
||||
static pthread_mutex_t g_mask_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static uint32_t g_mask = 0;
|
||||
::pthread_mutex_lock (&g_mask_mutex);
|
||||
|
||||
std::lock_guard<std::mutex> lock(g_mask_mutex);
|
||||
switch (action)
|
||||
{
|
||||
case eGet:
|
||||
|
@ -45,9 +50,7 @@ mask_access (MaskAction action, uint32_t mask)
|
|||
g_mask &= ~mask;
|
||||
break;
|
||||
}
|
||||
uint32_t new_mask = g_mask;
|
||||
::pthread_mutex_unlock (&g_mask_mutex);
|
||||
return new_mask;
|
||||
return g_mask;
|
||||
}
|
||||
|
||||
void *
|
||||
|
@ -57,12 +60,17 @@ thread_func (void *arg)
|
|||
uint32_t thread_mask = (1u << (thread_index));
|
||||
printf ("%s (thread index = %u) startng...\n", __FUNCTION__, thread_index);
|
||||
|
||||
std::default_random_engine generator;
|
||||
std::uniform_int_distribution<int> distribution(0, 3000000);
|
||||
|
||||
while (mask_access(eGet) & thread_mask)
|
||||
{
|
||||
// random micro second sleep from zero to 3 seconds
|
||||
int usec = ::rand() % 3000000;
|
||||
int usec = distribution(generator);
|
||||
printf ("%s (thread = %u) doing a usleep (%d)...\n", __FUNCTION__, thread_index, usec);
|
||||
::usleep (usec);
|
||||
|
||||
std::chrono::microseconds duration(usec);
|
||||
std::this_thread::sleep_for(duration);
|
||||
printf ("%s (thread = %u) after usleep ...\n", __FUNCTION__, thread_index); // Set break point at this line.
|
||||
}
|
||||
printf ("%s (thread index = %u) exiting...\n", __FUNCTION__, thread_index);
|
||||
|
@ -72,8 +80,6 @@ thread_func (void *arg)
|
|||
|
||||
int main (int argc, char const *argv[])
|
||||
{
|
||||
int err;
|
||||
void *thread_result = NULL;
|
||||
uint32_t thread_index_1 = 1;
|
||||
uint32_t thread_index_2 = 2;
|
||||
uint32_t thread_index_3 = 3;
|
||||
|
@ -85,9 +91,9 @@ int main (int argc, char const *argv[])
|
|||
mask_access (eAssign, thread_mask_1 | thread_mask_2 | thread_mask_3); // And that line.
|
||||
|
||||
// Create 3 threads
|
||||
err = ::pthread_create (&g_thread_1, NULL, thread_func, &thread_index_1);
|
||||
err = ::pthread_create (&g_thread_2, NULL, thread_func, &thread_index_2);
|
||||
err = ::pthread_create (&g_thread_3, NULL, thread_func, &thread_index_3);
|
||||
g_thread_1 = std::thread(thread_func, (void*)&thread_index_1);
|
||||
g_thread_2 = std::thread(thread_func, (void*)&thread_index_2);
|
||||
g_thread_3 = std::thread(thread_func, (void*)&thread_index_3);
|
||||
|
||||
char line[64];
|
||||
while (mask_access(eGet) != 0)
|
||||
|
@ -120,9 +126,9 @@ int main (int argc, char const *argv[])
|
|||
mask_access (eClearBits, UINT32_MAX);
|
||||
|
||||
// Join all of our threads
|
||||
err = ::pthread_join (g_thread_1, &thread_result);
|
||||
err = ::pthread_join (g_thread_2, &thread_result);
|
||||
err = ::pthread_join (g_thread_3, &thread_result);
|
||||
g_thread_1.join();
|
||||
g_thread_2.join();
|
||||
g_thread_3.join();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
CFLAGS_EXTRAS := -D__STDC_LIMIT_MACROS
|
||||
LD_EXTRAS := -lpthread
|
||||
ENABLE_THREADS := YES
|
||||
CXX_SOURCES := main.cpp
|
||||
MAKE_DSYM :=NO
|
||||
|
||||
|
|
|
@ -8,15 +8,20 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// C includes
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
pthread_t g_thread_1 = NULL;
|
||||
pthread_t g_thread_2 = NULL;
|
||||
pthread_t g_thread_3 = NULL;
|
||||
// C++ includes
|
||||
#include <chrono>
|
||||
#include <mutex>
|
||||
#include <random>
|
||||
#include <thread>
|
||||
|
||||
std::thread g_thread_1;
|
||||
std::thread g_thread_2;
|
||||
std::thread g_thread_3;
|
||||
std::mutex g_mask_mutex;
|
||||
|
||||
typedef enum {
|
||||
eGet,
|
||||
|
@ -29,9 +34,9 @@ uint32_t mask_access (MaskAction action, uint32_t mask = 0);
|
|||
uint32_t
|
||||
mask_access (MaskAction action, uint32_t mask)
|
||||
{
|
||||
static pthread_mutex_t g_mask_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static uint32_t g_mask = 0;
|
||||
::pthread_mutex_lock (&g_mask_mutex);
|
||||
|
||||
std::lock_guard<std::mutex> lock(g_mask_mutex);
|
||||
switch (action)
|
||||
{
|
||||
case eGet:
|
||||
|
@ -45,9 +50,7 @@ mask_access (MaskAction action, uint32_t mask)
|
|||
g_mask &= ~mask;
|
||||
break;
|
||||
}
|
||||
uint32_t new_mask = g_mask;
|
||||
::pthread_mutex_unlock (&g_mask_mutex);
|
||||
return new_mask;
|
||||
return g_mask;
|
||||
}
|
||||
|
||||
void *
|
||||
|
@ -57,12 +60,17 @@ thread_func (void *arg)
|
|||
uint32_t thread_mask = (1u << (thread_index));
|
||||
printf ("%s (thread index = %u) startng...\n", __FUNCTION__, thread_index);
|
||||
|
||||
std::default_random_engine generator;
|
||||
std::uniform_int_distribution<int> distribution(0, 3000000);
|
||||
|
||||
while (mask_access(eGet) & thread_mask)
|
||||
{
|
||||
// random micro second sleep from zero to 3 seconds
|
||||
int usec = ::rand() % 3000000;
|
||||
int usec = distribution(generator);
|
||||
|
||||
printf ("%s (thread = %u) doing a usleep (%d)...\n", __FUNCTION__, thread_index, usec);
|
||||
::usleep (usec);
|
||||
std::chrono::microseconds duration(usec);
|
||||
std::this_thread::sleep_for(duration);
|
||||
printf ("%s (thread = %u) after usleep ...\n", __FUNCTION__, thread_index); // Set break point at this line.
|
||||
}
|
||||
printf ("%s (thread index = %u) exiting...\n", __FUNCTION__, thread_index);
|
||||
|
@ -85,9 +93,9 @@ int main (int argc, char const *argv[])
|
|||
mask_access (eAssign, thread_mask_1 | thread_mask_2 | thread_mask_3); // And that line.
|
||||
|
||||
// Create 3 threads
|
||||
err = ::pthread_create (&g_thread_1, NULL, thread_func, &thread_index_1);
|
||||
err = ::pthread_create (&g_thread_2, NULL, thread_func, &thread_index_2);
|
||||
err = ::pthread_create (&g_thread_3, NULL, thread_func, &thread_index_3);
|
||||
g_thread_1 = std::thread(thread_func, (void*)&thread_index_1);
|
||||
g_thread_2 = std::thread(thread_func, (void*)&thread_index_2);
|
||||
g_thread_3 = std::thread(thread_func, (void*)&thread_index_3);
|
||||
|
||||
char line[64];
|
||||
while (mask_access(eGet) != 0)
|
||||
|
@ -120,9 +128,9 @@ int main (int argc, char const *argv[])
|
|||
mask_access (eClearBits, UINT32_MAX);
|
||||
|
||||
// Join all of our threads
|
||||
err = ::pthread_join (g_thread_1, &thread_result);
|
||||
err = ::pthread_join (g_thread_2, &thread_result);
|
||||
err = ::pthread_join (g_thread_3, &thread_result);
|
||||
g_thread_1.join();
|
||||
g_thread_2.join();
|
||||
g_thread_3.join();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
LEVEL = ../../make
|
||||
|
||||
CFLAGS_EXTRAS := -D__STDC_LIMIT_MACROS
|
||||
LD_EXTRAS := -lpthread
|
||||
ENABLE_THREADS := YES
|
||||
CXX_SOURCES := main.cpp b.cpp c.cpp
|
||||
MAKE_DSYM :=NO
|
||||
|
||||
|
|
|
@ -8,15 +8,20 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// C includes
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
pthread_t g_thread_1 = NULL;
|
||||
pthread_t g_thread_2 = NULL;
|
||||
pthread_t g_thread_3 = NULL;
|
||||
// C++ includes
|
||||
#include <chrono>
|
||||
#include <mutex>
|
||||
#include <random>
|
||||
#include <thread>
|
||||
|
||||
std::thread g_thread_1;
|
||||
std::thread g_thread_2;
|
||||
std::thread g_thread_3;
|
||||
std::mutex g_mask_mutex;
|
||||
|
||||
typedef enum {
|
||||
eGet,
|
||||
|
@ -29,9 +34,9 @@ uint32_t mask_access (MaskAction action, uint32_t mask = 0);
|
|||
uint32_t
|
||||
mask_access (MaskAction action, uint32_t mask)
|
||||
{
|
||||
static pthread_mutex_t g_mask_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static uint32_t g_mask = 0;
|
||||
::pthread_mutex_lock (&g_mask_mutex);
|
||||
|
||||
std::lock_guard<std::mutex> lock(g_mask_mutex);
|
||||
switch (action)
|
||||
{
|
||||
case eGet:
|
||||
|
@ -45,9 +50,7 @@ mask_access (MaskAction action, uint32_t mask)
|
|||
g_mask &= ~mask;
|
||||
break;
|
||||
}
|
||||
uint32_t new_mask = g_mask;
|
||||
::pthread_mutex_unlock (&g_mask_mutex);
|
||||
return new_mask;
|
||||
return g_mask;
|
||||
}
|
||||
|
||||
void *
|
||||
|
@ -57,12 +60,17 @@ thread_func (void *arg)
|
|||
uint32_t thread_mask = (1u << (thread_index));
|
||||
printf ("%s (thread index = %u) startng...\n", __FUNCTION__, thread_index);
|
||||
|
||||
std::default_random_engine generator;
|
||||
std::uniform_int_distribution<int> distribution(0, 3000000);
|
||||
|
||||
while (mask_access(eGet) & thread_mask)
|
||||
{
|
||||
// random micro second sleep from zero to 3 seconds
|
||||
int usec = ::rand() % 3000000;
|
||||
int usec = distribution(generator);
|
||||
|
||||
printf ("%s (thread = %u) doing a usleep (%d)...\n", __FUNCTION__, thread_index, usec);
|
||||
::usleep (usec);
|
||||
std::chrono::microseconds duration(usec);
|
||||
std::this_thread::sleep_for(duration);
|
||||
printf ("%s (thread = %u) after usleep ...\n", __FUNCTION__, thread_index); // Set break point at this line.
|
||||
}
|
||||
printf ("%s (thread index = %u) exiting...\n", __FUNCTION__, thread_index);
|
||||
|
@ -85,9 +93,9 @@ int main (int argc, char const *argv[])
|
|||
mask_access (eAssign, thread_mask_1 | thread_mask_2 | thread_mask_3); // And that line.
|
||||
|
||||
// Create 3 threads
|
||||
err = ::pthread_create (&g_thread_1, NULL, thread_func, &thread_index_1);
|
||||
err = ::pthread_create (&g_thread_2, NULL, thread_func, &thread_index_2);
|
||||
err = ::pthread_create (&g_thread_3, NULL, thread_func, &thread_index_3);
|
||||
g_thread_1 = std::thread(thread_func, (void*)&thread_index_1);
|
||||
g_thread_2 = std::thread(thread_func, (void*)&thread_index_2);
|
||||
g_thread_3 = std::thread(thread_func, (void*)&thread_index_3);
|
||||
|
||||
char line[64];
|
||||
while (mask_access(eGet) != 0)
|
||||
|
@ -120,9 +128,9 @@ int main (int argc, char const *argv[])
|
|||
mask_access (eClearBits, UINT32_MAX);
|
||||
|
||||
// Join all of our threads
|
||||
err = ::pthread_join (g_thread_1, &thread_result);
|
||||
err = ::pthread_join (g_thread_2, &thread_result);
|
||||
err = ::pthread_join (g_thread_3, &thread_result);
|
||||
g_thread_1.join();
|
||||
g_thread_2.join();
|
||||
g_thread_3.join();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -8,13 +8,21 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
// This simple program is to test the lldb Python API related to process.
|
||||
|
||||
int main (int argc, char const *argv[])
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
::ExitProcess(1);
|
||||
#else
|
||||
kill(getpid(), SIGINT); // Set break point at this line and setup signal ignores.
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
LD_EXTRAS := -lpthread
|
||||
ENABLE_THREADS := YES
|
||||
CXX_SOURCES := main.cpp
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
LEVEL = ../../make
|
||||
|
||||
CFLAGS_EXTRAS := -D__STDC_LIMIT_MACROS -D__STDC_FORMAT_MACROS -std=c++11
|
||||
LD_EXTRAS := -lpthread
|
||||
CFLAGS_EXTRAS := -D__STDC_LIMIT_MACROS -D__STDC_FORMAT_MACROS
|
||||
ENABLE_THREADS := YES
|
||||
CXX_SOURCES := main.cpp
|
||||
MAKE_DSYM :=NO
|
||||
|
||||
|
|
Loading…
Reference in New Issue