PERFORCE change 67971 for review
David Xu
davidxu at FreeBSD.org
Fri Dec 31 06:44:47 PST 2004
http://perforce.freebsd.org/chv.cgi?CH=67971
Change 67971 by davidxu at davidxu_tiger on 2004/12/31 14:43:55
slight cleanup, remove no longer used fields.
Affected files ...
.. //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_private.h#9 edit
Differences ...
==== //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_private.h#9 (text+ko) ====
@@ -41,21 +41,22 @@
* Include files.
*/
#include <sys/limits.h>
-#include <setjmp.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/cdefs.h>
+#include <sys/queue.h>
+#include <machine/atomic.h>
+#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <sched.h>
#include <unistd.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/cdefs.h>
-#include <sys/queue.h>
#include <ucontext.h>
#include <sys/thr.h>
+#include <sys/umtx.h>
#include <pthread.h>
#include <pthread_np.h>
-#include "lock.h"
#include "pthread_md.h"
/*
@@ -69,10 +70,13 @@
#define SCLASS_PRESET(x...)
#endif
+/* Signal to do cancellation */
+#define SIGCANCEL 32
+
/*
* Kernel fatal error handler macro.
*/
-#define PANIC(string) _thr_exit(__FILE__,__LINE__,string)
+#define PANIC(string) _thr_exit(__FILE__,__LINE__,string)
/* Output debug messages like this: */
#define stdout_debug(args...) _thread_printf(STDOUT_FILENO, ##args)
@@ -80,23 +84,13 @@
#ifdef _PTHREADS_INVARIANTS
#define THR_ASSERT(cond, msg) do { \
- if (!(cond)) \
+ if (__predict_false(!(cond))) \
PANIC(msg); \
} while (0)
#else
#define THR_ASSERT(cond, msg)
#endif
-/*
- * State change macro without scheduling queue change:
- */
-#define THR_SET_STATE(thrd, newstate) do { \
- (thrd)->state = newstate; \
- (thrd)->fname = __FILE__; \
- (thrd)->lineno = __LINE__; \
-} while (0)
-
-
#define TIMESPEC_ADD(dst, src, val) \
do { \
(dst)->tv_sec = (src)->tv_sec + (val)->tv_sec; \
@@ -180,8 +174,10 @@
* Lock for accesses to this structure.
*/
struct umtx c_lock;
+ volatile long c_seqno;
+ volatile long c_waiters;
+ volatile long c_wakeups;
long c_flags;
- int c_count;
};
struct pthread_cond_attr {
@@ -194,7 +190,7 @@
pthread_cond_t b_cond;
int b_count;
int b_waiters;
- int b_generation;
+ int b_cycle;
};
struct pthread_barrierattr {
@@ -202,7 +198,7 @@
};
struct pthread_spinlock {
- struct umtx s_lock;
+ struct umtx s_lock;
};
/*
@@ -219,8 +215,24 @@
struct pthread_cleanup *next;
void (*routine)();
void *routine_arg;
+ int onstack;
};
+#define THR_CLEANUP_PUSH(td, func, arg) { \
+ struct pthread_cleanup __cup; \
+ \
+ __cup.routine = func; \
+ __cup.routine_arg = arg; \
+ __cup.onstack = 1; \
+ __cup.next = (td)->cleanup; \
+ (td)->cleanup = &__cup;
+
+#define THR_CLEANUP_POP(td, exec) \
+ (td)->cleanup = __cup.next; \
+ if ((exec) != 0) \
+ __cup.routine(__cup.routine_arg); \
+}
+
struct pthread_atfork {
TAILQ_ENTRY(pthread_atfork) qe;
void (*prepare)(void);
@@ -235,7 +247,6 @@
int prio;
int suspend;
#define THR_STACK_USER 0x100 /* 0xFF reserved for <pthread.h> */
-#define THR_SIGNAL_THREAD 0x200 /* This is a signal thread */
int flags;
void *arg_attr;
void (*cleanup_attr)();
@@ -260,7 +271,7 @@
* than the stacks of other threads, since many applications are likely to run
* almost entirely on this stack.
*/
-#define THR_STACK_INITIAL 0x100000
+#define THR_STACK_INITIAL 0x200000
/*
* Define the different priority ranges. All applications have thread
@@ -308,41 +319,18 @@
*/
enum pthread_state {
PS_RUNNING,
- PS_MUTEX_WAIT,
- PS_JOIN,
- PS_SUSPENDED,
- PS_DEAD,
- PS_DEADLOCK,
- PS_STATE_MAX
+ PS_DEAD
};
union pthread_wait_data {
pthread_mutex_t mutex;
- pthread_cond_t cond;
};
/*
* Define a continuation routine that can be used to perform a
* transfer of control:
*/
-typedef void (*thread_continuation_t)(void *);
-
-/*
- * This stores a thread's state prior to running a signal handler.
- * It is used when a signal is delivered to a thread blocked in
- * userland. If the signal handler returns normally, the thread's
- * state is restored from here.
- */
-struct pthread_sigframe {
- int psf_flags;
- int psf_cancelflags;
- int psf_interrupted;
- int psf_timeout;
- enum pthread_state psf_state;
- union pthread_wait_data psf_wait_data;
- struct timespec psf_wakeup_time;
- thread_continuation_t psf_continuation;
-};
+typedef void (*thread_continuation_t) (void *);
struct join_status {
struct pthread *thread;
@@ -386,18 +374,18 @@
/* Kernel thread id. */
long tid;
+ /* Internal condition variable cycle number. */
+ long cycle;
+
/* How many low level locks the thread held. */
int locklevel;
- /* How many signals were received. */
- int sigseqno;
+ /*
+ * Set to non-zero when this thread has entered a critical
+ * region. We allow for recursive entries into critical regions.
+ */
+ int critical_count;
- /* Thread lock held and switching state. */
- int lock_switch;
-
- /* Thread is waiting. */
- int idle;
-
/* Queue entry for list of all threads. */
TAILQ_ENTRY(pthread) tle; /* link for all threads in process */
@@ -418,21 +406,18 @@
void *arg;
struct pthread_attr attr;
- /* backout routine must be invoke before handling signal. */
- thread_continuation_t sigbackout;
-
/*
- * Cancelability flags - the lower 2 bits are used by cancel
- * definitions in pthread.h
+ * Cancelability flags
*/
-#define THR_AT_CANCEL_POINT 0x0004
+#define THR_CANCEL_DISABLE 0x0001
+#define THR_CANCEL_EXITING 0x0002
+#define THR_CANCEL_AT_POINT 0x0004
#define THR_CANCELLING 0x0008
#define THR_CANCEL_NEEDED 0x0010
+#define THR_CANCEL_ASYNCHRONOUS 0x0020
int cancelflags;
- thread_continuation_t continuation;
-
- /* Thread's temporary signal masks. */
+ /* Thread temporary signal mask. */
sigset_t sigmask;
/* Used for tracking delivery of signal handlers. */
@@ -440,19 +425,13 @@
siginfo_t siginfo[_SIG_MAXSIG];
volatile int check_pending;
+ /* backout routine must be invoke before handling signal. */
+ thread_continuation_t sigbackout;
+
/* Thread state: */
enum pthread_state state;
/*
- * Time to wake up thread. This is used for sleeping threads and
- * for any operation which may time out (such as select).
- */
- struct timespec wakeup_time;
-
- /* TRUE if operation has timed out. */
- int timeout;
-
- /*
* Error variable used instead of errno. The function __error()
* returns a pointer to this.
*/
@@ -466,54 +445,29 @@
struct join_status join_status;
/*
- * The current thread can belong to:
- *
- * o A queue of threads waiting for a mutex
- * o A queue of threads waiting for a condition variable
- *
- * It is possible for a thread to belong to more than one of the
- * above queues if it is handling a signal. A thread may only
- * enter a mutex or condition variable queue when it is not
- * being called from a signal handler. If a thread is a member
- * of one of these queues when a signal handler is invoked, it
- * must be removed from the queue before invoking the handler
- * and then added back to the queue after return from the handler.
- *
- * Use pqe for the scheduling queue link (both ready and waiting),
- * sqe for synchronization (mutex, condition variable, and join)
- * queue links, and qe for all other links.
+ * The current thread can belong to a priority mutex queue.
+ * This is the synchronization queue link.
*/
- TAILQ_ENTRY(pthread) sqe; /* synchronization queue link */
+ TAILQ_ENTRY(pthread) sqe;
/* Wait data. */
union pthread_wait_data data;
- /*
- * Set to TRUE if a blocking operation was
- * interrupted by a signal:
- */
- int interrupted;
-
- /*
- * Set to non-zero when this thread has entered a critical
- * region. We allow for recursive entries into critical regions.
- */
- int critical_count;
-
int sflags;
#define THR_FLAGS_IN_SYNCQ 0x0001
/* Miscellaneous flags; only set with scheduling lock held. */
int flags;
#define THR_FLAGS_PRIVATE 0x0001
-#define THR_FLAGS_EXITING 0x0008 /* thread is exiting */
-#define THR_FLAGS_SUSPENDED 0x0010 /* thread is suspended */
+#define THR_FLAGS_NEED_SUSPEND 0x0002 /* thread should be suspended */
+#define THR_FLAGS_SUSPENDED 0x0004 /* thread is suspended */
/* Thread list flags; only set with thread list lock held. */
+ int tlflags;
#define TLFLAGS_GC_SAFE 0x0001 /* thread safe for cleaning */
#define TLFLAGS_IN_TDLIST 0x0002 /* thread in all thread list */
#define TLFLAGS_IN_GCLIST 0x0004 /* thread in gc list */
- int tlflags;
+#define TLFLAGS_DETACHED 0x0008 /* thread is detached */
/*
* Base priority is the user setable and retrievable priority
@@ -565,14 +519,14 @@
/* Cleanup handlers Link List */
struct pthread_cleanup *cleanup;
+};
- /* Ptr to source file name*/
- char *fname;
+#define UMTX_LOCK(m, tid) \
+ do { \
+ while (umtx_lock(m, tid)) \
+ ; \
+ } while (0)
- /* Source line number. */
- int lineno;
-};
-
/*
* Critical regions can also be detected by looking at the threads
* current lock level. Ensure these macros increment and decrement
@@ -581,9 +535,9 @@
*/
#define THR_IN_CRITICAL(thrd) \
(((thrd)->locklevel > 0) || \
- ((thrd)->critical_count > 0))
+ ((thrd)->critical_count > 0))
-#define THR_YIELD_CHECK(thrd) \
+#define THR_CRITICAL_CHECK(thrd) \
do { \
if (!THR_IN_CRITICAL(thrd)) { \
if ((thrd)->check_pending != 0) \
@@ -594,26 +548,28 @@
#define THR_LOCK_ACQUIRE(thrd, lck) \
do { \
(thrd)->locklevel++; \
- UMTX_ACQUIRE((lck), (thrd)->tid); \
+ UMTX_LOCK((lck), (thrd)->tid); \
} while (0)
#define THR_LOCK_RELEASE(thrd, lck) \
do { \
if ((thrd)->locklevel > 0) { \
- UMTX_RELEASE((lck), (thrd)->tid); \
+ umtx_unlock((lck), (thrd)->tid); \
(thrd)->locklevel--; \
- if ((thrd)->locklevel == 0) \
- THR_YIELD_CHECK(thrd); \
+ THR_CRITICAL_CHECK(thrd); \
} else { \
- PANIC("locklevel <= 0"); \
+ _thr_assert_lock_level(); \
} \
} while (0)
-#define THR_LOCK(thr) THR_LOCK_ACQUIRE(thr, &(thr)->lock)
-#define THR_UNLOCK(thr) THR_LOCK_RELEASE(thr, &(thr)->lock)
+#define THR_LOCK(curthrd) THR_LOCK_ACQUIRE(curthrd, &(curthrd)->lock)
+#define THR_UNLOCK(curthrd) THR_LOCK_RELEASE(curthrd, &(curthrd)->lock)
#define THR_THREAD_LOCK(curthrd, thr) THR_LOCK_ACQUIRE(curthrd, &(thr)->lock)
#define THR_THREAD_UNLOCK(curthrd, thr) THR_LOCK_RELEASE(curthrd, &(thr)->lock)
+#define THREAD_LIST_LOCK(curthrd) THR_LOCK_ACQUIRE((curthrd), &_thread_list_lock)
+#define THREAD_LIST_UNLOCK(curthrd) THR_LOCK_RELEASE((curthrd), &_thread_list_lock)
+
/*
* Macros to insert/remove threads to the all thread list and
* the gc list.
@@ -649,32 +605,15 @@
#define GC_NEEDED() (atomic_load_acq_int(&_gc_count) >= 5)
-/* Take the scheduling lock with the intent to call the scheduler. */
-#define THR_LOCK_SWITCH(curthr) do { \
- curthread->lock_switch++; \
- UMTX_ACQUIRE(&(curthr->lock), (curthr)->tid); \
-} while (0)
-#define THR_UNLOCK_SWITCH(curthr) do { \
- UMTX_RELEASE(&(curthr->lock), (curthr)->tid); \
- curthread->lock_switch--; \
- THR_YIELD_CHECK(curthr); \
-} while (0)
-
#define THR_CRITICAL_ENTER(thr) (thr)->critical_count++
#define THR_CRITICAL_LEAVE(thr) do { \
(thr)->critical_count--; \
- if ((thr)->critical_count == 0) { \
- THR_YIELD_CHECK(thr); \
+ THR_CRITICAL_CHECK(thr); \
} \
} while (0)
#define THR_IN_SYNCQ(thrd) (((thrd)->sflags & THR_FLAGS_IN_SYNCQ) != 0)
-#define THR_IS_SUSPENDED(thrd) \
- (((thrd)->state == PS_SUSPENDED) || \
- (((thrd)->flags & THR_FLAGS_SUSPENDED) != 0))
-#define THR_IS_EXITING(thrd) (((thrd)->flags & THR_FLAGS_EXITING) != 0)
-
extern int __isthreaded;
/*
@@ -741,14 +680,13 @@
* Function prototype definitions.
*/
__BEGIN_DECLS
-int _cond_reinit(pthread_cond_t *);
void _thr_kern_init();
void _thr_single_thread(struct pthread *);
int _thr_setthreaded(int);
int _mutex_cv_lock(pthread_mutex_t *);
int _mutex_cv_unlock(pthread_mutex_t *);
void _mutex_notify_priochange(struct pthread *, struct pthread *, int);
-int _mutex_reinit(struct pthread_mutex *);
+int _mutex_reinit(pthread_mutex_t *);
void _mutex_unlock_private(struct pthread *);
void _libpthread_init(struct pthread *);
void *_pthread_getspecific(pthread_key_t);
@@ -771,34 +709,25 @@
void _pthread_cleanup_push(void (*routine) (void *), void *routine_arg);
void _pthread_cleanup_pop(int execute);
struct pthread *_thr_alloc(struct pthread *);
-void _thr_exit(char *, int, char *);
+void _thr_exit(char *, int, char *) __dead2;
void _thr_exit_cleanup(void);
-void _thr_mutex_reinit(pthread_mutex_t *);
int _thr_ref_add(struct pthread *, struct pthread *, int);
void _thr_ref_delete(struct pthread *, struct pthread *);
+int _thr_find_thread(struct pthread *, struct pthread *, int);
void _thr_rtld_init(void);
void _thr_rtld_fini(void);
-void _thr_setrunnable(struct pthread *curthread, struct pthread *thread);
-long _thr_setrunnable_unlocked(struct pthread *thread);
-long _thr_sig_add(struct pthread *, int, siginfo_t *);
int _thr_stack_alloc(struct pthread_attr *);
void _thr_stack_free(struct pthread_attr *);
-void _thr_exit_cleanup(void);
void _thr_free(struct pthread *, struct pthread *);
void _thr_gc(struct pthread *);
void _thread_cleanupspecific(void);
void _thread_dump_info(void);
void _thread_printf(int, const char *, ...);
-void _thr_sched_switch(struct pthread *);
-void _thr_sched_switch_unlocked(struct pthread *);
-void _thr_set_timeout(const struct timespec *);
void _thr_sig_handler(int, siginfo_t *, ucontext_t *);
void _thr_sig_check_pending(struct pthread *);
void _thr_sig_rundown(struct pthread *);
-void _thr_sig_send(struct pthread *pthread, int sig);
-void _thr_sigframe_restore(struct pthread *thread, struct pthread_sigframe *psf);
void _thr_spinlock_init(void);
-void _thr_cancel_enter(struct pthread *);
+int _thr_cancel_enter(struct pthread *);
void _thr_cancel_leave(struct pthread *, int);
void _thr_critical_enter(struct pthread *);
void _thr_critical_leave(struct pthread *);
@@ -807,9 +736,10 @@
void _thr_hash_add(struct pthread *);
void _thr_hash_remove(struct pthread *);
struct pthread *_thr_hash_find(struct pthread *);
-void _thr_finish_cancellation(void *arg);
void _thr_link(struct pthread *curthread, struct pthread *thread);
void _thr_unlink(struct pthread *curthread, struct pthread *thread);
+void _thr_suspend_check(struct pthread *curthread);
+void _thr_assert_lock_level() __dead2;
/*
* Aliases for _pthread functions. Should be called instead of
More information about the p4-projects
mailing list