summaryrefslogtreecommitdiffstats
path: root/lib/libpthread/thread/thr_kern.c
diff options
context:
space:
mode:
authorjulian <julian@FreeBSD.org>1996-08-20 08:22:01 +0000
committerjulian <julian@FreeBSD.org>1996-08-20 08:22:01 +0000
commit7350d1d3b2ec940c89a2b20f9d09985d9fd9e9d7 (patch)
treeb14348030d1048f8628b798374a8a061a990aae3 /lib/libpthread/thread/thr_kern.c
parent60125bd1a9e42a8b02f15396ba886b417c95bbc1 (diff)
downloadFreeBSD-src-7350d1d3b2ec940c89a2b20f9d09985d9fd9e9d7.zip
FreeBSD-src-7350d1d3b2ec940c89a2b20f9d09985d9fd9e9d7.tar.gz
Submitted by: John Birrell <cimaxp1!jb@werple.net.au>
Here are the diffs for libc_r to get it one step closer to P1003.1c These make most of the thread/mutex/condvar structures opaque to the user. There are three functions which have been renamed with _np suffixes because they are extensions to P1003.1c (I did them for JAVA, which needs to suspend/resume threads and also start threads suspended). I've created a new header (pthread_np.h) for the non-POSIX stuff. The egrep tags stuff in /usr/src/lib/libc_r/Makefile that I uncommented doesn't work. I think its best to delete it. I don't think libc_r needs tags anyway, 'cause most of the source is in libc which does have tags. also: Here's the first batch of man pages for the thread functions. The diff to /usr/src/lib/libc_r/Makefile removes some stuff that was inherited from /usr/src/lib/libc/Makefile that should only be done with libc. also: I should have sent this diff with the pthread(3) man page. It allows people to type make -DWANT_LIBC_R world to get libc_r built with the rest of the world. I put this in the pthread(3) man page. The default is still not to build libc_r. also: The diff attached adds a pthread(3) man page to /usr/src/share/man/man3. The idea is that without libc_r installed, this man page will give people enough info to know that they have to build libc_r.
Diffstat (limited to 'lib/libpthread/thread/thr_kern.c')
-rw-r--r--lib/libpthread/thread/thr_kern.c231
1 files changed, 230 insertions, 1 deletions
diff --git a/lib/libpthread/thread/thr_kern.c b/lib/libpthread/thread/thr_kern.c
index 35e8e29..c6759cf 100644
--- a/lib/libpthread/thread/thr_kern.c
+++ b/lib/libpthread/thread/thr_kern.c
@@ -250,18 +250,30 @@ __asm__("fnsave %0": :"m"(*fdata));
pthread->state == PS_FDW_WAIT ||
pthread->state == PS_SELECT_WAIT) {
/* Check if this thread is to wait forever: */
+#if defined(__FreeBSD__)
if (pthread->wakeup_time.ts_sec == -1) {
+#else
+ if (pthread->wakeup_time.tv_sec == -1) {
+#endif
}
/*
* Check if this thread is to wakeup
* immediately or if it is past its wakeup
* time:
*/
+#if defined(__FreeBSD__)
else if ((pthread->wakeup_time.ts_sec == 0 &&
pthread->wakeup_time.ts_nsec == 0) ||
(ts.ts_sec > pthread->wakeup_time.ts_sec) ||
((ts.ts_sec == pthread->wakeup_time.ts_sec) &&
(ts.ts_nsec >= pthread->wakeup_time.ts_nsec))) {
+#else
+ else if ((pthread->wakeup_time.tv_sec == 0 &&
+ pthread->wakeup_time.tv_nsec == 0) ||
+ (ts.tv_sec > pthread->wakeup_time.tv_sec) ||
+ ((ts.tv_sec == pthread->wakeup_time.tv_sec) &&
+ (ts.tv_nsec >= pthread->wakeup_time.tv_nsec))) {
+#endif
/*
* Check if this thread is waiting on
* select:
@@ -364,9 +376,48 @@ __asm__("fnsave %0": :"m"(*fdata));
}
/*
* Enter a loop to look for the first thread of the highest
- * priority:
+ * priority that is ready to run:
*/
for (pthread = _thread_link_list; pthread != NULL; pthread = pthread->nxt) {
+ /* Check if in single-threaded mode: */
+ if (_thread_single != NULL) {
+ /*
+ * Check if the current thread is
+ * the thread for which single-threaded
+ * mode is enabled:
+ */
+ if (pthread == _thread_single) {
+ /*
+ * This thread is allowed
+ * to run.
+ */
+ } else {
+ /*
+ * Walk up the signal handler
+ * parent thread tree to see
+ * if the current thread is
+ * descended from the thread
+ * for which single-threaded
+ * mode is enabled.
+ */
+ pthread_nxt = pthread;
+ while(pthread_nxt != NULL &&
+ pthread_nxt != _thread_single) {
+ pthread_nxt = pthread->parent_thread;
+ }
+ /*
+ * Check if the current
+ * thread is not descended
+ * from the thread for which
+ * single-threaded mode is
+ * enabled.
+ */
+ if (pthread_nxt == NULL)
+ /* Ignore this thread. */
+ continue;
+ }
+ }
+
/* Check if the current thread is unable to run: */
if (pthread->state != PS_RUNNING) {
}
@@ -392,6 +443,45 @@ __asm__("fnsave %0": :"m"(*fdata));
* least recently.
*/
for (pthread = _thread_link_list; pthread != NULL; pthread = pthread->nxt) {
+ /* Check if in single-threaded mode: */
+ if (_thread_single != NULL) {
+ /*
+ * Check if the current thread is
+ * the thread for which single-threaded
+ * mode is enabled:
+ */
+ if (pthread == _thread_single) {
+ /*
+ * This thread is allowed
+ * to run.
+ */
+ } else {
+ /*
+ * Walk up the signal handler
+ * parent thread tree to see
+ * if the current thread is
+ * descended from the thread
+ * for which single-threaded
+ * mode is enabled.
+ */
+ pthread_nxt = pthread;
+ while(pthread_nxt != NULL &&
+ pthread_nxt != _thread_single) {
+ pthread_nxt = pthread->parent_thread;
+ }
+ /*
+ * Check if the current
+ * thread is not descended
+ * from the thread for which
+ * single-threaded mode is
+ * enabled.
+ */
+ if (pthread_nxt == NULL)
+ /* Ignore this thread. */
+ continue;
+ }
+ }
+
/* Check if the current thread is unable to run: */
if (pthread->state != PS_RUNNING) {
/* Ignore threads that are not ready to run. */
@@ -446,6 +536,45 @@ __asm__("fnsave %0": :"m"(*fdata));
* priority. 3. Became inactive least recently.
*/
for (pthread = _thread_link_list; pthread != NULL; pthread = pthread->nxt) {
+ /* Check if in single-threaded mode: */
+ if (_thread_single != NULL) {
+ /*
+ * Check if the current thread is
+ * the thread for which single-threaded
+ * mode is enabled:
+ */
+ if (pthread == _thread_single) {
+ /*
+ * This thread is allowed
+ * to run.
+ */
+ } else {
+ /*
+ * Walk up the signal handler
+ * parent thread tree to see
+ * if the current thread is
+ * descended from the thread
+ * for which single-threaded
+ * mode is enabled.
+ */
+ pthread_nxt = pthread;
+ while(pthread_nxt != NULL &&
+ pthread_nxt != _thread_single) {
+ pthread_nxt = pthread->parent_thread;
+ }
+ /*
+ * Check if the current
+ * thread is not descended
+ * from the thread for which
+ * single-threaded mode is
+ * enabled.
+ */
+ if (pthread_nxt == NULL)
+ /* Ignore this thread. */
+ continue;
+ }
+ }
+
/*
* Check if the current thread is unable to
* run:
@@ -565,22 +694,37 @@ __asm__("fnsave %0": :"m"(*fdata));
* Check if this thread is to
* wait forever:
*/
+#if defined(__FreeBSD__)
if (pthread->wakeup_time.ts_sec == -1) {
+#else
+ if (pthread->wakeup_time.tv_sec == -1) {
+#endif
}
/*
* Check if this thread is to
* wakeup immediately:
*/
+#if defined(__FreeBSD__)
else if (pthread->wakeup_time.ts_sec == 0 &&
pthread->wakeup_time.ts_nsec == 0) {
+#else
+ else if (pthread->wakeup_time.tv_sec == 0 &&
+ pthread->wakeup_time.tv_nsec == 0) {
+#endif
}
/*
* Check if the current time
* is after the wakeup time:
*/
+#if defined(__FreeBSD__)
else if ((ts.ts_sec > pthread->wakeup_time.ts_sec) ||
((ts.ts_sec == pthread->wakeup_time.ts_sec) &&
(ts.ts_nsec > pthread->wakeup_time.ts_nsec))) {
+#else
+ else if ((ts.tv_sec > pthread->wakeup_time.tv_sec) ||
+ ((ts.tv_sec == pthread->wakeup_time.tv_sec) &&
+ (ts.tv_nsec > pthread->wakeup_time.tv_nsec))) {
+#endif
} else {
/*
* Calculate the time
@@ -589,16 +733,26 @@ __asm__("fnsave %0": :"m"(*fdata));
* for the clock
* resolution:
*/
+#if defined(__FreeBSD__)
ts1.ts_sec = pthread->wakeup_time.ts_sec - ts.ts_sec;
ts1.ts_nsec = pthread->wakeup_time.ts_nsec - ts.ts_nsec +
CLOCK_RES_NSEC;
+#else
+ ts1.tv_sec = pthread->wakeup_time.tv_sec - ts.tv_sec;
+ ts1.tv_nsec = pthread->wakeup_time.tv_nsec - ts.tv_nsec +
+ CLOCK_RES_NSEC;
+#endif
/*
* Check for
* underflow of the
* nanosecond field:
*/
+#if defined(__FreeBSD__)
if (ts1.ts_nsec < 0) {
+#else
+ if (ts1.tv_nsec < 0) {
+#endif
/*
* Allow for
* the
@@ -607,15 +761,24 @@ __asm__("fnsave %0": :"m"(*fdata));
* nanosecond
* field:
*/
+#if defined(__FreeBSD__)
ts1.ts_sec--;
ts1.ts_nsec += 1000000000;
+#else
+ ts1.tv_sec--;
+ ts1.tv_nsec += 1000000000;
+#endif
}
/*
* Check for overflow
* of the nanosecond
* field:
*/
+#if defined(__FreeBSD__)
if (ts1.ts_nsec >= 1000000000) {
+#else
+ if (ts1.tv_nsec >= 1000000000) {
+#endif
/*
* Allow for
* the
@@ -624,8 +787,13 @@ __asm__("fnsave %0": :"m"(*fdata));
* nanosecond
* field:
*/
+#if defined(__FreeBSD__)
ts1.ts_sec++;
ts1.ts_nsec -= 1000000000;
+#else
+ ts1.tv_sec++;
+ ts1.tv_nsec -= 1000000000;
+#endif
}
/*
* Convert the
@@ -1100,11 +1268,20 @@ _thread_kern_select(int wait_reqd)
*/
if (wait_reqd && settimeout) {
/* Check if this thread wants to wait forever: */
+#if defined(__FreeBSD__)
if (pthread->wakeup_time.ts_sec == -1) {
+#else
+ if (pthread->wakeup_time.tv_sec == -1) {
+#endif
}
/* Check if this thread doesn't want to wait at all: */
+#if defined(__FreeBSD__)
else if (pthread->wakeup_time.ts_sec == 0 &&
pthread->wakeup_time.ts_nsec == 0) {
+#else
+ else if (pthread->wakeup_time.tv_sec == 0 &&
+ pthread->wakeup_time.tv_nsec == 0) {
+#endif
/* Override the caller's request to wait: */
wait_reqd = 0;
} else {
@@ -1112,33 +1289,57 @@ _thread_kern_select(int wait_reqd)
* Calculate the time until this thread is
* ready, allowing for the clock resolution:
*/
+#if defined(__FreeBSD__)
ts1.ts_sec = pthread->wakeup_time.ts_sec - ts.ts_sec;
ts1.ts_nsec = pthread->wakeup_time.ts_nsec - ts.ts_nsec +
CLOCK_RES_NSEC;
+#else
+ ts1.tv_sec = pthread->wakeup_time.tv_sec - ts.tv_sec;
+ ts1.tv_nsec = pthread->wakeup_time.tv_nsec - ts.tv_nsec +
+ CLOCK_RES_NSEC;
+#endif
/*
* Check for underflow of the nanosecond
* field:
*/
+#if defined(__FreeBSD__)
if (ts1.ts_nsec < 0) {
+#else
+ if (ts1.tv_nsec < 0) {
+#endif
/*
* Allow for the underflow of the
* nanosecond field:
*/
+#if defined(__FreeBSD__)
ts1.ts_sec--;
ts1.ts_nsec += 1000000000;
+#else
+ ts1.tv_sec--;
+ ts1.tv_nsec += 1000000000;
+#endif
}
/*
* Check for overflow of the nanosecond
* field:
*/
+#if defined(__FreeBSD__)
if (ts1.ts_nsec >= 1000000000) {
+#else
+ if (ts1.tv_nsec >= 1000000000) {
+#endif
/*
* Allow for the overflow of the
* nanosecond field:
*/
+#if defined(__FreeBSD__)
ts1.ts_sec++;
ts1.ts_nsec -= 1000000000;
+#else
+ ts1.tv_sec++;
+ ts1.tv_nsec -= 1000000000;
+#endif
}
/*
* Convert the timespec structure to a
@@ -1552,28 +1753,56 @@ _thread_kern_set_timeout(struct timespec * timeout)
* Set the wakeup time to something that can be recognised as
* different to an actual time of day:
*/
+#if defined(__FreeBSD__)
_thread_run->wakeup_time.ts_sec = -1;
_thread_run->wakeup_time.ts_nsec = -1;
+#else
+ _thread_run->wakeup_time.tv_sec = -1;
+ _thread_run->wakeup_time.tv_nsec = -1;
+#endif
}
/* Check if no waiting is required: */
+#if defined(__FreeBSD__)
else if (timeout->ts_sec == 0 && timeout->ts_nsec == 0) {
+#else
+ else if (timeout->tv_sec == 0 && timeout->tv_nsec == 0) {
+#endif
/* Set the wake up time to 'immediately': */
+#if defined(__FreeBSD__)
_thread_run->wakeup_time.ts_sec = 0;
_thread_run->wakeup_time.ts_nsec = 0;
+#else
+ _thread_run->wakeup_time.tv_sec = 0;
+ _thread_run->wakeup_time.tv_nsec = 0;
+#endif
} else {
/* Get the current time: */
gettimeofday(&tv, NULL);
TIMEVAL_TO_TIMESPEC(&tv, &current_time);
/* Calculate the time for the current thread to wake up: */
+#if defined(__FreeBSD__)
_thread_run->wakeup_time.ts_sec = current_time.ts_sec + timeout->ts_sec;
_thread_run->wakeup_time.ts_nsec = current_time.ts_nsec + timeout->ts_nsec;
+#else
+ _thread_run->wakeup_time.tv_sec = current_time.tv_sec + timeout->tv_sec;
+ _thread_run->wakeup_time.tv_nsec = current_time.tv_nsec + timeout->tv_nsec;
+#endif
/* Check if the nanosecond field needs to wrap: */
+#if defined(__FreeBSD__)
if (_thread_run->wakeup_time.ts_nsec >= 1000000000) {
+#else
+ if (_thread_run->wakeup_time.tv_nsec >= 1000000000) {
+#endif
/* Wrap the nanosecond field: */
+#if defined(__FreeBSD__)
_thread_run->wakeup_time.ts_sec += 1;
_thread_run->wakeup_time.ts_nsec -= 1000000000;
+#else
+ _thread_run->wakeup_time.tv_sec += 1;
+ _thread_run->wakeup_time.tv_nsec -= 1000000000;
+#endif
}
}
return;
OpenPOWER on IntegriCloud