mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-09-10 12:22:20 +08:00
Add infrastructure for threading support.
This commit is contained in:
@ -18,6 +18,10 @@ INCLUDES = -D_GNU_SOURCE \
|
|||||||
|
|
||||||
LIBIBERTY = ../libiberty/libiberty.a
|
LIBIBERTY = ../libiberty/libiberty.a
|
||||||
|
|
||||||
|
if THREADS
|
||||||
|
THREADSLIB = -lpthread
|
||||||
|
endif
|
||||||
|
|
||||||
AM_YFLAGS = -d
|
AM_YFLAGS = -d
|
||||||
|
|
||||||
noinst_PROGRAMS = ld-new
|
noinst_PROGRAMS = ld-new
|
||||||
@ -95,7 +99,7 @@ libgold_a_SOURCES = $(CCFILES) $(HFILES) $(YFILES)
|
|||||||
|
|
||||||
sources_var = main.cc
|
sources_var = main.cc
|
||||||
deps_var = $(TARGETOBJS) libgold.a $(LIBIBERTY) $(LIBINTL_DEP)
|
deps_var = $(TARGETOBJS) libgold.a $(LIBIBERTY) $(LIBINTL_DEP)
|
||||||
ldadd_var = $(TARGETOBJS) libgold.a $(LIBIBERTY) $(LIBINTL)
|
ldadd_var = $(TARGETOBJS) libgold.a $(LIBIBERTY) $(LIBINTL) $(THREADSLIB)
|
||||||
|
|
||||||
ld_new_SOURCES = $(sources_var)
|
ld_new_SOURCES = $(sources_var)
|
||||||
ld_new_DEPENDENCIES = $(deps_var) $(LIBOBJS)
|
ld_new_DEPENDENCIES = $(deps_var) $(LIBOBJS)
|
||||||
|
@ -91,7 +91,8 @@ ld_new_OBJECTS = $(am_ld_new_OBJECTS)
|
|||||||
am__DEPENDENCIES_1 =
|
am__DEPENDENCIES_1 =
|
||||||
am__DEPENDENCIES_2 = ../libiberty/libiberty.a
|
am__DEPENDENCIES_2 = ../libiberty/libiberty.a
|
||||||
am__DEPENDENCIES_3 = $(am__DEPENDENCIES_1) libgold.a \
|
am__DEPENDENCIES_3 = $(am__DEPENDENCIES_1) libgold.a \
|
||||||
$(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
|
$(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \
|
||||||
|
$(am__DEPENDENCIES_1)
|
||||||
am__DEPENDENCIES_4 = @LIBOBJS@
|
am__DEPENDENCIES_4 = @LIBOBJS@
|
||||||
am__ld1_SOURCES_DIST = main.cc
|
am__ld1_SOURCES_DIST = main.cc
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@am_ld1_OBJECTS = $(am__objects_4)
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@am_ld1_OBJECTS = $(am__objects_4)
|
||||||
@ -210,6 +211,8 @@ STATIC_TLS_FALSE = @STATIC_TLS_FALSE@
|
|||||||
STATIC_TLS_TRUE = @STATIC_TLS_TRUE@
|
STATIC_TLS_TRUE = @STATIC_TLS_TRUE@
|
||||||
STRIP = @STRIP@
|
STRIP = @STRIP@
|
||||||
TARGETOBJS = @TARGETOBJS@
|
TARGETOBJS = @TARGETOBJS@
|
||||||
|
THREADS_FALSE = @THREADS_FALSE@
|
||||||
|
THREADS_TRUE = @THREADS_TRUE@
|
||||||
TLS_FALSE = @TLS_FALSE@
|
TLS_FALSE = @TLS_FALSE@
|
||||||
TLS_TRUE = @TLS_TRUE@
|
TLS_TRUE = @TLS_TRUE@
|
||||||
USE_NLS = @USE_NLS@
|
USE_NLS = @USE_NLS@
|
||||||
@ -275,6 +278,7 @@ INCLUDES = -D_GNU_SOURCE \
|
|||||||
@INCINTL@
|
@INCINTL@
|
||||||
|
|
||||||
LIBIBERTY = ../libiberty/libiberty.a
|
LIBIBERTY = ../libiberty/libiberty.a
|
||||||
|
@THREADS_TRUE@THREADSLIB = -lpthread
|
||||||
AM_YFLAGS = -d
|
AM_YFLAGS = -d
|
||||||
noinst_LIBRARIES = libgold.a
|
noinst_LIBRARIES = libgold.a
|
||||||
CCFILES = \
|
CCFILES = \
|
||||||
@ -347,7 +351,7 @@ ALL_TARGETOBJS = \
|
|||||||
libgold_a_SOURCES = $(CCFILES) $(HFILES) $(YFILES)
|
libgold_a_SOURCES = $(CCFILES) $(HFILES) $(YFILES)
|
||||||
sources_var = main.cc
|
sources_var = main.cc
|
||||||
deps_var = $(TARGETOBJS) libgold.a $(LIBIBERTY) $(LIBINTL_DEP)
|
deps_var = $(TARGETOBJS) libgold.a $(LIBIBERTY) $(LIBINTL_DEP)
|
||||||
ldadd_var = $(TARGETOBJS) libgold.a $(LIBIBERTY) $(LIBINTL)
|
ldadd_var = $(TARGETOBJS) libgold.a $(LIBIBERTY) $(LIBINTL) $(THREADSLIB)
|
||||||
ld_new_SOURCES = $(sources_var)
|
ld_new_SOURCES = $(sources_var)
|
||||||
ld_new_DEPENDENCIES = $(deps_var) $(LIBOBJS)
|
ld_new_DEPENDENCIES = $(deps_var) $(LIBOBJS)
|
||||||
ld_new_LDADD = $(ldadd_var) $(LIBOBJS)
|
ld_new_LDADD = $(ldadd_var) $(LIBOBJS)
|
||||||
|
@ -4,6 +4,9 @@
|
|||||||
language is requested. */
|
language is requested. */
|
||||||
#undef ENABLE_NLS
|
#undef ENABLE_NLS
|
||||||
|
|
||||||
|
/* Define to do multi-threaded linking */
|
||||||
|
#undef ENABLE_THREADS
|
||||||
|
|
||||||
/* Define to 1 if you have the <ext/hash_map> header file. */
|
/* Define to 1 if you have the <ext/hash_map> header file. */
|
||||||
#undef HAVE_EXT_HASH_MAP
|
#undef HAVE_EXT_HASH_MAP
|
||||||
|
|
||||||
|
41
gold/configure
vendored
41
gold/configure
vendored
@ -309,7 +309,7 @@ ac_includes_default="\
|
|||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
#endif"
|
#endif"
|
||||||
|
|
||||||
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar TARGETOBJS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE YACC RANLIB ac_ct_RANLIB LN_S USE_NLS LIBINTL LIBINTL_DEP INCINTL XGETTEXT GMSGFMT POSUB CATALOGS DATADIRNAME INSTOBJEXT GENCAT CATOBJEXT MKINSTALLDIRS MSGFMT MSGMERGE NATIVE_LINKER_TRUE NATIVE_LINKER_FALSE GCC_TRUE GCC_FALSE FN_PTRS_IN_SO_WITHOUT_PIC_TRUE FN_PTRS_IN_SO_WITHOUT_PIC_FALSE TLS_TRUE TLS_FALSE STATIC_TLS_TRUE STATIC_TLS_FALSE WARN_CFLAGS NO_WERROR WARN_CXXFLAGS LFS_CXXFLAGS LIBOBJS CXXCPP EGREP MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT LTLIBOBJS'
|
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar THREADS_TRUE THREADS_FALSE TARGETOBJS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE YACC RANLIB ac_ct_RANLIB LN_S USE_NLS LIBINTL LIBINTL_DEP INCINTL XGETTEXT GMSGFMT POSUB CATALOGS DATADIRNAME INSTOBJEXT GENCAT CATOBJEXT MKINSTALLDIRS MSGFMT MSGMERGE NATIVE_LINKER_TRUE NATIVE_LINKER_FALSE GCC_TRUE GCC_FALSE FN_PTRS_IN_SO_WITHOUT_PIC_TRUE FN_PTRS_IN_SO_WITHOUT_PIC_FALSE TLS_TRUE TLS_FALSE STATIC_TLS_TRUE STATIC_TLS_FALSE WARN_CFLAGS NO_WERROR WARN_CXXFLAGS LFS_CXXFLAGS LIBOBJS CXXCPP EGREP MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT LTLIBOBJS'
|
||||||
ac_subst_files=''
|
ac_subst_files=''
|
||||||
|
|
||||||
# Initialize some variables set by options.
|
# Initialize some variables set by options.
|
||||||
@ -860,6 +860,7 @@ if test -n "$ac_init_help"; then
|
|||||||
Optional Features:
|
Optional Features:
|
||||||
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
|
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
|
||||||
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
|
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
|
||||||
|
--enable-threads multi-threaded linking
|
||||||
--enable-targets alternative target configurations
|
--enable-targets alternative target configurations
|
||||||
--disable-dependency-tracking speeds up one-time build
|
--disable-dependency-tracking speeds up one-time build
|
||||||
--enable-dependency-tracking do not reject slow dependency extractors
|
--enable-dependency-tracking do not reject slow dependency extractors
|
||||||
@ -1897,6 +1898,35 @@ cat >>confdefs.h <<_ACEOF
|
|||||||
_ACEOF
|
_ACEOF
|
||||||
|
|
||||||
|
|
||||||
|
# Check whether --enable-threads or --disable-threads was given.
|
||||||
|
if test "${enable_threads+set}" = set; then
|
||||||
|
enableval="$enable_threads"
|
||||||
|
case "${enableval}" in
|
||||||
|
yes | "") threads=yes ;;
|
||||||
|
no) threads=no ;;
|
||||||
|
*) threads=yes ;;
|
||||||
|
esac
|
||||||
|
else
|
||||||
|
threads=no
|
||||||
|
fi;
|
||||||
|
if test "$threads" = "yes"; then
|
||||||
|
|
||||||
|
cat >>confdefs.h <<\_ACEOF
|
||||||
|
#define ENABLE_THREADS 1
|
||||||
|
_ACEOF
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if test "$threads" = "yes"; then
|
||||||
|
THREADS_TRUE=
|
||||||
|
THREADS_FALSE='#'
|
||||||
|
else
|
||||||
|
THREADS_TRUE='#'
|
||||||
|
THREADS_FALSE=
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
# Check whether --enable-targets or --disable-targets was given.
|
# Check whether --enable-targets or --disable-targets was given.
|
||||||
if test "${enable_targets+set}" = set; then
|
if test "${enable_targets+set}" = set; then
|
||||||
enableval="$enable_targets"
|
enableval="$enable_targets"
|
||||||
@ -5791,6 +5821,13 @@ LIBOBJS=$ac_libobjs
|
|||||||
LTLIBOBJS=$ac_ltlibobjs
|
LTLIBOBJS=$ac_ltlibobjs
|
||||||
|
|
||||||
|
|
||||||
|
if test -z "${THREADS_TRUE}" && test -z "${THREADS_FALSE}"; then
|
||||||
|
{ { echo "$as_me:$LINENO: error: conditional \"THREADS\" was never defined.
|
||||||
|
Usually this means the macro was only invoked conditionally." >&5
|
||||||
|
echo "$as_me: error: conditional \"THREADS\" was never defined.
|
||||||
|
Usually this means the macro was only invoked conditionally." >&2;}
|
||||||
|
{ (exit 1); exit 1; }; }
|
||||||
|
fi
|
||||||
if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
|
if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
|
||||||
{ { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined.
|
{ { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined.
|
||||||
Usually this means the macro was only invoked conditionally." >&5
|
Usually this means the macro was only invoked conditionally." >&5
|
||||||
@ -6430,6 +6467,8 @@ s,@am__leading_dot@,$am__leading_dot,;t t
|
|||||||
s,@AMTAR@,$AMTAR,;t t
|
s,@AMTAR@,$AMTAR,;t t
|
||||||
s,@am__tar@,$am__tar,;t t
|
s,@am__tar@,$am__tar,;t t
|
||||||
s,@am__untar@,$am__untar,;t t
|
s,@am__untar@,$am__untar,;t t
|
||||||
|
s,@THREADS_TRUE@,$THREADS_TRUE,;t t
|
||||||
|
s,@THREADS_FALSE@,$THREADS_FALSE,;t t
|
||||||
s,@TARGETOBJS@,$TARGETOBJS,;t t
|
s,@TARGETOBJS@,$TARGETOBJS,;t t
|
||||||
s,@CC@,$CC,;t t
|
s,@CC@,$CC,;t t
|
||||||
s,@CFLAGS@,$CFLAGS,;t t
|
s,@CFLAGS@,$CFLAGS,;t t
|
||||||
|
@ -38,6 +38,21 @@ AC_DEFINE_UNQUOTED(TARGET_SYSTEM_ROOT, "$sysroot",
|
|||||||
AC_DEFINE_UNQUOTED(TARGET_SYSTEM_ROOT_RELOCATABLE, $sysroot_relocatable,
|
AC_DEFINE_UNQUOTED(TARGET_SYSTEM_ROOT_RELOCATABLE, $sysroot_relocatable,
|
||||||
[Whether the system root can be relocated])
|
[Whether the system root can be relocated])
|
||||||
|
|
||||||
|
dnl For now threads are a configure time option.
|
||||||
|
AC_ARG_ENABLE([threads],
|
||||||
|
[ --enable-threads multi-threaded linking],
|
||||||
|
[case "${enableval}" in
|
||||||
|
yes | "") threads=yes ;;
|
||||||
|
no) threads=no ;;
|
||||||
|
*) threads=yes ;;
|
||||||
|
esac],
|
||||||
|
[threads=no])
|
||||||
|
if test "$threads" = "yes"; then
|
||||||
|
AC_DEFINE(ENABLE_THREADS, 1,
|
||||||
|
[Define to do multi-threaded linking])
|
||||||
|
fi
|
||||||
|
AM_CONDITIONAL(THREADS, test "$threads" = "yes")
|
||||||
|
|
||||||
AC_ARG_ENABLE([targets],
|
AC_ARG_ENABLE([targets],
|
||||||
[ --enable-targets alternative target configurations],
|
[ --enable-targets alternative target configurations],
|
||||||
[case "${enableval}" in
|
[case "${enableval}" in
|
||||||
|
@ -22,6 +22,9 @@
|
|||||||
|
|
||||||
#include "gold.h"
|
#include "gold.h"
|
||||||
|
|
||||||
|
#include <cerrno>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
#ifdef ENABLE_THREADS
|
#ifdef ENABLE_THREADS
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#endif
|
#endif
|
||||||
@ -63,37 +66,37 @@ Lock_impl::Lock_impl()
|
|||||||
{
|
{
|
||||||
pthread_mutexattr_t attr;
|
pthread_mutexattr_t attr;
|
||||||
if (pthread_mutexattr_init(&attr) != 0)
|
if (pthread_mutexattr_init(&attr) != 0)
|
||||||
gold_fatal(_("pthead_mutextattr_init failed"), true);
|
gold_fatal(_("pthead_mutextattr_init failed: %s"), strerror(errno));
|
||||||
#ifdef PTHREAD_MUTEXT_ADAPTIVE_NP
|
#ifdef PTHREAD_MUTEXT_ADAPTIVE_NP
|
||||||
if (pthread_mutextattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP) != 0)
|
if (pthread_mutextattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP) != 0)
|
||||||
gold_fatal(_("pthread_mutextattr_settype failed"), true);
|
gold_fatal(_("pthread_mutextattr_settype failed: %s"), strerror(errno));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (pthread_mutex_init (&this->mutex_, &attr) != 0)
|
if (pthread_mutex_init (&this->mutex_, &attr) != 0)
|
||||||
gold_fatal(_("pthread_mutex_init failed"), true);
|
gold_fatal(_("pthread_mutex_init failed: %s"), strerror(errno));
|
||||||
|
|
||||||
if (pthread_mutexattr_destroy(&attr) != 0)
|
if (pthread_mutexattr_destroy(&attr) != 0)
|
||||||
gold_fatal(_("pthread_mutexattr_destroy failed"), true);
|
gold_fatal(_("pthread_mutexattr_destroy failed: %s"), strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
Lock_impl::~Lock_impl()
|
Lock_impl::~Lock_impl()
|
||||||
{
|
{
|
||||||
if (pthread_mutex_destroy(&this->mutex_) != 0)
|
if (pthread_mutex_destroy(&this->mutex_) != 0)
|
||||||
gold_fatal(_("pthread_mutex_destroy failed"), true);
|
gold_fatal(_("pthread_mutex_destroy failed: %s"), strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Lock_impl::acquire()
|
Lock_impl::acquire()
|
||||||
{
|
{
|
||||||
if (pthread_mutex_lock(&this->mutex_) != 0)
|
if (pthread_mutex_lock(&this->mutex_) != 0)
|
||||||
gold_fatal(_("pthread_mutex_lock failed"), true);
|
gold_fatal(_("pthread_mutex_lock failed: %s"), strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Lock_impl::release()
|
Lock_impl::release()
|
||||||
{
|
{
|
||||||
if (pthread_mutex_unlock(&this->mutex_) != 0)
|
if (pthread_mutex_unlock(&this->mutex_) != 0)
|
||||||
gold_fatal(_("pthread_mutex_unlock failed"), true);
|
gold_fatal(_("pthread_mutex_unlock failed: %s"), strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // !defined(ENABLE_THREADS)
|
#else // !defined(ENABLE_THREADS)
|
||||||
@ -174,27 +177,27 @@ class Condvar_impl
|
|||||||
Condvar_impl::Condvar_impl()
|
Condvar_impl::Condvar_impl()
|
||||||
{
|
{
|
||||||
if (pthread_cond_init(&this->cond_, NULL) != 0)
|
if (pthread_cond_init(&this->cond_, NULL) != 0)
|
||||||
gold_fatal(_("pthread_cond_init failed"), true);
|
gold_fatal(_("pthread_cond_init failed: %s"), strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
Condvar_impl::~Condvar_impl()
|
Condvar_impl::~Condvar_impl()
|
||||||
{
|
{
|
||||||
if (pthread_cond_destroy(&this->cond_) != 0)
|
if (pthread_cond_destroy(&this->cond_) != 0)
|
||||||
gold_fatal(_("pthread_cond_destroy failed"), true);
|
gold_fatal(_("pthread_cond_destroy failed: %s"), strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Condvar_impl::wait(Lock_impl* li)
|
Condvar_impl::wait(Lock_impl* li)
|
||||||
{
|
{
|
||||||
if (pthread_cond_wait(&this->cond_, &li->mutex_) != 0)
|
if (pthread_cond_wait(&this->cond_, &li->mutex_) != 0)
|
||||||
gold_fatal(_("pthread_cond_wait failed"), true);
|
gold_fatal(_("pthread_cond_wait failed: %s"), strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Condvar_impl::signal()
|
Condvar_impl::signal()
|
||||||
{
|
{
|
||||||
if (pthread_cond_signal(&this->cond_) != 0)
|
if (pthread_cond_signal(&this->cond_) != 0)
|
||||||
gold_fatal(_("pthread_cond_signal failed"), true);
|
gold_fatal(_("pthread_cond_signal failed: %s"), strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // !defined(ENABLE_THREADS)
|
#else // !defined(ENABLE_THREADS)
|
||||||
|
27
gold/gold.cc
27
gold/gold.cc
@ -114,6 +114,15 @@ queue_initial_tasks(const General_options& options,
|
|||||||
Workqueue* workqueue, Input_objects* input_objects,
|
Workqueue* workqueue, Input_objects* input_objects,
|
||||||
Symbol_table* symtab, Layout* layout)
|
Symbol_table* symtab, Layout* layout)
|
||||||
{
|
{
|
||||||
|
int thread_count = options.thread_count_initial();
|
||||||
|
if (thread_count == 0)
|
||||||
|
{
|
||||||
|
thread_count = cmdline.number_of_input_files();
|
||||||
|
if (thread_count == 0)
|
||||||
|
thread_count = 1;
|
||||||
|
}
|
||||||
|
workqueue->set_thread_count(thread_count);
|
||||||
|
|
||||||
if (cmdline.begin() == cmdline.end())
|
if (cmdline.begin() == cmdline.end())
|
||||||
gold_fatal(_("no input files"));
|
gold_fatal(_("no input files"));
|
||||||
|
|
||||||
@ -152,6 +161,15 @@ queue_middle_tasks(const General_options& options,
|
|||||||
Layout* layout,
|
Layout* layout,
|
||||||
Workqueue* workqueue)
|
Workqueue* workqueue)
|
||||||
{
|
{
|
||||||
|
int thread_count = options.thread_count_middle();
|
||||||
|
if (thread_count == 0)
|
||||||
|
{
|
||||||
|
thread_count = input_objects->number_of_input_objects();
|
||||||
|
if (thread_count == 0)
|
||||||
|
thread_count = 1;
|
||||||
|
}
|
||||||
|
workqueue->set_thread_count(thread_count);
|
||||||
|
|
||||||
// Now we have seen all the input files.
|
// Now we have seen all the input files.
|
||||||
const bool doing_static_link = (!input_objects->any_dynamic()
|
const bool doing_static_link = (!input_objects->any_dynamic()
|
||||||
&& !parameters->output_is_shared());
|
&& !parameters->output_is_shared());
|
||||||
@ -228,6 +246,15 @@ queue_final_tasks(const General_options& options,
|
|||||||
Workqueue* workqueue,
|
Workqueue* workqueue,
|
||||||
Output_file* of)
|
Output_file* of)
|
||||||
{
|
{
|
||||||
|
int thread_count = options.thread_count_final();
|
||||||
|
if (thread_count == 0)
|
||||||
|
{
|
||||||
|
thread_count = input_objects->number_of_input_objects();
|
||||||
|
if (thread_count == 0)
|
||||||
|
thread_count = 1;
|
||||||
|
}
|
||||||
|
workqueue->set_thread_count(thread_count);
|
||||||
|
|
||||||
// Use a blocker to block the final cleanup task.
|
// Use a blocker to block the final cleanup task.
|
||||||
Task_token* final_blocker = new Task_token();
|
Task_token* final_blocker = new Task_token();
|
||||||
|
|
||||||
|
@ -828,6 +828,11 @@ class Input_objects
|
|||||||
any_dynamic() const
|
any_dynamic() const
|
||||||
{ return !this->dynobj_list_.empty(); }
|
{ return !this->dynobj_list_.empty(); }
|
||||||
|
|
||||||
|
// Return the number of input objects.
|
||||||
|
int
|
||||||
|
number_of_input_objects() const
|
||||||
|
{ return this->relobj_list_.size() + this->dynobj_list_.size(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Input_objects(const Input_objects&);
|
Input_objects(const Input_objects&);
|
||||||
Input_objects& operator=(const Input_objects&);
|
Input_objects& operator=(const Input_objects&);
|
||||||
|
@ -357,6 +357,25 @@ options::Command_line_options::options[] =
|
|||||||
GENERAL_ARG('\0', "Ttext", N_("Set the address of the .text section"),
|
GENERAL_ARG('\0', "Ttext", N_("Set the address of the .text section"),
|
||||||
N_("-Ttext ADDRESS"), ONE_DASH,
|
N_("-Ttext ADDRESS"), ONE_DASH,
|
||||||
&General_options::set_text_segment_address),
|
&General_options::set_text_segment_address),
|
||||||
|
GENERAL_NOARG('\0', "threads", N_("Run the linker multi-threaded"),
|
||||||
|
NULL, TWO_DASHES, &General_options::set_threads),
|
||||||
|
GENERAL_NOARG('\0', "no-threads", N_("Do not run the linker multi-threaded"),
|
||||||
|
NULL, TWO_DASHES, &General_options::clear_threads),
|
||||||
|
GENERAL_ARG('\0', "thread-count", N_("Number of threads to use"),
|
||||||
|
N_("--thread-count COUNT"), TWO_DASHES,
|
||||||
|
&General_options::set_thread_count),
|
||||||
|
GENERAL_ARG('\0', "thread-count-initial",
|
||||||
|
N_("Number of threads to use in initial pass"),
|
||||||
|
N_("--thread-count-initial COUNT"), TWO_DASHES,
|
||||||
|
&General_options::set_thread_count_initial),
|
||||||
|
GENERAL_ARG('\0', "thread-count-middle",
|
||||||
|
N_("Number of threads to use in middle pass"),
|
||||||
|
N_("--thread-count-middle COUNT"), TWO_DASHES,
|
||||||
|
&General_options::set_thread_count_middle),
|
||||||
|
GENERAL_ARG('\0', "thread-count-final",
|
||||||
|
N_("Number of threads to use in final pass"),
|
||||||
|
N_("--thread-count-final COUNT"), TWO_DASHES,
|
||||||
|
&General_options::set_thread_count_final),
|
||||||
POSDEP_NOARG('\0', "whole-archive",
|
POSDEP_NOARG('\0', "whole-archive",
|
||||||
N_("Include all archive contents"),
|
N_("Include all archive contents"),
|
||||||
NULL, TWO_DASHES,
|
NULL, TWO_DASHES,
|
||||||
@ -395,7 +414,11 @@ General_options::General_options()
|
|||||||
is_static_(false),
|
is_static_(false),
|
||||||
print_stats_(false),
|
print_stats_(false),
|
||||||
sysroot_(),
|
sysroot_(),
|
||||||
text_segment_address_(-1U) // -1 indicates value not set by user
|
text_segment_address_(-1U), // -1 indicates value not set by user
|
||||||
|
threads_(false),
|
||||||
|
thread_count_initial_(0),
|
||||||
|
thread_count_middle_(0),
|
||||||
|
thread_count_final_(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,6 +189,26 @@ class General_options
|
|||||||
user_set_text_segment_address() const
|
user_set_text_segment_address() const
|
||||||
{ return this->text_segment_address_ != -1U; }
|
{ return this->text_segment_address_ != -1U; }
|
||||||
|
|
||||||
|
// --threads: Whether to use threads.
|
||||||
|
bool
|
||||||
|
threads() const
|
||||||
|
{ return this->threads_; }
|
||||||
|
|
||||||
|
// --thread-count-initial: Threads to use in initial pass.
|
||||||
|
int
|
||||||
|
thread_count_initial() const
|
||||||
|
{ return this->thread_count_initial_; }
|
||||||
|
|
||||||
|
// --thread-count-middle: Threads to use in middle pass.
|
||||||
|
int
|
||||||
|
thread_count_middle() const
|
||||||
|
{ return this->thread_count_middle_; }
|
||||||
|
|
||||||
|
// --thread-count-final: Threads to use in final pass.
|
||||||
|
int
|
||||||
|
thread_count_final() const
|
||||||
|
{ return this->thread_count_final_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Don't copy this structure.
|
// Don't copy this structure.
|
||||||
General_options(const General_options&);
|
General_options(const General_options&);
|
||||||
@ -288,6 +308,49 @@ class General_options
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
parse_thread_count(const char* arg)
|
||||||
|
{
|
||||||
|
char* endptr;
|
||||||
|
int count = strtol(arg, &endptr, 0);
|
||||||
|
if (*endptr != '\0' || count < 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, _("%s: invalid thread count: %s\n"),
|
||||||
|
program_name, arg);
|
||||||
|
::exit(1);
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
set_threads()
|
||||||
|
{ this->threads_ = true; }
|
||||||
|
|
||||||
|
void
|
||||||
|
clear_threads()
|
||||||
|
{ this->threads_ = false; }
|
||||||
|
|
||||||
|
void
|
||||||
|
set_thread_count(const char* arg)
|
||||||
|
{
|
||||||
|
int count = this->parse_thread_count(arg);
|
||||||
|
this->thread_count_initial_ = count;
|
||||||
|
this->thread_count_middle_ = count;
|
||||||
|
this->thread_count_final_ = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
set_thread_count_initial(const char* arg)
|
||||||
|
{ this->thread_count_initial_ = this->parse_thread_count(arg); }
|
||||||
|
|
||||||
|
void
|
||||||
|
set_thread_count_middle(const char* arg)
|
||||||
|
{ this->thread_count_initial_ = this->parse_thread_count(arg); }
|
||||||
|
|
||||||
|
void
|
||||||
|
set_thread_count_final(const char* arg)
|
||||||
|
{ this->thread_count_initial_ = this->parse_thread_count(arg); }
|
||||||
|
|
||||||
void
|
void
|
||||||
ignore(const char*)
|
ignore(const char*)
|
||||||
{ }
|
{ }
|
||||||
@ -311,6 +374,10 @@ class General_options
|
|||||||
bool print_stats_;
|
bool print_stats_;
|
||||||
std::string sysroot_;
|
std::string sysroot_;
|
||||||
uint64_t text_segment_address_;
|
uint64_t text_segment_address_;
|
||||||
|
bool threads_;
|
||||||
|
int thread_count_initial_;
|
||||||
|
int thread_count_middle_;
|
||||||
|
int thread_count_final_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// The current state of the position dependent options.
|
// The current state of the position dependent options.
|
||||||
@ -543,6 +610,11 @@ class Input_arguments
|
|||||||
in_group() const
|
in_group() const
|
||||||
{ return this->in_group_; }
|
{ return this->in_group_; }
|
||||||
|
|
||||||
|
// The number of entries in the list.
|
||||||
|
int
|
||||||
|
size() const
|
||||||
|
{ return this->input_argument_list_.size(); }
|
||||||
|
|
||||||
// Iterators to iterate over the list of input files.
|
// Iterators to iterate over the list of input files.
|
||||||
|
|
||||||
const_iterator
|
const_iterator
|
||||||
@ -594,6 +666,11 @@ class Command_line
|
|||||||
options() const
|
options() const
|
||||||
{ return this->options_; }
|
{ return this->options_; }
|
||||||
|
|
||||||
|
// The number of input files.
|
||||||
|
int
|
||||||
|
number_of_input_files() const
|
||||||
|
{ return this->inputs_.size(); }
|
||||||
|
|
||||||
// Iterators to iterate over the list of input files.
|
// Iterators to iterate over the list of input files.
|
||||||
|
|
||||||
const_iterator
|
const_iterator
|
||||||
|
@ -17,6 +17,10 @@ INCLUDES = -D_GNU_SOURCE \
|
|||||||
-DLOCALEDIR="\"$(datadir)/locale\"" \
|
-DLOCALEDIR="\"$(datadir)/locale\"" \
|
||||||
@INCINTL@
|
@INCINTL@
|
||||||
|
|
||||||
|
if THREADS
|
||||||
|
THREADSLIB = -lpthread
|
||||||
|
endif
|
||||||
|
|
||||||
TESTS = object_unittest
|
TESTS = object_unittest
|
||||||
check_SCRIPTS =
|
check_SCRIPTS =
|
||||||
|
|
||||||
@ -95,7 +99,8 @@ libgoldtest_a_SOURCES = test.cc testmain.cc testfile.cc
|
|||||||
|
|
||||||
DEPENDENCIES = \
|
DEPENDENCIES = \
|
||||||
libgoldtest.a ../libgold.a ../../libiberty/libiberty.a $(LIBINTL_DEP)
|
libgoldtest.a ../libgold.a ../../libiberty/libiberty.a $(LIBINTL_DEP)
|
||||||
LDADD = libgoldtest.a ../libgold.a ../../libiberty/libiberty.a $(LIBINTL)
|
LDADD = libgoldtest.a ../libgold.a ../../libiberty/libiberty.a $(LIBINTL) \
|
||||||
|
$(THREADSLIB)
|
||||||
|
|
||||||
check_PROGRAMS = object_unittest $(NATIVE_PROGS)
|
check_PROGRAMS = object_unittest $(NATIVE_PROGS)
|
||||||
|
|
||||||
|
@ -63,40 +63,49 @@ target_triplet = @target@
|
|||||||
|
|
||||||
check_PROGRAMS = object_unittest$(EXEEXT) $(am__EXEEXT_5)
|
check_PROGRAMS = object_unittest$(EXEEXT) $(am__EXEEXT_5)
|
||||||
@GCC_FALSE@constructor_test_DEPENDENCIES = libgoldtest.a ../libgold.a \
|
@GCC_FALSE@constructor_test_DEPENDENCIES = libgoldtest.a ../libgold.a \
|
||||||
@GCC_FALSE@ ../../libiberty/libiberty.a $(am__DEPENDENCIES_1)
|
@GCC_FALSE@ ../../libiberty/libiberty.a $(am__DEPENDENCIES_1) \
|
||||||
|
@GCC_FALSE@ $(am__DEPENDENCIES_1)
|
||||||
@NATIVE_LINKER_FALSE@constructor_test_DEPENDENCIES = libgoldtest.a \
|
@NATIVE_LINKER_FALSE@constructor_test_DEPENDENCIES = libgoldtest.a \
|
||||||
@NATIVE_LINKER_FALSE@ ../libgold.a ../../libiberty/libiberty.a \
|
@NATIVE_LINKER_FALSE@ ../libgold.a ../../libiberty/libiberty.a \
|
||||||
|
@NATIVE_LINKER_FALSE@ $(am__DEPENDENCIES_1) \
|
||||||
@NATIVE_LINKER_FALSE@ $(am__DEPENDENCIES_1)
|
@NATIVE_LINKER_FALSE@ $(am__DEPENDENCIES_1)
|
||||||
@GCC_FALSE@constructor_static_test_DEPENDENCIES = libgoldtest.a \
|
@GCC_FALSE@constructor_static_test_DEPENDENCIES = libgoldtest.a \
|
||||||
@GCC_FALSE@ ../libgold.a ../../libiberty/libiberty.a \
|
@GCC_FALSE@ ../libgold.a ../../libiberty/libiberty.a \
|
||||||
@GCC_FALSE@ $(am__DEPENDENCIES_1)
|
@GCC_FALSE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
|
||||||
@NATIVE_LINKER_FALSE@constructor_static_test_DEPENDENCIES = \
|
@NATIVE_LINKER_FALSE@constructor_static_test_DEPENDENCIES = \
|
||||||
@NATIVE_LINKER_FALSE@ libgoldtest.a ../libgold.a \
|
@NATIVE_LINKER_FALSE@ libgoldtest.a ../libgold.a \
|
||||||
@NATIVE_LINKER_FALSE@ ../../libiberty/libiberty.a \
|
@NATIVE_LINKER_FALSE@ ../../libiberty/libiberty.a \
|
||||||
|
@NATIVE_LINKER_FALSE@ $(am__DEPENDENCIES_1) \
|
||||||
@NATIVE_LINKER_FALSE@ $(am__DEPENDENCIES_1)
|
@NATIVE_LINKER_FALSE@ $(am__DEPENDENCIES_1)
|
||||||
@GCC_FALSE@two_file_test_DEPENDENCIES = libgoldtest.a ../libgold.a \
|
@GCC_FALSE@two_file_test_DEPENDENCIES = libgoldtest.a ../libgold.a \
|
||||||
@GCC_FALSE@ ../../libiberty/libiberty.a $(am__DEPENDENCIES_1)
|
@GCC_FALSE@ ../../libiberty/libiberty.a $(am__DEPENDENCIES_1) \
|
||||||
|
@GCC_FALSE@ $(am__DEPENDENCIES_1)
|
||||||
@NATIVE_LINKER_FALSE@two_file_test_DEPENDENCIES = libgoldtest.a \
|
@NATIVE_LINKER_FALSE@two_file_test_DEPENDENCIES = libgoldtest.a \
|
||||||
@NATIVE_LINKER_FALSE@ ../libgold.a ../../libiberty/libiberty.a \
|
@NATIVE_LINKER_FALSE@ ../libgold.a ../../libiberty/libiberty.a \
|
||||||
|
@NATIVE_LINKER_FALSE@ $(am__DEPENDENCIES_1) \
|
||||||
@NATIVE_LINKER_FALSE@ $(am__DEPENDENCIES_1)
|
@NATIVE_LINKER_FALSE@ $(am__DEPENDENCIES_1)
|
||||||
@GCC_FALSE@two_file_static_test_DEPENDENCIES = libgoldtest.a \
|
@GCC_FALSE@two_file_static_test_DEPENDENCIES = libgoldtest.a \
|
||||||
@GCC_FALSE@ ../libgold.a ../../libiberty/libiberty.a \
|
@GCC_FALSE@ ../libgold.a ../../libiberty/libiberty.a \
|
||||||
@GCC_FALSE@ $(am__DEPENDENCIES_1)
|
@GCC_FALSE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
|
||||||
@NATIVE_LINKER_FALSE@two_file_static_test_DEPENDENCIES = \
|
@NATIVE_LINKER_FALSE@two_file_static_test_DEPENDENCIES = \
|
||||||
@NATIVE_LINKER_FALSE@ libgoldtest.a ../libgold.a \
|
@NATIVE_LINKER_FALSE@ libgoldtest.a ../libgold.a \
|
||||||
@NATIVE_LINKER_FALSE@ ../../libiberty/libiberty.a \
|
@NATIVE_LINKER_FALSE@ ../../libiberty/libiberty.a \
|
||||||
|
@NATIVE_LINKER_FALSE@ $(am__DEPENDENCIES_1) \
|
||||||
@NATIVE_LINKER_FALSE@ $(am__DEPENDENCIES_1)
|
@NATIVE_LINKER_FALSE@ $(am__DEPENDENCIES_1)
|
||||||
@GCC_FALSE@exception_test_DEPENDENCIES = libgoldtest.a ../libgold.a \
|
@GCC_FALSE@exception_test_DEPENDENCIES = libgoldtest.a ../libgold.a \
|
||||||
@GCC_FALSE@ ../../libiberty/libiberty.a $(am__DEPENDENCIES_1)
|
@GCC_FALSE@ ../../libiberty/libiberty.a $(am__DEPENDENCIES_1) \
|
||||||
|
@GCC_FALSE@ $(am__DEPENDENCIES_1)
|
||||||
@NATIVE_LINKER_FALSE@exception_test_DEPENDENCIES = libgoldtest.a \
|
@NATIVE_LINKER_FALSE@exception_test_DEPENDENCIES = libgoldtest.a \
|
||||||
@NATIVE_LINKER_FALSE@ ../libgold.a ../../libiberty/libiberty.a \
|
@NATIVE_LINKER_FALSE@ ../libgold.a ../../libiberty/libiberty.a \
|
||||||
|
@NATIVE_LINKER_FALSE@ $(am__DEPENDENCIES_1) \
|
||||||
@NATIVE_LINKER_FALSE@ $(am__DEPENDENCIES_1)
|
@NATIVE_LINKER_FALSE@ $(am__DEPENDENCIES_1)
|
||||||
@GCC_FALSE@exception_static_test_DEPENDENCIES = libgoldtest.a \
|
@GCC_FALSE@exception_static_test_DEPENDENCIES = libgoldtest.a \
|
||||||
@GCC_FALSE@ ../libgold.a ../../libiberty/libiberty.a \
|
@GCC_FALSE@ ../libgold.a ../../libiberty/libiberty.a \
|
||||||
@GCC_FALSE@ $(am__DEPENDENCIES_1)
|
@GCC_FALSE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
|
||||||
@NATIVE_LINKER_FALSE@exception_static_test_DEPENDENCIES = \
|
@NATIVE_LINKER_FALSE@exception_static_test_DEPENDENCIES = \
|
||||||
@NATIVE_LINKER_FALSE@ libgoldtest.a ../libgold.a \
|
@NATIVE_LINKER_FALSE@ libgoldtest.a ../libgold.a \
|
||||||
@NATIVE_LINKER_FALSE@ ../../libiberty/libiberty.a \
|
@NATIVE_LINKER_FALSE@ ../../libiberty/libiberty.a \
|
||||||
|
@NATIVE_LINKER_FALSE@ $(am__DEPENDENCIES_1) \
|
||||||
@NATIVE_LINKER_FALSE@ $(am__DEPENDENCIES_1)
|
@NATIVE_LINKER_FALSE@ $(am__DEPENDENCIES_1)
|
||||||
@GCC_FALSE@tls_test_DEPENDENCIES =
|
@GCC_FALSE@tls_test_DEPENDENCIES =
|
||||||
@NATIVE_LINKER_FALSE@tls_test_DEPENDENCIES =
|
@NATIVE_LINKER_FALSE@tls_test_DEPENDENCIES =
|
||||||
@ -221,7 +230,8 @@ am_object_unittest_OBJECTS = object_unittest.$(OBJEXT)
|
|||||||
object_unittest_OBJECTS = $(am_object_unittest_OBJECTS)
|
object_unittest_OBJECTS = $(am_object_unittest_OBJECTS)
|
||||||
object_unittest_LDADD = $(LDADD)
|
object_unittest_LDADD = $(LDADD)
|
||||||
object_unittest_DEPENDENCIES = libgoldtest.a ../libgold.a \
|
object_unittest_DEPENDENCIES = libgoldtest.a ../libgold.a \
|
||||||
../../libiberty/libiberty.a $(am__DEPENDENCIES_1)
|
../../libiberty/libiberty.a $(am__DEPENDENCIES_1) \
|
||||||
|
$(am__DEPENDENCIES_1)
|
||||||
am__tls_pic_test_SOURCES_DIST = tls_test_main.cc
|
am__tls_pic_test_SOURCES_DIST = tls_test_main.cc
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@am_tls_pic_test_OBJECTS = tls_test_main.$(OBJEXT)
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@am_tls_pic_test_OBJECTS = tls_test_main.$(OBJEXT)
|
||||||
tls_pic_test_OBJECTS = $(am_tls_pic_test_OBJECTS)
|
tls_pic_test_OBJECTS = $(am_tls_pic_test_OBJECTS)
|
||||||
@ -330,7 +340,8 @@ am__weak_test_SOURCES_DIST = weak_test.cc
|
|||||||
weak_test_OBJECTS = $(am_weak_test_OBJECTS)
|
weak_test_OBJECTS = $(am_weak_test_OBJECTS)
|
||||||
weak_test_LDADD = $(LDADD)
|
weak_test_LDADD = $(LDADD)
|
||||||
weak_test_DEPENDENCIES = libgoldtest.a ../libgold.a \
|
weak_test_DEPENDENCIES = libgoldtest.a ../libgold.a \
|
||||||
../../libiberty/libiberty.a $(am__DEPENDENCIES_1)
|
../../libiberty/libiberty.a $(am__DEPENDENCIES_1) \
|
||||||
|
$(am__DEPENDENCIES_1)
|
||||||
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
|
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
|
||||||
depcomp = $(SHELL) $(top_srcdir)/../depcomp
|
depcomp = $(SHELL) $(top_srcdir)/../depcomp
|
||||||
am__depfiles_maybe = depfiles
|
am__depfiles_maybe = depfiles
|
||||||
@ -473,6 +484,8 @@ STATIC_TLS_FALSE = @STATIC_TLS_FALSE@
|
|||||||
STATIC_TLS_TRUE = @STATIC_TLS_TRUE@
|
STATIC_TLS_TRUE = @STATIC_TLS_TRUE@
|
||||||
STRIP = @STRIP@
|
STRIP = @STRIP@
|
||||||
TARGETOBJS = @TARGETOBJS@
|
TARGETOBJS = @TARGETOBJS@
|
||||||
|
THREADS_FALSE = @THREADS_FALSE@
|
||||||
|
THREADS_TRUE = @THREADS_TRUE@
|
||||||
TLS_FALSE = @TLS_FALSE@
|
TLS_FALSE = @TLS_FALSE@
|
||||||
TLS_TRUE = @TLS_TRUE@
|
TLS_TRUE = @TLS_TRUE@
|
||||||
USE_NLS = @USE_NLS@
|
USE_NLS = @USE_NLS@
|
||||||
@ -538,6 +551,7 @@ INCLUDES = -D_GNU_SOURCE \
|
|||||||
-DLOCALEDIR="\"$(datadir)/locale\"" \
|
-DLOCALEDIR="\"$(datadir)/locale\"" \
|
||||||
@INCINTL@
|
@INCINTL@
|
||||||
|
|
||||||
|
@THREADS_TRUE@THREADSLIB = -lpthread
|
||||||
TESTS = object_unittest $(NATIVE_TESTING)
|
TESTS = object_unittest $(NATIVE_TESTING)
|
||||||
check_SCRIPTS =
|
check_SCRIPTS =
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@NATIVE_PROGS = constructor_test \
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@NATIVE_PROGS = constructor_test \
|
||||||
@ -572,7 +586,9 @@ libgoldtest_a_SOURCES = test.cc testmain.cc testfile.cc
|
|||||||
DEPENDENCIES = \
|
DEPENDENCIES = \
|
||||||
libgoldtest.a ../libgold.a ../../libiberty/libiberty.a $(LIBINTL_DEP)
|
libgoldtest.a ../libgold.a ../../libiberty/libiberty.a $(LIBINTL_DEP)
|
||||||
|
|
||||||
LDADD = libgoldtest.a ../libgold.a ../../libiberty/libiberty.a $(LIBINTL)
|
LDADD = libgoldtest.a ../libgold.a ../../libiberty/libiberty.a $(LIBINTL) \
|
||||||
|
$(THREADSLIB)
|
||||||
|
|
||||||
object_unittest_SOURCES = object_unittest.cc
|
object_unittest_SOURCES = object_unittest.cc
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@constructor_test_SOURCES = constructor_test.cc
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@constructor_test_SOURCES = constructor_test.cc
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@constructor_test_DEPENDENCIES = gcctestdir/ld
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@constructor_test_DEPENDENCIES = gcctestdir/ld
|
||||||
|
@ -22,6 +22,10 @@
|
|||||||
|
|
||||||
#include "gold.h"
|
#include "gold.h"
|
||||||
|
|
||||||
|
#ifdef ENABLE_THREADS
|
||||||
|
#include <pthread.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "workqueue.h"
|
#include "workqueue.h"
|
||||||
|
|
||||||
namespace gold
|
namespace gold
|
||||||
@ -153,7 +157,13 @@ class Workqueue_runner
|
|||||||
{ }
|
{ }
|
||||||
|
|
||||||
// Run a task. This is always called in the main thread.
|
// Run a task. This is always called in the main thread.
|
||||||
virtual void run(Task*, Task_locker*) = 0;
|
virtual void
|
||||||
|
run(Task*, Task_locker*) = 0;
|
||||||
|
|
||||||
|
// Set the number of threads to use. This is ignored when not using
|
||||||
|
// threads.
|
||||||
|
virtual void
|
||||||
|
set_thread_count(int) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// This is called by an implementation when a task is completed.
|
// This is called by an implementation when a task is completed.
|
||||||
@ -178,7 +188,11 @@ class Workqueue_runner_single : public Workqueue_runner
|
|||||||
~Workqueue_runner_single()
|
~Workqueue_runner_single()
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
void run(Task*, Task_locker*);
|
void
|
||||||
|
run(Task*, Task_locker*);
|
||||||
|
|
||||||
|
void
|
||||||
|
set_thread_count(int);
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -188,9 +202,15 @@ Workqueue_runner_single::run(Task* t, Task_locker* tl)
|
|||||||
this->completed(t, tl);
|
this->completed(t, tl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Workqueue_runner_single::set_thread_count(int thread_count)
|
||||||
|
{
|
||||||
|
gold_assert(thread_count > 0);
|
||||||
|
}
|
||||||
|
|
||||||
// Workqueue methods.
|
// Workqueue methods.
|
||||||
|
|
||||||
Workqueue::Workqueue(const General_options&)
|
Workqueue::Workqueue(const General_options& options)
|
||||||
: tasks_lock_(),
|
: tasks_lock_(),
|
||||||
tasks_(),
|
tasks_(),
|
||||||
completed_lock_(),
|
completed_lock_(),
|
||||||
@ -199,9 +219,14 @@ Workqueue::Workqueue(const General_options&)
|
|||||||
completed_condvar_(this->completed_lock_),
|
completed_condvar_(this->completed_lock_),
|
||||||
cleared_blockers_(0)
|
cleared_blockers_(0)
|
||||||
{
|
{
|
||||||
// At some point we will select the specific implementation of
|
bool threads = options.threads();
|
||||||
// Workqueue_runner to use based on the command line options.
|
#ifndef ENABLE_THREADS
|
||||||
|
threads = false;
|
||||||
|
#endif
|
||||||
|
if (!threads)
|
||||||
this->runner_ = new Workqueue_runner_single(this);
|
this->runner_ = new Workqueue_runner_single(this);
|
||||||
|
else
|
||||||
|
gold_unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
Workqueue::~Workqueue()
|
Workqueue::~Workqueue()
|
||||||
@ -421,4 +446,13 @@ Workqueue::cleared_blocker()
|
|||||||
++this->cleared_blockers_;
|
++this->cleared_blockers_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the number of threads to use for the workqueue, if we are using
|
||||||
|
// threads.
|
||||||
|
|
||||||
|
void
|
||||||
|
Workqueue::set_thread_count(int threads)
|
||||||
|
{
|
||||||
|
this->runner_->set_thread_count(threads);
|
||||||
|
}
|
||||||
|
|
||||||
} // End namespace gold.
|
} // End namespace gold.
|
||||||
|
@ -47,7 +47,7 @@ class Task;
|
|||||||
class Workqueue;
|
class Workqueue;
|
||||||
|
|
||||||
// Some tasks require access to shared data structures, such as the
|
// Some tasks require access to shared data structures, such as the
|
||||||
// symbol table. Some tasks must be executed in a particular error,
|
// symbol table. Some tasks must be executed in a particular order,
|
||||||
// such as reading input file symbol tables--if we see foo.o -llib, we
|
// such as reading input file symbol tables--if we see foo.o -llib, we
|
||||||
// have to read the symbols for foo.o before we read the ones for
|
// have to read the symbols for foo.o before we read the ones for
|
||||||
// -llib. To implement this safely and efficiently, we use tokens.
|
// -llib. To implement this safely and efficiently, we use tokens.
|
||||||
@ -391,6 +391,10 @@ class Workqueue
|
|||||||
void
|
void
|
||||||
cleared_blocker();
|
cleared_blocker();
|
||||||
|
|
||||||
|
// Set the thread count.
|
||||||
|
void
|
||||||
|
set_thread_count(int);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// This class can not be copied.
|
// This class can not be copied.
|
||||||
Workqueue(const Workqueue&);
|
Workqueue(const Workqueue&);
|
||||||
|
Reference in New Issue
Block a user