Commit Graph

55 Commits

Author SHA1 Message Date
marcel
241ed6e2c5 Create compatibility links for libc_r on ia64 to prevent build-time
breakages. Note that runtime compatibility is not guaranteed. Future
changes to setjmp/longjmp in libc will break threaded applications
linked against libc_r.so.5 on ia64. We pull our "tier 2" card once
more...

Reviewed by: ru
2003-06-27 18:07:47 +00:00
mtm
367c2bf710 _thread_printf() is only used for debugging or in cases where something's
screwed beyond all help, so it can just skip the pthreads wrapper
for write(2) and call directly into it.
2003-06-09 17:58:15 +00:00
mtm
1cbcd8981e Make C applications statically compiled with libthr work. Previously,
an application compiled -static with libthr would dump core in
malloc(3) because the stub thread initialization routine in libc would
be used instead of the libthr supplied one.
2003-06-04 08:23:05 +00:00
mtm
2e32bd0e48 Teach recent changes in the umtx structure in the kernel to the libthr
initialiazer.

Found by:	tinderbox
2003-06-03 09:31:33 +00:00
mtm
36ca946c21 Unwind the _giant_mutex from pthread_detach(). When detaching a joiner thread
it's important the correct lock order is observed: lock first the joined and
then the joiner.
2003-06-02 11:01:00 +00:00
mtm
26fddf76d0 Consolidate static_init() and static_init_private into one function.
The behaviour of this function is controlled by the argument: private.
2003-06-02 10:04:18 +00:00
obrien
975daeb011 .S comments must be C comments, not ASM ones. 2003-06-02 02:32:56 +00:00
mtm
12068977c4 I botched one of my committs in the last round. Fix it. 2003-05-31 14:38:22 +00:00
mtm
ba1a492744 Make the mutex static initializers look more like the one for
condition variables. Cosmetic.

Explicitly compare against PTHREAD_MUTEX_INITIALIZER. We shouldn't
encourage calls to the mutex functions with null pointers to mutexes.

Approved by:	re/jhb
2003-05-29 20:58:31 +00:00
mtm
c13b303c62 Use a static lock to ake sure pthread_cond_* functions called
from multiple threads don't initialze the same condition variable
more than once.

Explicitly compare cond pointers with PTHREAD_COND_INITIALIZER instead
of NULL. Just because it happens to be defined as NULL is no reason
to encourage the idea that people can call those functions with
NULL pointers to a condition variable.

Approved by:	re/jhb
2003-05-29 20:54:00 +00:00
mtm
f6ab524199 Missing unlock.
Approved by:	re/jhb
2003-05-29 20:49:17 +00:00
mtm
cf28d45530 Don't hold the active thread list lock when signaling the gc thread.
The dead list thread is sufficient for synchronization.

Retire the arch_id (ldt array slot) in the gc thread instead of the
doing it in the thread itself.

Approved by:	re/jhb
2003-05-29 20:46:53 +00:00
mtm
b20e8e3838 It's unnecessary to lock the thread during creation. Simply extend
the scope of the active thread list lock.

Approved by:	re/jhb
2003-05-29 20:40:50 +00:00
mtm
6fe5416153 Minimize the potential for deadlocks between an exiting thread and it's
joiner by making sure all locks and unlocks occur in the same order. For
the record the lock order is: DEAD_LIST, THREAD_LIST, exiting thread, joiner
thread.

Approved by: re/rwatson
2003-05-27 21:48:42 +00:00
mtm
f8cea3eec0 Revert part of the last commit. I don't know what I was smoking.
Approved by: re/rwatson
2003-05-27 21:43:49 +00:00
mtm
968f993941 Decouple the thread stack [de]allocating functions from the 'dead threads list'
lock. It's not really necessary and we don't need the added complexity
or potential for deadlocks.

Approved by:	re/blanket libthr
2003-05-26 00:37:07 +00:00
mtm
1758180227 Revise the unlock order in _pthread_join(). Also, if the joined
thread is not dead, the join loop is guaranteed to execute at least
once, so there is no need to pick up the thread list lock after
we return from suspenstion only to release it after the loop.

Approved by:	re/blanket libthr
2003-05-26 00:28:49 +00:00
mtm
23cb2b75ff Return gracefully, rather than aborting, when the maximum concurrent
threads per process has been reached. Return EAGAIN, as per spec.

Approved by:	re/blanket libthr
2003-05-25 22:40:57 +00:00
mtm
4c97496368 _pthread_cancel() breaks the normal lock order of first locking the
joined and then the joiner thread. There isn't an easy (sane?) way
to make it use the correct order without introducing races involving
the target thread and finding which (active or dead) list it is on. So,
after locking the canceled thread it will try to lock the joined thread
and if it fails release the first lock and try again from the top.

Introduce a new function, _spintrylock, which is simply a wrapper arround
umtx_trylock(), to help accomplish this.

