Separate thread synchronization from signals in libthr. Instead

use msleep() and wakeup_one().

Discussed with: jhb, peter, tjr
This commit is contained in:
Mike Makonnen 2004-03-27 14:30:43 +00:00
parent 9af414d156
commit 1713a51661
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=127482
5 changed files with 68 additions and 0 deletions

View File

@ -604,3 +604,5 @@
439 UNIMPL extattr_list_link
440 UNIMPL kse_switchin
441 UNIMPL ksem_timedwait
442 MNOPROTO { int thr_suspend(const struct timespec *timeout); }
443 MNOPROTO { int thr_wake(thr_id_t id); }

View File

@ -254,3 +254,64 @@ thr_kill(struct thread *td, struct thr_kill_args *uap)
PROC_UNLOCK(p);
return (error);
}
int
thr_suspend(struct thread *td, struct thr_suspend_args *uap)
/* const struct timespec *timeout */
{
struct timespec ts;
struct timeval tv;
int error;
int hz;
hz = 0;
error = 0;
if (uap->timeout != NULL) {
error = copyin((const void *)uap->timeout, (void *)&ts,
sizeof(struct timespec));
if (error != 0)
return (error);
if (ts.tv_nsec < 0 || ts.tv_nsec > 1000000000)
return (EINVAL);
if (ts.tv_sec == 0 && ts.tv_nsec == 0)
return (ETIMEDOUT);
TIMESPEC_TO_TIMEVAL(&tv, &ts);
hz = tvtohz(&tv);
}
PROC_LOCK(td->td_proc);
mtx_lock_spin(&sched_lock);
if ((td->td_flags & TDF_THRWAKEUP) == 0) {
mtx_unlock_spin(&sched_lock);
error = msleep((void *)td, &td->td_proc->p_mtx,
td->td_priority | PCATCH, "lthr", hz);
mtx_lock_spin(&sched_lock);
}
td->td_flags &= ~TDF_THRWAKEUP;
mtx_unlock_spin(&sched_lock);
PROC_UNLOCK(td->td_proc);
return (error == EWOULDBLOCK ? ETIMEDOUT : error);
}
int
thr_wake(struct thread *td, struct thr_wake_args *uap)
/* thr_id_t id */
{
struct thread *tdsleeper, *ttd;
tdsleeper = ((struct thread *)uap->id);
PROC_LOCK(tdsleeper->td_proc);
FOREACH_THREAD_IN_PROC(tdsleeper->td_proc, ttd) {
if (ttd == tdsleeper)
break;
}
if (ttd == NULL) {
PROC_UNLOCK(tdsleeper->td_proc);
return (ESRCH);
}
mtx_lock_spin(&sched_lock);
tdsleeper->td_flags |= TDF_THRWAKEUP;
mtx_unlock_spin(&sched_lock);
wakeup_one((void *)tdsleeper);
PROC_UNLOCK(tdsleeper->td_proc);
return (0);
}

View File

@ -629,5 +629,7 @@
440 MSTD { int kse_switchin(const struct __mcontext *mcp, \
long val, long *loc); }
441 MNOSTD { int ksem_timedwait(semid_t id, struct timespec *abstime); }
442 MSTD { int thr_suspend(const struct timespec *timeout); }
443 MSTD { int thr_wake(thr_id_t id); }
; Please copy any additions and changes to the following compatability tables:
; sys/compat/freebsd32/syscalls.master

View File

@ -356,6 +356,7 @@ struct thread {
#define TDF_NEEDSIGCHK 0x020000 /* Thread may need signal delivery. */
#define TDF_SA 0x040000 /* A scheduler activation based thread. */
#define TDF_UMTXWAKEUP 0x080000 /* Libthr thread must not sleep on a umtx. */
#define TDF_THRWAKEUP 0x100000 /* Libthr thread must not suspend itself. */
#define TDF_DEADLKTREAT 0x800000 /* Lock aquisition - deadlock treatment. */
/* "private" flags kept in td_pflags */

View File

@ -46,6 +46,8 @@ int thr_create(ucontext_t *ctx, thr_id_t *id, int flags);
int thr_self(thr_id_t *id);
void thr_exit(void);
int thr_kill(thr_id_t id, int sig);
int thr_suspend(const struct timespec *timeout);
int thr_wake(thr_id_t id);
#endif /* !_KERNEL */