Subject: lwp_emuldata
To: None <tech-kern@netbsd.org>
From: Emmanuel Dreyfus <manu@netbsd.org>
List: tech-kern
Date: 12/11/2003 09:22:26
Hi folks

I have the need of per-lwp emuldata for COMPAT_MACH. I have two ideas to
implement it. The first one is the most straightforward, the second one
tries to avoid adding emulation hooks, as this tends to make some
developers unhappy.

First idea:
- Add a l_emuldata field in struct lwp. 
- Add emulation hooks in struct emul to handle lwp_emuldata allocation
and deallocation: e_newlwp and e_lwp_exit. 
- Call the emulation hooks in newlwp() and lwp_exit()  

Second idea:
- Setup a chained list of struct mach_lwp_emuldata in struct
mach_emuldata, one for each thread:

struct mach_lwp_emuldata {
        LIST_ENTRY(mle_list, mach_mle_emuldata) mle_list;
        struct mach_port mle_kernel;    /* lwp kernel port */
        struct proc *mle_p;
        struct lwp *mle_l;              /* may be stale */
        /* more data */ 
}; 

- This struct mach_lwp_emuldata  referencies the thread kernel port (in
Mach each thread has a kernel port, we need that). The thread kernel
port would referece the struct mach_lwp_emuldata from it mp_data field.
  
- The struct mach_port has a reference count that ensures the struct
mach_lwp_emuldata survives after the process death, until nobody
references it anymore.

- On the process exit hook, we can walk the struct mach_lwp_emuldata
list and set mle_p to NULL, so that no stale reference is hold to the
struct proc once the process is destroyed. 

- Since we have no emulation hooks for thread creation and deletion,
each time the struct mach_lwp_emuldata list is accessed on read or
write, we must update it before performing the actual operation. This
means using the mle_p field (which will be always valid, except if the
process died, then it's NULL) to find the process, walk its lwp list and
update the struct mach_lwp_emuldata list (add or remove items).

The only problem I have remaining: what about if a thread is created,
then removed, the  another thread is created? If we did no operation on
the struct mach_lwp_emuldata list between the removal and the second
creation, and if the first and second thread have their struct lwp at
the same address, then we have no way to distinguish them. Is there a
way of avoiding confusing the threads here? It's the only problem I have
with this second idea.

Comments?
 
-- 
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