Approved by: re/blanket libthr
2003-05-25 08:48:11 +00:00
mtm
e182f494ed Part of the last patch.
Modify the thread creation and thread searching routine
to lock the thread lists with the new locks instead of GIANT_LOCK.

Approved by:	re/blanket libthr
2003-05-25 08:35:37 +00:00
mtm
d14b2bbb8b Start locking up the active and dead threads lists. The active threads
list is protected by a spinlock_t, but the dead list uses a pthread_mutex
because it is necessary to synchronize other threads with the garbage
collector thread. Lock/Unlock macros are used so it's easier to make
changes to the locks in the future.

The 'dead thread list' lock is intended to replace the gc mutex.
This doesn't have any practical ramifications. It simply makes it
clearer what the purpose of the lock is. The gc will use this lock,
instead of the gc mutex, to synchronize access to the dead list with
other threads.

Modify _pthread_exit() to use these two new locks instead of GIANT_LOCK,
and also to properly lock and protect thread state changes,
especially with respect to a joining thread.

The gc thread was also re-arranged to be more organized and less nested.

_pthread_join() was also modified to use the thread list locks. However,
locking and unlocking here needs special care because a thread could find
itself in a position where it's joining an exiting thread that is
waiting on the dead list lock, which this thread (joiner) holds. If the
joiner doesn't take care to lock *and* unlock in the same order they
(the joiner and the joinee) could deadlock against each other.

Approved by:	re/blanket libthr
2003-05-25 08:31:33 +00:00
mtm
56afebcb6b The libthr code makes use of higher-level primitives (pthread_mutex_t and
pthread_cond_t) internaly in addition to the low-level spinlock_t. The
garbage collector mutex and condition variable are two such examples. This
might lead to critical sections nested within critical sections. Implement
a reference counting mechanism so that signals are masked only on the first
entry and unmasked on the last exit.

I'm not sure I like the idea of nested critical sections, but if
the library is going to use the pthread primitives it might be necessary.

Approved by:	re/blanket libthr
2003-05-25 07:58:22 +00:00
marcel
9f10385e1b The struct mcontext has changed. It's using the register sets. Bring
this in line.
2003-05-25 06:49:19 +00:00
mtm
02051dbacb Lock the cond queue (condition variables):
Access to the thread's flags and state is protected by
_thread_critical_enter/exit(). When a thread is signaled with a condition
its state must be protected by locking it and disabling
signals before it is taken of the waiters' queue.

Move the implementation of pthread_cond_signal() and pthread_cond_broadcast()
into one function, cond_signal(). Its behaviour is determined by the
last argument, int broadcast. If this is set to 1 it will remove all
waiters, otherwise it will wake up only the first waiter thread.

Remove an extraneous call to pthread_testcancel().

Approved by:	re/blanket libthr
2003-05-24 01:02:16 +00:00
mtm
364f965fef Add two functions: _spinlock_pthread() and _spinunlock_pthread()
that take the address of a struct pthread as their first argument.
_spin[un]lock() just become wrappers arround these two functions.
These new functions are for use in situations where curthread can't be
used. One example is _thread_retire(), where we invalidate the array index
curthread uses to get its pointer..

Approved by:	re/blanket libthr
2003-05-23 23:39:31 +00:00
mtm
cd8b6f00c5 EDOOFUS
Prevent one thread from messing up another thread's saved signal
mask by saving it in struct pthread instead of leaving it as a
global variable. D'oh!

Approved by:	re/blanket libthr
2003-05-23 10:28:13 +00:00
mtm
2ebe826fa4 Make WARNS2 clean. The fixes mostly included:
o removed unused variables
	o explicit inclusion of header files
	o prototypes for externally defined functions

Approved by:    re/blanket libthr
2003-05-23 09:48:20 +00:00
mtm
131a49e2ae note to self: do not confuse void* with int.
Approved by:	re/blanket libthr
2003-05-23 08:13:24 +00:00
mtm
1837329d03 o Make the defenition of _set_curthread() match its declaration
in thr_private.h

o Lock down the ldt_entries array and ldt_free, which points to
  the next free slot. As noted in the comments, it's necessary
  to special case the initial_thread because %gs is not setup
  for it yet. This is ok because that early in the program there
  won't be any reentrancy issues anyways.

Approved by:	re/blanket libthr
2003-05-21 08:21:24 +00:00
mtm
445a2987cd Insert a debugging aid:
When in either the mutex or cond queue we notice that the thread
 is already on one of the queues, don't just simply abort(). Print
 out the thread's identifiers and what queue it was on.

Approved by: markm/mentor, re/blanket libthr
2003-05-21 03:41:07 +00:00
mtm
690445ccd6 Re-enable the garbage collector thread in anticipation of further
locking work. I can't see anything obviously wrong with it (other than
the need to update the locking).

