Subject: Re: lwp_emuldata
To: Matt Thomas <matt@3am-software.com>
From: Emmanuel Dreyfus <manu@netbsd.org>
List: tech-kern
Date: 12/17/2003 18:09:25
Here is my proposal. It tested it and it works fine, the hooks are invoked as
expected. 

It is the responsability of the emulation layer to call e_lwp_exit for the
last thread on process exit and on exec when appropriate. This lowers the
amount of hooks in MI code to only 2.

I call e_lwp_fork with l2 = NULL on exec if the emulation is different. At
that stage, l1 already has any information we would need, and there is nothing
to copy from l2 since the emulation is different. 

proc_representative_lwp is used in e_proc_exit and e_proc_exec as there should
be only one lwp at that moment.

Comments?

Index: sys/proc.h
===================================================================
RCS file: /cvsroot/src/sys/sys/proc.h,v
retrieving revision 1.182
diff -U4 -r1.182 proc.h
--- sys/proc.h  6 Dec 2003 04:16:33 -0000       1.182
+++ sys/proc.h  17 Dec 2003 16:55:12 -0000
@@ -120,8 +120,10 @@
        void            (*e_proc_exec) __P((struct proc *,
                                            struct exec_package *));
        void            (*e_proc_fork) __P((struct proc *, struct proc *));
        void            (*e_proc_exit) __P((struct proc *));
+       void            (*e_lwp_fork)  __P((struct lwp *, struct lwp *));
+       void            (*e_lwp_exit)  __P((struct lwp *));
 
 #ifdef __HAVE_SYSCALL_INTERN
        void            (*e_syscall_intern) __P((struct proc *));
 #else
cvs server: Diffing kern
Index: kern/kern_exec.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_exec.c,v
retrieving revision 1.178
diff -U4 -r1.178 kern_exec.c
--- kern/kern_exec.c    5 Dec 2003 21:12:43 -0000       1.178
+++ kern/kern_exec.c    17 Dec 2003 16:55:15 -0000
@@ -165,8 +165,10 @@
        setregs,
        NULL,
        NULL,
        NULL,
+       NULL,
+       NULL,
 #ifdef __HAVE_SYSCALL_INTERN
        syscall_intern,
 #else
        syscall,
Index: kern/kern_lwp.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_lwp.c,v
retrieving revision 1.15
diff -U4 -r1.15 kern_lwp.c
--- kern/kern_lwp.c     4 Nov 2003 10:33:15 -0000       1.15
+++ kern/kern_lwp.c     17 Dec 2003 16:55:16 -0000
@@ -514,8 +514,11 @@
        s = proclist_lock_write();
        LIST_INSERT_HEAD(&alllwp, l2, l_list);
        proclist_unlock_write(s);
 
+       if (p2->p_emul->e_lwp_fork)
+               (*p2->p_emul->e_lwp_fork)(l1, l2);
+
        return (0);
 }
 
 
@@ -532,8 +535,11 @@
 
        DPRINTF(("lwp_exit: %d.%d exiting.\n", p->p_pid, l->l_lid));
        DPRINTF((" nlwps: %d nrlwps %d nzlwps: %d\n",
            p->p_nlwps, p->p_nrlwps, p->p_nzlwps));
+
+       if (p->p_emul->e_lwp_exit)
+               (*p->p_emul->e_lwp_exit)(l);
 
        /*
         * If we are the last live LWP in a process, we need to exit
         * the entire process (if that's not already going on). We do
Index: mach_exec.c
===================================================================
RCS file: /cvsroot/src/sys/compat/mach/mach_exec.c,v
retrieving revision 1.44
diff -U4 -r1.44 mach_exec.c
--- mach_exec.c 6 Dec 2003 17:04:50 -0000       1.44
+++ mach_exec.c 17 Dec 2003 17:00:00 -0000
@@ -104,13 +104,14 @@
        NULL,
        NULL,
        NULL,
 #endif
        setregs,
        mach_e_proc_exec,
        mach_e_proc_fork,
        mach_e_proc_exit,
+       mach_e_lwp_fork,
+       mach_e_lwp_exit,
 #ifdef __HAVE_SYSCALL_INTERN
        mach_syscall_intern,
 #else
        syscall,
@@ -194,12 +195,15 @@
 mach_e_proc_exec(p, epp)
        struct proc *p;
        struct exec_package *epp;
 {
        mach_e_proc_init(p, p->p_vmspace);
 
+       if (p->p_emul != epp->ep_es->es_emul)
+               mach_e_lwp_fork(proc_representative_lwp(p), NULL);
+
        return;
 }
 
 void
 mach_e_proc_fork(p, parent)
        struct proc *p;
 {
        struct mach_emuldata *med;
        struct mach_right *mr;
        int i;
 
+       mach_e_lwp_exit(proc_representative_lwp(p));
+
        mach_semaphore_cleanup(p);
 
        med = (struct mach_emuldata *)p->p_emuldata;
 
        lockmgr(&med->med_rightlock, LK_EXCLUSIVE, NULL);
        while ((mr = LIST_FIRST(&med->med_right)) != NULL)

-- 
Emmanuel Dreyfus
Il y a 10 sortes de personnes dans le monde: ceux qui comprennent 
le binaire et ceux qui ne le comprennent pas.
manu@netbsd.org