int    pthread_attr_setcreatesuspend_np(pthread_attr_t *);
int    pthread_suspend_np(pthread_t);
int    pthread_resume_np(pthread_t);

needed for java. Approved and fixed by cl.
This commit is contained in:
christos 2003-11-09 18:56:48 +00:00
parent 146396081b
commit 38b1c6f405
6 changed files with 124 additions and 13 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: pthread.c,v 1.29 2003/08/13 18:52:01 nathanw Exp $ */
/* $NetBSD: pthread.c,v 1.30 2003/11/09 18:56:48 christos Exp $ */
/*-
* Copyright (c) 2001,2002,2003 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: pthread.c,v 1.29 2003/08/13 18:52:01 nathanw Exp $");
__RCSID("$NetBSD: pthread.c,v 1.30 2003/11/09 18:56:48 christos Exp $");
#include <err.h>
#include <errno.h>
@ -87,6 +87,7 @@ static int pthread__diagassert = DIAGASSERT_ABORT | DIAGASSERT_STDERR;
pthread_spin_t pthread__runqueue_lock;
struct pthread_queue_t pthread__runqueue;
struct pthread_queue_t pthread__idlequeue;
struct pthread_queue_t pthread__suspqueue;
__strong_alias(__libc_thr_self,pthread_self)
__strong_alias(__libc_thr_create,pthread_create)
@ -355,8 +356,13 @@ pthread_create(pthread_t *thread, const pthread_attr_t *attr,
pthread_spinunlock(self, &pthread__allqueue_lock);
SDPRINTF(("(pthread_create %p) Created new thread %p (name pointer %p).\n", self, newthread, newthread->pt_name));
/* 6. Put on run queue. */
pthread__sched(self, newthread);
/* 6. Put on appropriate queue. */
if (newthread->pt_flags & PT_FLAG_SUSPENDED) {
pthread_spinlock(self, &newthread->pt_statelock);
pthread__suspend(self, newthread);
pthread_spinunlock(self, &newthread->pt_statelock);
} else
pthread__sched(self, newthread);
*thread = newthread;
@ -377,6 +383,67 @@ pthread__create_tramp(void *(*start)(void *), void *arg)
pthread__abort();
}
int
pthread_suspend_np(pthread_t thread)
{
pthread_t self = pthread__self();
if (self == thread) {
fprintf(stderr, "suspend_np: can't suspend self\n");
return EDEADLK;
}
SDPRINTF(("(pthread_suspend_np %p) Suspend thread %p (state %d).\n",
self, thread, thread->pt_state));
pthread_spinlock(self, &thread->pt_statelock);
switch (thread->pt_state) {
case PT_STATE_RUNNING:
pthread__abort(); /* XXX */
break;
case PT_STATE_SUSPENDED:
pthread_spinunlock(self, &thread->pt_statelock);
return 0;
case PT_STATE_RUNNABLE:
pthread_spinlock(self, &pthread__runqueue_lock);
PTQ_REMOVE(&pthread__runqueue, thread, pt_runq);
pthread_spinunlock(self, &pthread__runqueue_lock);
break;
case PT_STATE_BLOCKED_QUEUE:
pthread_spinlock(self, thread->pt_sleeplock);
PTQ_REMOVE(thread->pt_sleepq, thread, pt_sleep);
pthread_spinunlock(self, thread->pt_sleeplock);
break;
case PT_STATE_BLOCKED_SYS:
/* XXX flaglock? */
thread->pt_flags |= PT_FLAG_SUSPENDED;
pthread_spinunlock(self, &thread->pt_statelock);
return 0;
default:
break; /* XXX */
}
pthread__suspend(self, thread);
pthread_spinunlock(self, &thread->pt_statelock);
return 0;
}
int
pthread_resume_np(pthread_t thread)
{
pthread_t self = pthread__self();
SDPRINTF(("(pthread_resume_np %p) Resume thread %p (state %d).\n",
self, thread, thread->pt_state));
pthread_spinlock(self, &thread->pt_statelock);
/* XXX flaglock? */
thread->pt_flags &= ~PT_FLAG_SUSPENDED;
if (thread->pt_state == PT_STATE_SUSPENDED) {
pthread_spinlock(self, &pthread__runqueue_lock);
PTQ_REMOVE(&pthread__suspqueue, thread, pt_runq);
pthread_spinunlock(self, &pthread__runqueue_lock);
pthread__sched(self, thread);
}
pthread_spinunlock(self, &thread->pt_statelock);
return 0;
}
/*
* Other threads will switch to the idle thread so that they

View File

@ -1,4 +1,4 @@
/* $NetBSD: pthread.h,v 1.14 2003/07/18 22:01:47 nathanw Exp $ */
/* $NetBSD: pthread.h,v 1.15 2003/11/09 18:56:48 christos Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@ -119,6 +119,10 @@ void pthread_testcancel(void);
int pthread_getname_np(pthread_t, char *, size_t);
int pthread_setname_np(pthread_t, const char *, void *);
int pthread_attr_setcreatesuspend_np(pthread_attr_t *);
int pthread_suspend_np(pthread_t);
int pthread_resume_np(pthread_t);
struct pthread_cleanup_store {
void *pad[4];
};

View File

@ -1,4 +1,4 @@
/* $NetBSD: pthread_attr.c,v 1.2 2003/09/11 21:51:57 christos Exp $ */
/* $NetBSD: pthread_attr.c,v 1.3 2003/11/09 18:56:48 christos Exp $ */
/*-
* Copyright (c) 2001,2002,2003 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: pthread_attr.c,v 1.2 2003/09/11 21:51:57 christos Exp $");
__RCSID("$NetBSD: pthread_attr.c,v 1.3 2003/11/09 18:56:48 christos Exp $");
#include <errno.h>
#include <stdio.h>
@ -397,3 +397,10 @@ pthread_attr_setname_np(pthread_attr_t *attr, const char *name, void *arg)
return 0;
}
int
pthread_attr_setcreatesuspend_np(pthread_attr_t *attr)
{
attr->pta_flags |= PT_FLAG_SUSPENDED;
return 0;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: pthread_int.h,v 1.19 2003/09/12 00:37:17 christos Exp $ */
/* $NetBSD: pthread_int.h,v 1.20 2003/11/09 18:56:48 christos Exp $ */
/*-
* Copyright (c) 2001,2002,2003 The NetBSD Foundation, Inc.
@ -183,6 +183,7 @@ struct pthread_lock_ops {
#define PT_STATE_BLOCKED_QUEUE 4
#define PT_STATE_ZOMBIE 5
#define PT_STATE_DEAD 6
#define PT_STATE_SUSPENDED 7
/* Flag values */
@ -194,6 +195,7 @@ struct pthread_lock_ops {
#define PT_FLAG_SIGDEFERRED 0x0020 /* There are signals to take */
#define PT_FLAG_SCOPE_SYSTEM 0x0040
#define PT_FLAG_EXPLICIT_SCHED 0x0080
#define PT_FLAG_SUSPENDED 0x0100 /* In the suspended queue */
#define PT_MAGIC 0x11110001
#define PT_DEAD 0xDEAD0001
@ -228,6 +230,8 @@ void pthread__initthread(pthread_t self, pthread_t t);
/* Go do something else. Don't go back on the run queue */
void pthread__block(pthread_t self, pthread_spin_t* queuelock);
/* Put a thread back on the suspended queue */
void pthread__suspend(pthread_t self, pthread_t thread);
/* Put a thread back on the run queue */
void pthread__sched(pthread_t self, pthread_t thread);
void pthread__sched_sleepers(pthread_t self, struct pthread_queue_t *threadq);

View File

@ -1,4 +1,4 @@
/* $NetBSD: pthread_run.c,v 1.12 2003/09/16 13:51:35 cl Exp $ */
/* $NetBSD: pthread_run.c,v 1.13 2003/11/09 18:56:48 christos Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: pthread_run.c,v 1.12 2003/09/16 13:51:35 cl Exp $");
__RCSID("$NetBSD: pthread_run.c,v 1.13 2003/11/09 18:56:48 christos Exp $");
#include <ucontext.h>
@ -53,6 +53,7 @@ __RCSID("$NetBSD: pthread_run.c,v 1.12 2003/09/16 13:51:35 cl Exp $");
extern pthread_spin_t pthread__runqueue_lock;
extern struct pthread_queue_t pthread__runqueue;
extern struct pthread_queue_t pthread__idlequeue;
extern struct pthread_queue_t pthread__suspqueue;
extern pthread_spin_t pthread__deadqueue_lock;
extern struct pthread_queue_t pthread__reidlequeue;
@ -129,6 +130,22 @@ pthread__next(pthread_t self)
}
/* Put a thread on the suspended queue */
void
pthread__suspend(pthread_t self, pthread_t thread)
{
SDPRINTF(("(sched %p) suspending %p\n", self, thread));
thread->pt_state = PT_STATE_SUSPENDED;
pthread__assert(thread->pt_type == PT_THREAD_NORMAL);
pthread__assert(thread->pt_spinlocks == 0);
pthread_spinlock(self, &pthread__runqueue_lock);
PTQ_INSERT_TAIL(&pthread__suspqueue, thread, pt_runq);
pthread_spinunlock(self, &pthread__runqueue_lock);
/* XXX flaglock? */
thread->pt_flags &= ~PT_FLAG_SUSPENDED;
}
/* Put a thread back on the run queue */
void
pthread__sched(pthread_t self, pthread_t thread)
@ -240,7 +257,11 @@ pthread__sched_bulk(pthread_t self, pthread_t qhead)
SDPRINTF(("(bulk %p) scheduling %p\n", self, qhead));
pthread__assert(PTQ_LAST(&pthread__runqueue, pthread_queue_t) != qhead);
pthread__assert(PTQ_FIRST(&pthread__runqueue) != qhead);
PTQ_INSERT_TAIL(&pthread__runqueue, qhead, pt_runq);
if (qhead->pt_flags & PT_FLAG_SUSPENDED) {
qhead->pt_state = PT_STATE_SUSPENDED;
PTQ_INSERT_TAIL(&pthread__suspqueue, qhead, pt_runq);
} else
PTQ_INSERT_TAIL(&pthread__runqueue, qhead, pt_runq);
} else if (qhead->pt_type == PT_THREAD_IDLE) {
qhead->pt_state = PT_STATE_RUNNABLE;
qhead->pt_flags &= ~PT_FLAG_IDLED;

View File

@ -1,4 +1,4 @@
/* $NetBSD: pthread_sig.c,v 1.23 2003/10/16 13:38:28 yamt Exp $ */
/* $NetBSD: pthread_sig.c,v 1.24 2003/11/09 18:56:48 christos Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: pthread_sig.c,v 1.23 2003/10/16 13:38:28 yamt Exp $");
__RCSID("$NetBSD: pthread_sig.c,v 1.24 2003/11/09 18:56:48 christos Exp $");
/* We're interposing a specific version of the signal interface. */
#define __LIBC12_SOURCE__
@ -72,6 +72,9 @@ extern struct pthread_queue_t pthread__runqueue;
extern pthread_spin_t pthread__allqueue_lock;
extern struct pthread_queue_t pthread__allqueue;
extern pthread_spin_t pthread__suspqueue_lock;
extern struct pthread_queue_t pthread__suspqueue;
static pthread_spin_t pt_sigacts_lock;
static struct sigaction pt_sigacts[_NSIG];
@ -792,6 +795,11 @@ pthread__kill(pthread_t self, pthread_t target, siginfo_t *si)
*/
pthread_spinlock(self, &target->pt_statelock);
switch (target->pt_state) {
case PT_STATE_SUSPENDED:
pthread_spinlock(self, &pthread__runqueue_lock);
PTQ_REMOVE(&pthread__suspqueue, target, pt_runq);
pthread_spinunlock(self, &pthread__runqueue_lock);
break;
case PT_STATE_RUNNABLE:
pthread_spinlock(self, &pthread__runqueue_lock);
PTQ_REMOVE(&pthread__runqueue, target, pt_runq);