Hi.
I have noticed that Cygwin's spinlock goes into heavy sleeping code
for each spin. It seems it would be a good idea to actually try to
spin a bit first. There is this 'pause' instruction which let's the
CPU make such busy loops be less busy. Here is a patch to do this.
--
VH
* signal.cc (sigwait): Fix return value to reflect errno in case of
error according to POSIX. Never return EINTR.
* thread.cc (pthread_kill): Return errno if sig_send failed.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
* thread.cc (pthread_getattr_np): Fix memory leak, remove usage of
malloc for small local buffer.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
* miscfuncs.cc (struct pthread_wrapper_arg): Add member guardsize.
(pthread_wrapper): Set thread stack guarantee according to guardsize.
Tweak assembler code so that $rax/$eax is not required by GCC to
prepare the wrapper_arg value.
(CygwinCreateThread): Fix deadzone handling. Drop setting a "POSIX"
guardpage (aka page w/ PAGE_NOACCESS). Always use Windows guard
pages instead. On post-XP systems (providing SetThreadStackGuarantee)
always set up stack Windows like with reserved/commited areas and
movable guard pages. Only on XP set up stack fully commited if the
guardpage size is not the default system guardpage size.
Fill out pthread_wrapper_arg::guardsize. Improve comments.
* resource.cc: Implement RSTACK_LIMIT Linux-like.
(DEFAULT_STACKSIZE): New macro.
(DEFAULT_STACKGUARD): Ditto.
(rlimit_stack_guard): New muto.
(rlimit_stack): New global variable holding current RSTACK_LIMIT values.
(__set_rlimit_stack): Set rlimit_stack under lock.
(__get_rlimit_stack): Initialize rlimit_stack from executable header
and return rlimit_stack values under lock.
(get_rlimit_stack): Filtering function to return useful default
stacksize from rlimit_stack.rlim_cur value.
(getrlimit): Call __get_rlimit_stack in RLIMIT_STACK case.
(setrlimit): Call __set_rlimit_stack in RLIMIT_STACK case.
* thread.cc (pthread::create): Fetch default stacksize calling
get_rlimit_stack.
(pthread_attr::pthread_attr): Fetch default guardsize calling
wincap.def_guard_page_size.
(pthread_attr_getstacksize): Fetch default stacksize calling
get_rlimit_stack.
* thread.h (PTHREAD_DEFAULT_STACKSIZE): Remove.
(PTHREAD_DEFAULT_GUARDSIZE): Remove.
(get_rlimit_stack): Declare.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
to explain the meaning of the possible values.
* cygwait.cc (is_cw_sig_restart): Define.
(is_cw_sig_handle): Check for cw_sig_restart as well.
(cygwait): Restart always if cw_sig_restart is set.
* thread.cc (pthread::join): Call cygwait with cw_sig_restart flag
to avoid having to handle signals at all.
having a new type threadlist_t *. Convert commented out code into an
#if 0. Create thread mutex. Explain why.
(init_cygheap::remove_tls): Drop timeout value. Always wait infinitely
for tls_sentry. Return mutex HANDLE of just deleted threadlist entry.
(init_cygheap::find_tls): New implementation taking tls pointer as
search parameter. Return threadlist_t *.
(init_cygheap::find_tls): Return threadlist_t *. Define ix as auto
variable. Drop exception handling since crash must be made impossible
due to correct synchronization. Return with locked mutex.
* cygheap.h (struct threadlist_t): Define.
(struct init_cygheap): Convert threadlist to threadlist_t type.
(init_cygheap::remove_tls): Align declaration to above change.
(init_cygheap::find_tls): Ditto.
(init_cygheap::unlock_tls): Define.
* cygtls.cc (_cygtls::remove): Unlock and close mutex when finishing.
* exceptions.cc (sigpacket::process): Lock _cygtls area of thread before
accessing it.
* fhandler_termios.cc (fhandler_termios::bg_check): Ditto.
* sigproc.cc (sig_send): Ditto.
* thread.cc (pthread::exit): Ditto. Add comment.
(pthread::cancel): Ditto.
* cygtls.cc (well_known_dlls): Rephrase comment.
(bloda_detect): New function.
(_cygtls::call2): Call init_thread and bloda_detect for non-pthread
threads only.
(_cygtls::remove): Move remove_tls and remove_wq calls up to run first.
* miscfuncs.cc (struct pthread_wrapper_arg): Rename from struct
thread_wrapper_arg.
(pthread_wrapper): Rename from thread_wrapper and drop "static". Fix
comment. Drop call to _cygtls::remove. Call api_fatal rather than
ExitThread. Explain why.
* miscfuncs.h (pthread_wrapper): Declare pthread_wrapper.
* thread.cc (pthread::exit): Add a FIXME comment. Call _cygtls::remove
before calling ExitThread.
handler.
* cygtls.cc (_cygtls::remove): Accommodate the fact that pathbufs
has been moved from _local_storage to _cygtls.
* cygtls.h (class tls_pathbuf): Add comment to hint to gendef usage
of counters. Change type of counters to uint32_t for clarity.
Remove _cygtls as friend class.
(struct _local_storage): Move pathbufs from here...
(struct _cygtls): ...to here, allowing to access it from _sigbe.
(class san): Only define on 32 bit. Remove errno, _c_cnt and _w_cnt
members.
(san::setup): Drop parameter. Don't initialize removed members.
(san::leave): Don't set removed members.
(class myfault): Only define on 32 bit.
(myfault::faulted): Only keep implementation not taking any parameter.
Drop argument in call to sebastian.setup.
(__try/__leave/__except/__endtry): Implement to support real SEH. For
now stick to SJLJ on 32 bit.
* dcrt0.cc (dll_crt0_0): Drop 64 bit call to
exception::install_myfault_handler.
* exception.h (exception_handler): Define with EXCEPTION_DISPOSITION
as return type.
(PDISPATCHER_CONTEXT): Define as void * on 32 bit. Define as pointer
to _DISPATCHER_CONTEXT on 64 bit.
(class exception): Define separately for 32 and 64 bit.
(exception::myfault): Add handler for myfault SEH handling on 64 bit.
(exception::exception): Fix mangled method name to account for change
in type of last parameter.
(exception::install_myfault_handler): Remove.
* exceptions.cc (exception::myfault_handle): Remove.
(exception::myfault): New SEH handler for 64 bit.
* gendef (_sigbe): Set tls_pathbuf counters to 0 explicitely when
returning to the caller.
* ntdll.h: Move a comment to a better place.
(struct _SCOPE_TABLE): Define on 64 bit.
* thread.cc (verifyable_object_isvalid): Remove gcc 4.7 workaround.
* tls_pbuf.cc (tls_pbuf): Fix to accommodate new place of pathbufs.
(tls_pathbuf::destroy): Change type of loop variables to uint32_t.
* tls_pbuf.h (class tmp_pathbuf): Change type of buffer counters to
uint32_t. Accommodate new place of pathbufs.
* tlsoffsets.h: Regenerate.
* tlsoffsets64.h: Regenerate.
Add comment.
(pthread_attr_setstack): Store upper bound address in stackaddr.
Explain why.
(pthread_attr_getstack): Handle stackaddr as upper bound address.
Add comment.
(pthread_attr_setstackaddr): Add comment.
(pthread_attr_getstackaddr): Add comment.
(pthread_attr_getstacksize): Return default stacksize if stacksize has
not been set by the application, just as on Linux. Add comment.
(pthread_getattr_np): Store upper bound address in stackaddr. Explain
why.
* include/pthread.h: Remove outdated comment.
(pthread_attr_getstackaddr): Mark as deprecated, as on Linux.
(pthread_attr_setstackaddr): Ditto.
to PTHREAD_MUTEX_NORMAL.
(pthread_mutex::unlock): Return EPERM if the mutex has no owner and
the mutex type is PTHREAD_MUTEX_ERRORCHECK, as on Linux.
(pthread_mutexattr::pthread_mutexattr): Ditto.
(pthread_mutex_unlock): Do not fail if mutex is a normal mutex
initializer.
* include/pthread.h (PTHREAD_MUTEX_INITIALIZER): Redefine as
PTHREAD_NORMAL_MUTEX_INITIALIZER_NP.
if attr.stacksize is 0.
(pthread_attr::pthread_attr): Initialize stacksize to 0 to align more
closely to Linux.
(pthread_attr_getstack): Fix incorrect stackaddr computation. Return
stackaddr just like pthread_attr_getstackaddr. Remove slightly off
comment.
(pthread_attr_getstackaddr): Remove slightly off comment.
(pthread_getattr_np): Return stackaddr and stacksize based on the full
allocated stackarea.
(enum _SEMAPHORE_INFORMATION_CLASS): Define.
(NtQuerySemaphore): Declare.
* thread.h (class semaphore): Add member startvalue.
(semaphore::fixup_before_fork): New inline method.
(semaphore::_fixup_before_fork): Declare.
* thread.cc (MTinterface::fixup_before_fork): Additionally call
semaphore::fixup_before_fork.
(semaphore::semaphore): Set currentvalue to -1. Set startvalue to
incoming initializer value.
(semaphore::_getvalue): Just query semaphore using NtQuerySemaphore
rather then using WFSO/Release.
(semaphore::_post): Drop setting currentvalue. It's not thread-safe.
(semaphore::_trywait): Ditto.
(semaphore::_timedwait): Ditto.
(semaphore::_wait): Ditto.
(semaphore::_fixup_before_fork): New method, setting currentvalue from
actual windows semaphore right before fork.
(semaphore::_fixup_after_fork): Drop kludge from 2013-07-10. Drop
FIXME comment.
* thread.cc (semaphore::_fixup_after_fork): Report on potential problem
parameter. Make sure that currentvalue is never zero.
(semaphore::init): Make cosmetic change.
warnings between regparm definitions and declarations.
* smallprint.cc (__small_vswprintf): Conditionalize declaration and
setting of l_opt for only x86_64.
* spawn.cc (child_info_spawn::worker): Remove unused 'pid' variable.
* thread.cc (verifyable_object_isvalid): Temporarily define as
non-inline with gcc 4.7+, regardless of target.
* dcrt0.cc (parent_sigmask): Delete.
(dll_crt0_1): Use spawn_info->moreinfo->sigmask rather than saved parent signal
mask.
* thread.cc (pthread::thread_init_wrapper): Add comment stressing the
importance of maintaining ordering of statements.
* cygheap.cc (init_cygheap::find_tls): Rename threadlist_ix -> ix. Only take
one pass through thread list, looking for eligible threads to signal. Set a
new param indicating that function has found a sigwait* mask.
* cygheap.h (init_cygheap::find_tls): Reflect new parameter.
* dcrt0.cc (parent_sigmask): New variable.
(child_info_spawn::handle_spawn): Save parent's signal mask here.
(dll_crt0_1): Restore parent's signal mask to tls sigmask as appropriate. Call
sig_dispatch_pending to flush signal queue when we can finally do something
with signals.
* exceptions.cc (sigpacket::process): Avoid attempting to handle signals if we
haven't finished initializing. Rely on the fact that find_tls will do mask
checking and don't do it again. Delete ill-named 'dummy' variable.
* sigproc.cc (cygheap_exec_info::alloc): Save calling thread's signal mask in
new sigmask field.
(wait_sig): Try to debug when WFSO fails and DEBUGGING is defined.
* thread.cc (pthread::set_tls_self_pointer): Make this a true automatic method
rather than inexplicably relying on a thread parameter.
(pthread::thread_init_wrapper): Accommodate set_tls_self_pointer change to
non-static. Initialize sigmask before setting tid or suffer signal races.
* ehread.h (pthread::set_tls_self_pointer): Make non-static, delete parameter.
that we're looking for the current thread.
(pthread_rwlock::tryrdlock): Eliminate self variable. Accommodate change in
lookup_reader().
(pthread_rwlock::unlock): Ditto.
(pthread_rwlock::rdlock): Ditto. Move add_reader call after writer tests to
more closely mimic old behavior.
(pthread_rwlock::wrlock): Accommodate change in lookup_reader().
* thread.h ((pthread_rwlock::lookup_reader): Eliminate argument.
pointer to allocated RWLOCK_READER structure.
(pthread_rwlock::rdlock): Reorganize to reflect new add_reader functionality.
(pthread_rwlock::tryrdlock): Ditto. Remove unneeded call to lookup_reader().
* thread.h (pthread_rwlock::RWLOCK_READER::RWLOCK_READER): New constructor.
(pthread_rwlock::add_reader): Reflect new functionality.
(select_info): Ditto.
(select_record::dump_select_record): Declare new debugging-only function.
(select_info): Zero all fields.
(select_pipe_info): Ditto.
(select_socket_info): Ditto.
(select_serial_info): Ditto.
(select_mailslot_info): Ditto.
* select.cc (select_record::dump_select_record): Define new debugging-only
function.
(select_stuff::test_and_set): Call dump_select_record when debugging.
* thread.cc (pthread_mutex::unlock): Revert setting of tid to NULL since, in
this context, it is a number, not a pointer.
(pthread_spinlock::unlock): Ditto.
* _cygtls.cc (_cygtls::call2): Use new exit_thread function in place of
ExitThread.
* miscfuncs.cc (thread_wrapper): Ditto.
* thread.cc (pthread::exit): Ditto.
(pthread_mutex::unlock): Set tid to NULL rather than 0.
(pthread_spinlock::unlock): Ditto.
* pinfo.cc (commune_process): Actually call lock_process constructor.
* sigproc.cc (exit_thread): New function.
(wait_sig): Handle __SIGTHREADEXIT case. Don't just block rather than
returning from this function.
* sigproc.h (__SIGTHREADEXIT): New enum.
(exit_thread): Declare.
* sync.cc (muto::release): Accept a tls command-line argument.
* sync.h (muto::release): Accept a tls command-line parameter. Default to
&_my_tls.
* cygserver_ipc.h (ipc_set_proc_info): Use _cygtls::ipc_set_proc_info to set
per-thread signal arrived value.
* cygthread.cc (cygthread::detach): Use per-thread signal_arrived via
set_thread_waiting.
* fork.cc (_cygtls::fixup_after_fork): Clear signal_arrived.
(_cygtls::remove): Close any signal_arrived handle when thread exists.
(_cygtls::find_tls): Remove unneeded function.
* cygtls.h: Update copyright.
(class _cygtls): Reorganize to help avoid rebuilding newlib when structure
changes.
(_cygtls::event): Delete.
(_cygtls::threadkill): Ditto.
(_cygtls::signal_waiting): Declare new bool.
(_cygtls::find_tls): Delete declaration.
(_cygtls::set_threadkill): Ditto.
(_cygtls::reset_threadkill): Ditto.
(_cygtls::set_signal_arrived): Declare new function.
(class set_thread_waiting): Declare new class.
* cygwait.cc (cw_nowait_storage): Define.
(cygwait): Set per-thread signal_arrived via set_thread_waiting. Don't
special-case _main_tls.
* cygwait.h (cw_nowait): Define.
(cw_infinite): Ditto.
(cygwait): Redefine pathological wait-only case.
* dcrt0.cc (dll_crt0_0): Remove call to now-defunct events_init().
(dll_crt0_1): Remove call to now-defunct create_signal_arrived().
* exceptions.cc: Reflect set_signal_mask() argument reordering throughout.
Remove signal mask synchronization throughout.
(events_init): Delete definition.
(mask_sync): Delete now-unneeded mask synchronization.
(set_signal_mask): Reverse order of arguments to "standard" to, from layout.
Rename "newmask" argument to "setmask". Remove debugging.
(sig_handle_tty_stop): Use cancelable_wait rather than WFMO.
(_cygtls::interrupt_setup): Don't treat "threadkill" events specially.
Conditionally set signal_arrived depending on whether the thread has created it
or not.
(sigpacket::process): Reorganize to reflect thread-specific sending of signals
which is more in line with the way it was actually supposed to work.
* fhandler_socket.cc (get_inet_addr): Use cancelable_wait rather than
IsEventSignalled to avoid potential race.
(fhandler_socket::wait_for_events): Set signal_arrived event using
set_thread_waiting().
(fhandler_socket::close): Use cygwait for the case of just waiting 10 ms for a
signal.
* fhandler_tape.cc (fhandler_dev_tape::_lock): Use cancelable_wait rather than
WFMO. Redo switch/case tests accordingly.
* fhandler_termios.cc (fhandler_termios::bg_check): Use cygwait for case of
just waiting 0 ms for a potential signal.
* fhandler_tty.cc (fhandler_pty_master::process_slave_output): Use
cancelable_wait rather than WFSO.
* fhandler_windows.cc (fhandler_windows::read): Set per-thread signal_arrived
via set_thread_waiting().
* flock.cc (lf_setlock): Ditto.
* select.cc (pselect): Ditto. Set per-thread signal_arrived using
set_thread_waiting().
* gendef: Don't special case handling of _cygtls::sig for threads.
* gentls_offsets: Use #pragma once in tlsoffsets.h.
* ntdll.h: Use #pragma once.
* poll.cc: Reflect set_signal_mask() argument reordering.
* posix_ipc.cc (ipc_mutex_lock): Use cancelable_wait rather than WFMO.
(ipc_cond_timedwait): Set perl-thread signal arrived using
set_thread_waiting().
* security.h: Use #pragma once.
* signal.cc (abort): Reflect set_signal_mask() argument reordering.
(clock_nanosleep): Ditto. Change call to cancelable_wait to properly specify
handling of cancel and interrupt.
(sigwaitinfo): Remove handling of per-thread event in favor of per-thread
signal_arrived. Use cancelable_wait rather than WFSO.
* sigproc.cc (signal_arrived): Delete definition.
(create_signal_arrived): Ditto.
* sigproc.h (signal_arrived): Delete declaration.
(set_signal_mask): Avoid defining as a "C" function. Don't conditionally
declare.
(create_signal_arrived): Delete declaration.
* syscalls.cc (rename): Use cygwait() rather than WFSO.
* thread.h (fast_mutex::lock): Use cw_infinite rather than LARGE_NULL.
* wait.cc (wait4): Ditto.
* thread.cc (pthread_mutex::lock): Ditto.
(pthread::join): Ditto.
(semaphore::_wait): Ditto.
(pthread_kill): Remove set_threadkill() accommodation.
* tlsoffsets.h: Regenerate.
(cancelable_wait): Define variant which accepts DWORD time argument.
(cygwait): Use cancelable_wait with DWORD argument.
(cygwait): Use cancelable_wait with DWORD argument and cw_sig_eintr for
timeout-only case.
* exceptions.cc (handle_sigsuspend): Use LARGE_NULL as second argument to
distinguish between cancelable_wait variants.
* thread.cc (pthread_mutex::lock): Ditto.
(pthread::join): Ditto.
(semaphore::_timedwait): Ditto.
* thread.h (fast_mutex::lock): Ditto.
* wait.cc (wait4): Ditto.
newlib doesn't install cleanup handlers. Explain the problem.
(class __cygwin_lock_handler): New class.
(__cygwin_lock_cleanup): New function.
(__cygwin_lock_lock): Push __cygwin_lock_cleanup thread cleanup
handler.
(__cygwin_lock_trylock): Ditto.
(__cygwin_lock_unlock): Pop thread cleanup handler.
(pthread::pop_cleanup_handler): Temporarily allow cleanup function to
destroy cleanup handler so we can pop in another function than we
pushed in.
to PTHREAD_CANCEL_DISABLE from here...
(pthread::pop_all_cleanup_handlers): ...to here, otherwise any explicit
call to pthread_cleanup_pop disables cancellation for this thread.