Approved by: markm/mentor, re/blanket libthr
2003-05-21 03:34:54 +00:00
mtm
4b5622fac3 When a thread exits it does not return from the kernel unless it
is the *only* remaining thread in the application, in which case we
should not core dump, and instead exit gracefully.

Approved by: markm/mentor, re/blanket libthr
2003-05-21 03:29:18 +00:00
mtm
753884c94c The thread id was being set *before* zeroing out the thread. Reverse
the order.

Approved by: markm/mentor, re/blanket libthr
2003-05-21 03:22:36 +00:00
mtm
7c20ad36ba Move a misplaced comment.
Approved by:	markm/mentor (implicit), re/blanket libthr
2003-05-20 18:48:41 +00:00
mtm
23119ee22a Do some cleanup with respect to condition variables. The implementation
of pthread_cond_timedwait() is moved into cond_wait_common().
Pthread_cond_wait() and pthread_cond_timedwait() are now wrappers around
this function. Previously, the former called the latter with the abstime
pointing to 0 time. This violated Posix semantics should an application
have reason to call it with that argument because instead or returning
immediately it would have waited indefinitely for the cv to be signaled.

Approved by:	markm/mentor, re/blanket libthr
Reviewed by:	jeff
2003-05-15 18:17:13 +00:00
mtm
7755d3cd84 o Make the setting/checking of cancel state atomic with
respect to other threads and signal handlers by moving to
  the _thread_critical_enter/exit functions.

o Introduce an static function, testcancel(), that is used by
  the other functions in this module. This allows it to make
  locking assumptions that the top-level functions can't.

o Rework the code flow a bit to reduce indentation levels.

Approved by:	markm/mentor, re/blanket libthr
Reviewed by:	jeff
2003-05-15 17:56:18 +00:00
mtm
19ce61a04c msg2 2003-05-12 10:40:53 +00:00
mtm
8a7ed645e8 msg1 2003-05-12 10:34:01 +00:00
mtm
b6ee26825b Fix a null dereference leading to a core dump when
the number of threads exceeds the number of open slots
in ldt_entries[].

Approved by:	markm (mentor)(implicit)
Reviewed by:	jeff
2003-05-06 02:33:49 +00:00
mtm
4f849fcd73 o Correct a debug message that refered to the wrong function
o Remove an unncecesary if clause

Approved by:	markm (mentor)(implicit)
Reviewd by:	jeff
2003-05-06 02:30:52 +00:00
marcel
0bcdf26399 Add support for ia64.
Note that the tp register (r13) is reserved as the TLS pointer in
the same way that that gp register (r1) is reserved as the global
pointer. This implementation uses the tp register to point to the
thread structure used by the threads implementation. This is not
in violation with the runtime specification provided the TLS is
a fixed distance from the thread structure. This is only an issue
when code used the __thread keyword to create TLS. This is not
supported at the moment.
2003-04-20 03:06:42 +00:00
marcel
bb02aad834 Use STDERR_FILENO as the file descriptor passed to _thread_printf()
instead of 0 (ie stdin). Writing to stdin may not be possible.
2003-04-20 02:58:30 +00:00
marcel
0597739137 Fix build breakage (on ia64) caused by a missing file descriptor to
_thread_printf(). Use STDERR_FILENO as the file descriptor.
2003-04-20 02:56:12 +00:00
jdp
bfcb757e94 Add stub implementations of pthread_[gs]etconcurrency to libc_r and
libthr.  No changes were made to libpthread by request of deischen,
who will soon commit a real implementation for that library.

PR:		standards/50848
Submitted by:	Sergey A. Osokin <osa@freebsd.org.ru>
MFC after:	1 week
2003-04-20 01:53:13 +00:00
jake
ae0306ff52 - Pass a ucontext_t to _set_curthread. If non-NULL the new thread is set
as curthread in the new context, so that it will be set automatically when
  the thread is switched to.  This fixes a race where we'd run for a little
  while with curthread unset in _thread_start.

Reviewed by:	jeff
2003-04-03 03:34:50 +00:00
jeff
f8e699234b - Don't overrun the ldt buffer.
Submitted by:	gordan@freebsd.org
2003-04-02 22:53:52 +00:00
jake
c659dc94d4 Implement _get_curthread and _set_curthread. This is especially easy. 2003-04-02 08:15:07 +00:00
jeff
2c8f04bc3e - Define curthread as _get_curthread() and remove all direct calls to
_get_curthread().  This is similar to the kernel's curthread.  Doing
   this saves stack overhead and is more convenient to the programmer.
 - Pass the pointer to the newly created thread to _thread_init().
 - Remove _get_curthread_slow().
2003-04-02 03:05:39 +00:00
jake
02b28b9c96 Add MD makefile. 2003-04-01 23:52:24 +00:00
jeff
afdf14858f - Don't drop and reacquire giant in thread_suspend(). Change callers to do
this manually.  This will facilitate the unrolling of giant.
 - Don't allow giant to recurse anymore.  This should never happen.
2003-04-01 22:41:41 +00:00