First attempt with task_suspend/task_resume, but we hit some bugs somewhere
else in our code.
This commit is contained in:
parent
972480b272
commit
0479104b05
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: mach_exec.c,v 1.28 2003/03/29 11:04:08 manu Exp $ */
|
||||
/* $NetBSD: mach_exec.c,v 1.29 2003/04/06 17:58:49 manu Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001-2003 The NetBSD Foundation, Inc.
|
||||
@ -37,7 +37,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: mach_exec.c,v 1.28 2003/03/29 11:04:08 manu Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: mach_exec.c,v 1.29 2003/04/06 17:58:49 manu Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -261,6 +261,7 @@ mach_e_proc_init(p, vmspace)
|
||||
bzero(med->med_exc, sizeof(med->med_exc));
|
||||
|
||||
med->med_dirty_thid = 1;
|
||||
med->med_suspend = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: mach_exec.h,v 1.16 2003/03/29 11:04:09 manu Exp $ */
|
||||
/* $NetBSD: mach_exec.h,v 1.17 2003/04/06 17:58:49 manu Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||
@ -59,6 +59,7 @@ struct mach_emuldata {
|
||||
struct mach_port *med_exc[MACH_EXC_MAX]; /* Exception ports */
|
||||
|
||||
int med_dirty_thid; /* Thread id not yet initialized */
|
||||
int med_suspend; /* Suspend semaphore */
|
||||
|
||||
};
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: mach_namemap.c,v 1.22 2003/04/05 21:18:02 manu Exp $ */
|
||||
/* $NetBSD: mach_namemap.c,v 1.23 2003/04/06 17:58:50 manu Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002-2003 The NetBSD Foundation, Inc.
|
||||
@ -37,7 +37,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: mach_namemap.c,v 1.22 2003/04/05 21:18:02 manu Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: mach_namemap.c,v 1.23 2003/04/06 17:58:50 manu Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
@ -108,6 +108,8 @@ struct mach_subsystem_namemap mach_namemap[] = {
|
||||
{ 3402, mach_task_threads, "task_threads" },
|
||||
{ 3404, mach_ports_lookup, "ports_lookup" },
|
||||
{ 3405, mach_task_info, "task_info" },
|
||||
{ 3407, mach_task_suspend, "task_suspend" },
|
||||
{ 3408, mach_task_resume, "task_resume" },
|
||||
{ 3409, mach_task_get_special_port, "task_get_special_port" },
|
||||
{ 3410, mach_task_set_special_port, "task_set_special_port" },
|
||||
{ 3412, mach_thread_create_running, "thread_create_running" },
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: mach_task.c,v 1.23 2003/04/05 21:18:02 manu Exp $ */
|
||||
/* $NetBSD: mach_task.c,v 1.24 2003/04/06 17:58:50 manu Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002-2003 The NetBSD Foundation, Inc.
|
||||
@ -39,7 +39,7 @@
|
||||
#include "opt_compat_darwin.h"
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: mach_task.c,v 1.23 2003/04/05 21:18:02 manu Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: mach_task.c,v 1.24 2003/04/06 17:58:50 manu Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
@ -479,6 +479,122 @@ mach_task_info(args)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
mach_task_suspend(args)
|
||||
struct mach_trap_args *args;
|
||||
{
|
||||
mach_task_suspend_request_t *req = args->smsg;
|
||||
mach_task_suspend_reply_t *rep = args->rmsg;
|
||||
size_t *msglen = args->rsize;
|
||||
mach_port_t mn;
|
||||
struct mach_right *mr;
|
||||
struct lwp *l;
|
||||
struct proc *p;
|
||||
struct mach_emuldata *med;
|
||||
int s;
|
||||
|
||||
/*
|
||||
* XXX Two bugs when gdb calls this function:
|
||||
* - gdb uses a port it never allocated (apparently)
|
||||
* - this makes mach_right_check panic because of the lock operation
|
||||
* on a draining lock.
|
||||
*/
|
||||
return mach_msg_error(args, 0);
|
||||
|
||||
/* XXX more permission checks nescessary here? */
|
||||
mn = req->req_msgh.msgh_remote_port;
|
||||
if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == 0)
|
||||
return mach_msg_error(args, EINVAL);
|
||||
if ((mr->mr_port == NULL) || (mr->mr_port->mp_recv == NULL)) {
|
||||
#ifdef DEBUG_MACH
|
||||
printf("mach_task_suspend: port = %p, recv = %p\n",
|
||||
mr->mr_port, mr->mr_port->mp_recv);
|
||||
#endif
|
||||
return mach_msg_error(args, EINVAL);
|
||||
}
|
||||
|
||||
l = mr->mr_port->mp_recv->mr_lwp;
|
||||
p = l->l_proc;
|
||||
med = p->p_emuldata;
|
||||
med->med_suspend++; /* XXX Mach also has a per thread semaphore */
|
||||
|
||||
if (p->p_stat == SACTIVE) {
|
||||
sigminusset(&contsigmask, &p->p_sigctx.ps_siglist);
|
||||
SCHED_LOCK(s);
|
||||
p->p_stat = SSTOP;
|
||||
l->l_stat = LSSTOP;
|
||||
p->p_nrlwps--;
|
||||
mi_switch(l, NULL);
|
||||
SCHED_ASSERT_UNLOCKED();
|
||||
splx(s);
|
||||
}
|
||||
|
||||
rep->rep_msgh.msgh_bits =
|
||||
MACH_MSGH_REPLY_LOCAL_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE);
|
||||
rep->rep_msgh.msgh_size = sizeof(*rep) - sizeof(rep->rep_trailer);
|
||||
rep->rep_msgh.msgh_local_port = req->req_msgh.msgh_local_port;
|
||||
rep->rep_msgh.msgh_id = req->req_msgh.msgh_id + 100;
|
||||
rep->rep_trailer.msgh_trailer_size = 8;
|
||||
|
||||
*msglen = sizeof(*rep);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
mach_task_resume(args)
|
||||
struct mach_trap_args *args;
|
||||
{
|
||||
mach_task_resume_request_t *req = args->smsg;
|
||||
mach_task_resume_reply_t *rep = args->rmsg;
|
||||
size_t *msglen = args->rsize;
|
||||
mach_port_t mn;
|
||||
struct mach_right *mr;
|
||||
struct lwp *l;
|
||||
struct proc *p;
|
||||
struct mach_emuldata *med;
|
||||
int s;
|
||||
|
||||
/* XXX more permission checks nescessary here? */
|
||||
mn = req->req_msgh.msgh_remote_port;
|
||||
if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == 0)
|
||||
return mach_msg_error(args, EINVAL);
|
||||
if ((mr->mr_port == NULL) || (mr->mr_port->mp_recv == NULL)) {
|
||||
#ifdef DEBUG_MACH
|
||||
printf("mach_task_resume: port = %p, recv = %p\n",
|
||||
mr->mr_port, mr->mr_port->mp_recv);
|
||||
#endif
|
||||
return mach_msg_error(args, EINVAL);
|
||||
}
|
||||
|
||||
l = mr->mr_port->mp_recv->mr_lwp;
|
||||
p = l->l_proc;
|
||||
med = p->p_emuldata;
|
||||
med->med_suspend--; /* XXX Mach also has a per thread semaphore */
|
||||
if (med->med_suspend > 0)
|
||||
return mach_msg_error(args, 0); /* XXX error code */
|
||||
|
||||
/* XXX We should also wake up the stopped thread... */
|
||||
if (p->p_stat == SSTOP) {
|
||||
sigminusset(&stopsigmask, &p->p_sigctx.ps_siglist);
|
||||
SCHED_LOCK(s);
|
||||
p->p_stat = SACTIVE;
|
||||
SCHED_ASSERT_UNLOCKED();
|
||||
splx(s);
|
||||
}
|
||||
|
||||
rep->rep_msgh.msgh_bits =
|
||||
MACH_MSGH_REPLY_LOCAL_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE);
|
||||
rep->rep_msgh.msgh_size = sizeof(*rep) - sizeof(rep->rep_trailer);
|
||||
rep->rep_msgh.msgh_local_port = req->req_msgh.msgh_local_port;
|
||||
rep->rep_msgh.msgh_id = req->req_msgh.msgh_id + 100;
|
||||
rep->rep_trailer.msgh_trailer_size = 8;
|
||||
|
||||
*msglen = sizeof(*rep);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
mach_sys_task_for_pid(l, v, retval)
|
||||
struct lwp *l;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: mach_task.h,v 1.7 2003/04/05 21:18:02 manu Exp $ */
|
||||
/* $NetBSD: mach_task.h,v 1.8 2003/04/06 17:58:50 manu Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002-2003 The NetBSD Foundation, Inc.
|
||||
@ -192,6 +192,32 @@ typedef struct {
|
||||
mach_msg_trailer_t rep_trailer;
|
||||
} mach_task_info_reply_t;
|
||||
|
||||
/* task_suspend */
|
||||
|
||||
typedef struct {
|
||||
mach_msg_header_t req_msgh;
|
||||
} mach_task_suspend_request_t;
|
||||
|
||||
typedef struct {
|
||||
mach_msg_header_t rep_msgh;
|
||||
mach_ndr_record_t rep_ndr;
|
||||
mach_kern_return_t rep_retval;
|
||||
mach_msg_trailer_t rep_trailer;
|
||||
} mach_task_suspend_reply_t;
|
||||
|
||||
/* task_resume */
|
||||
|
||||
typedef struct {
|
||||
mach_msg_header_t req_msgh;
|
||||
} mach_task_resume_request_t;
|
||||
|
||||
typedef struct {
|
||||
mach_msg_header_t rep_msgh;
|
||||
mach_ndr_record_t rep_ndr;
|
||||
mach_kern_return_t rep_retval;
|
||||
mach_msg_trailer_t rep_trailer;
|
||||
} mach_task_resume_reply_t;
|
||||
|
||||
int mach_task_get_special_port(struct mach_trap_args *);
|
||||
int mach_ports_lookup(struct mach_trap_args *);
|
||||
int mach_task_set_special_port(struct mach_trap_args *);
|
||||
@ -199,5 +225,7 @@ int mach_task_threads(struct mach_trap_args *);
|
||||
int mach_task_get_exception_ports(struct mach_trap_args *);
|
||||
int mach_task_set_exception_ports(struct mach_trap_args *);
|
||||
int mach_task_info(struct mach_trap_args *);
|
||||
int mach_task_suspend(struct mach_trap_args *);
|
||||
int mach_task_resume(struct mach_trap_args *);
|
||||
|
||||
#endif /* _MACH_TASK_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user