mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-03 09:00:21 +00:00
Pre-KSE/M3 commit.
this is a low-functionality change that changes the kernel to access the main thread of a process via the linked list of threads rather than assuming that it is embedded in the process. It IS still embeded there but remove all teh code that assumes that in preparation for the next commit which will actually move it out. Reviewed by: peter@freebsd.org, gallatin@cs.duke.edu, benno rice,
This commit is contained in:
parent
3daf63fc50
commit
079b7badea
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=90361
@ -254,7 +254,7 @@ db_stack_trace_cmd(db_expr_t addr, boolean_t have_addr, db_expr_t count, char *m
|
||||
db_printf("pid %d swapped out\n", pid);
|
||||
return;
|
||||
}
|
||||
pcbp = p->p_thread.td_pcb; /* XXXKSE */
|
||||
pcbp = FIRST_THREAD_IN_PROC(p)->td_pcb; /* XXXKSE */
|
||||
addr = (db_expr_t)pcbp->pcb_hw.apcb_ksp;
|
||||
callpc = pcbp->pcb_context[7];
|
||||
frame = addr;
|
||||
|
@ -119,7 +119,7 @@
|
||||
/*
|
||||
* Switch to proc0's PCB.
|
||||
*/
|
||||
ldq t0,thread0 /* get phys addr of pcb */
|
||||
lda t0,thread0 /* get phys addr of pcb */
|
||||
ldq a0,TD_MD_PCBPADDR(t0)
|
||||
SWITCH_CONTEXT
|
||||
|
||||
|
@ -894,17 +894,16 @@ alpha_init(pfn, ptb, bim, bip, biv)
|
||||
|
||||
}
|
||||
|
||||
proc_linkup(&proc0);
|
||||
proc_linkup(&proc0,&proc0.p_ksegrp,&proc0.p_kse,&thread0);
|
||||
/*
|
||||
* Init mapping for u page(s) for proc 0
|
||||
*/
|
||||
proc0uarea = (struct user *)pmap_steal_memory(UAREA_PAGES * PAGE_SIZE);
|
||||
proc0kstack = pmap_steal_memory(KSTACK_PAGES * PAGE_SIZE);
|
||||
proc0.p_uarea = proc0uarea;
|
||||
thread0 = &proc0.p_thread;
|
||||
thread0->td_kstack = proc0kstack;
|
||||
thread0->td_pcb = (struct pcb *)
|
||||
(thread0->td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
|
||||
thread0.td_kstack = proc0kstack;
|
||||
thread0.td_pcb = (struct pcb *)
|
||||
(thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
|
||||
|
||||
/*
|
||||
* Setup the per-CPU data for the bootstrap cpu.
|
||||
@ -917,7 +916,7 @@ alpha_init(pfn, ptb, bim, bip, biv)
|
||||
alpha_pal_wrval((u_int64_t) pcpup);
|
||||
PCPU_GET(next_asn) = 1; /* 0 used for proc0 pmap */
|
||||
#ifdef SMP
|
||||
thread0->td_md.md_kernnest = 1;
|
||||
thread0.td_md.md_kernnest = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -935,20 +934,20 @@ alpha_init(pfn, ptb, bim, bip, biv)
|
||||
* Initialize the rest of proc 0's PCB, and cache its physical
|
||||
* address.
|
||||
*/
|
||||
thread0->td_md.md_pcbpaddr =
|
||||
(struct pcb *)ALPHA_K0SEG_TO_PHYS((vm_offset_t)thread0->td_pcb);
|
||||
thread0.td_md.md_pcbpaddr =
|
||||
(struct pcb *)ALPHA_K0SEG_TO_PHYS((vm_offset_t)thread0.td_pcb);
|
||||
|
||||
/*
|
||||
* Set the kernel sp, reserving space for an (empty) trapframe,
|
||||
* and make proc0's trapframe pointer point to it for sanity.
|
||||
*/
|
||||
thread0->td_frame = (struct trapframe *)thread0->td_pcb - 1;
|
||||
thread0->td_pcb->pcb_hw.apcb_ksp = (u_int64_t)thread0->td_frame;
|
||||
thread0.td_frame = (struct trapframe *)thread0.td_pcb - 1;
|
||||
thread0.td_pcb->pcb_hw.apcb_ksp = (u_int64_t)thread0.td_frame;
|
||||
|
||||
/* Setup curthread so that mutexes work */
|
||||
PCPU_SET(curthread, thread0);
|
||||
PCPU_SET(curthread, &thread0);
|
||||
|
||||
LIST_INIT(&thread0->td_contested);
|
||||
LIST_INIT(&thread0.td_contested);
|
||||
|
||||
/*
|
||||
* Initialise mutexes.
|
||||
@ -2166,6 +2165,6 @@ cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t sz)
|
||||
pcpu->pc_idlepcbphys = vtophys((vm_offset_t) &pcpu->pc_idlepcb);
|
||||
pcpu->pc_idlepcb.apcb_ksp = (u_int64_t)
|
||||
((caddr_t) pcpu + sz - sizeof(struct trapframe));
|
||||
pcpu->pc_idlepcb.apcb_ptbr = thread0->td_pcb->pcb_hw.apcb_ptbr;
|
||||
pcpu->pc_idlepcb.apcb_ptbr = thread0.td_pcb->pcb_hw.apcb_ptbr;
|
||||
pcpu->pc_current_asngen = 1;
|
||||
}
|
||||
|
@ -557,9 +557,9 @@ pmap_bootstrap(vm_offset_t ptaddr, u_int maxasn)
|
||||
* Set up proc0's PCB such that the ptbr points to the right place
|
||||
* and has the kernel pmap's.
|
||||
*/
|
||||
thread0->td_pcb->pcb_hw.apcb_ptbr =
|
||||
thread0.td_pcb->pcb_hw.apcb_ptbr =
|
||||
ALPHA_K0SEG_TO_PHYS((vm_offset_t)Lev1map) >> PAGE_SHIFT;
|
||||
thread0->td_pcb->pcb_hw.apcb_asn = 0;
|
||||
thread0.td_pcb->pcb_hw.apcb_asn = 0;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -315,8 +315,8 @@ hwrpb_restart_setup()
|
||||
p = (struct pcs *)((char *)hwrpb + hwrpb->rpb_pcs_off);
|
||||
p->pcs_flags &= ~PCS_BIP;
|
||||
|
||||
bcopy(&thread0->td_pcb->pcb_hw, p->pcs_hwpcb,
|
||||
sizeof thread0->td_pcb->pcb_hw);
|
||||
bcopy(&thread0.td_pcb->pcb_hw, p->pcs_hwpcb,
|
||||
sizeof thread0.td_pcb->pcb_hw);
|
||||
hwrpb->rpb_vptb = VPTBASE;
|
||||
|
||||
/* when 'c'ontinuing from console halt, do a dump */
|
||||
|
@ -180,8 +180,8 @@ alpha_set_uac(struct thread *td, char *args)
|
||||
if (p->p_pptr) {
|
||||
PROC_LOCK(p->p_pptr);
|
||||
/* XXXKSE which threads? */
|
||||
p->p_pptr->p_thread.td_md.md_flags &= ~MDP_UAC_MASK;
|
||||
p->p_pptr->p_thread.td_md.md_flags |= uac & MDP_UAC_MASK;
|
||||
FIRST_THREAD_IN_PROC(p->p_pptr)->td_md.md_flags &= ~MDP_UAC_MASK;
|
||||
FIRST_THREAD_IN_PROC(p->p_pptr)->td_md.md_flags |= uac & MDP_UAC_MASK;
|
||||
PROC_UNLOCK(p->p_pptr);
|
||||
}
|
||||
PROC_UNLOCK(p);
|
||||
@ -201,7 +201,7 @@ alpha_get_uac(struct thread *td, char *args)
|
||||
if (p->p_pptr) {
|
||||
PROC_LOCK(p->p_pptr);
|
||||
/* XXXKSE which threads? */
|
||||
uac = p->p_pptr->p_thread.td_md.md_flags & MDP_UAC_MASK;
|
||||
uac = FIRST_THREAD_IN_PROC(p->p_pptr)->td_md.md_flags & MDP_UAC_MASK;
|
||||
PROC_UNLOCK(p->p_pptr);
|
||||
PROC_UNLOCK(p);
|
||||
error = copyout(&uac, args, sizeof(uac));
|
||||
|
@ -118,20 +118,19 @@ vm_fault_quick(v, prot)
|
||||
* ready to run and return to user mode.
|
||||
*/
|
||||
void
|
||||
cpu_fork(td1, p2, flags)
|
||||
cpu_fork(td1, p2, td2, flags)
|
||||
register struct thread *td1;
|
||||
register struct proc *p2;
|
||||
register struct thread *td2;
|
||||
int flags;
|
||||
{
|
||||
struct proc *p1;
|
||||
struct thread *td2;
|
||||
struct trapframe *p2tf;
|
||||
|
||||
if ((flags & RFPROC) == 0)
|
||||
return;
|
||||
|
||||
p1 = td1->td_proc;
|
||||
td2 = &p2->p_thread;
|
||||
td2->td_pcb = (struct pcb *)
|
||||
(td2->td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
|
||||
td2->td_md.md_flags = td1->td_md.md_flags & (MDP_FPUSED | MDP_UAC_MASK);
|
||||
|
@ -166,7 +166,7 @@ linux_clone(struct thread *td, struct linux_clone_args *args)
|
||||
PROC_LOCK(p2);
|
||||
p2->p_sigparent = exit_signal;
|
||||
PROC_UNLOCK(p2);
|
||||
p2->p_thread.td_pcb->pcb_hw.apcb_usp = (unsigned long)args->stack;
|
||||
FIRST_THREAD_IN_PROC(p2)->td_pcb->pcb_hw.apcb_usp = (unsigned long)args->stack;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (ldebug(clone))
|
||||
@ -179,7 +179,7 @@ linux_clone(struct thread *td, struct linux_clone_args *args)
|
||||
*/
|
||||
mtx_lock_spin(&sched_lock);
|
||||
p2->p_stat = SRUN;
|
||||
setrunqueue(&p2->p_thread);
|
||||
setrunqueue(FIRST_THREAD_IN_PROC(p2));
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
|
||||
td->td_retval[0] = p2->p_pid;
|
||||
|
@ -153,7 +153,7 @@ exec_linux_imgact_try(imgp)
|
||||
if ((error = exec_shell_imgact(imgp)) == 0) {
|
||||
char *rpath = NULL;
|
||||
|
||||
linux_emul_find(&imgp->proc->p_thread, NULL,
|
||||
linux_emul_find(FIRST_THREAD_IN_PROC(imgp->proc), NULL,
|
||||
imgp->interpreter_name, &rpath, 0);
|
||||
if (rpath != imgp->interpreter_name) {
|
||||
int len = strlen(rpath) + 1;
|
||||
|
@ -137,7 +137,7 @@ exec_osf1_imgact(struct image_params *imgp)
|
||||
ndp = (struct nameidata *)malloc(sizeof(struct nameidata),
|
||||
M_TEMP, M_WAITOK);
|
||||
NDINIT(ndp, LOOKUP, LOCKLEAF | FOLLOW | SAVENAME, UIO_SYSSPACE,
|
||||
"/compat/osf1/sbin/loader", &imgp->proc->p_thread);
|
||||
"/compat/osf1/sbin/loader", FIRST_THREAD_IN_PROC(imgp->proc));
|
||||
error = namei(ndp);
|
||||
if (error) {
|
||||
uprintf("imgact_osf1: can't read /compat/osf1/sbin/loader\n");
|
||||
@ -150,7 +150,7 @@ exec_osf1_imgact(struct image_params *imgp)
|
||||
}
|
||||
imgp->vp = ndp->ni_vp;
|
||||
error = exec_map_first_page(imgp);
|
||||
VOP_UNLOCK(imgp->vp, 0, &imgp->proc->p_thread);
|
||||
VOP_UNLOCK(imgp->vp, 0, FIRST_THREAD_IN_PROC(imgp->proc));
|
||||
osf_auxargs->loader = "/compat/osf1/sbin/loader";
|
||||
}
|
||||
|
||||
@ -249,7 +249,7 @@ exec_osf1_imgact(struct image_params *imgp)
|
||||
free(imgp->auxargs, M_TEMP);
|
||||
if (ndp) {
|
||||
VOP_CLOSE(ndp->ni_vp, FREAD, imgp->proc->p_ucred,
|
||||
&imgp->proc->p_thread);
|
||||
FIRST_THREAD_IN_PROC(imgp->proc));
|
||||
vrele(ndp->ni_vp);
|
||||
}
|
||||
return(error);
|
||||
|
@ -176,31 +176,34 @@ sw1b:
|
||||
#endif
|
||||
|
||||
/* switch address space */
|
||||
movl %cr3,%ebx
|
||||
movl %cr3,%ebx /* The same address space? */
|
||||
cmpl PCB_CR3(%edx),%ebx
|
||||
je 4f
|
||||
je 4f /* Yes, skip all that cruft */
|
||||
#if defined(SWTCH_OPTIM_STATS)
|
||||
decl swtch_optim_stats
|
||||
incl tlb_flush_count
|
||||
#endif
|
||||
movl PCB_CR3(%edx),%ebx
|
||||
movl %ebx,%cr3
|
||||
movl PCB_CR3(%edx),%ebx /* Tell the CPU about the */
|
||||
movl %ebx,%cr3 /* new address space */
|
||||
4:
|
||||
|
||||
movl PCPU(CPUID), %esi
|
||||
cmpl $0, PCB_EXT(%edx) /* has pcb extension? */
|
||||
je 1f
|
||||
je 1f /* If not, use the default */
|
||||
btsl %esi, private_tss /* mark use of private tss */
|
||||
movl PCB_EXT(%edx), %edi /* new tss descriptor */
|
||||
jmp 2f
|
||||
1:
|
||||
jmp 2f /* Load it up */
|
||||
|
||||
/* Update common_tss.tss_esp0 pointer. */
|
||||
1: /* Use the common default TSS instead of our own */
|
||||
/* Set our stack pointer into the TSS, it's set to just */
|
||||
/* below the PCB. In C, common_tss.tss_esp0 = &pcb - 16; */
|
||||
leal -16(%edx), %ebx /* leave space for vm86 */
|
||||
movl %ebx, PCPU(COMMON_TSS) + TSS_ESP0 /* stack is below pcb */
|
||||
movl %ebx, PCPU(COMMON_TSS) + TSS_ESP0
|
||||
|
||||
btrl %esi, private_tss
|
||||
jae 3f
|
||||
/* Test this CPU's bit in the bitmap to see if this */
|
||||
/* CPU was using a private TSS. */
|
||||
btrl %esi, private_tss /* Already using the common? */
|
||||
jae 3f /* if so, skip reloading */
|
||||
PCPU_ADDR(COMMON_TSSD, %edi)
|
||||
2:
|
||||
/* Move correct tss descriptor into GDT slot, then reload tr. */
|
||||
@ -213,7 +216,7 @@ sw1b:
|
||||
ltr %si
|
||||
3:
|
||||
/* Note in vmspace that this cpu is using it. */
|
||||
movl TD_PROC(%ecx),%eax /* XXXKSE proc from thread */
|
||||
movl TD_PROC(%ecx),%eax
|
||||
movl P_VMSPACE(%eax), %ebx
|
||||
movl PCPU(CPUID), %eax
|
||||
btsl %eax, VM_PMAP+PM_ACTIVE(%ebx)
|
||||
@ -302,7 +305,7 @@ badsw2:
|
||||
pushl $sw0_2
|
||||
call panic
|
||||
|
||||
sw0_2: .asciz "cpu_switch: not SRUN"
|
||||
sw0_2: .asciz "cpu_switch: not TDS_RUNQ"
|
||||
|
||||
badsw3:
|
||||
pushl $sw0_3
|
||||
|
@ -337,7 +337,7 @@ db_stack_trace_cmd(addr, have_addr, count, modif)
|
||||
db_printf("pid %d swapped out\n", pid);
|
||||
return;
|
||||
}
|
||||
pcb = p->p_thread.td_pcb; /* XXXKSE */
|
||||
pcb = FIRST_THREAD_IN_PROC(p)->td_pcb; /* XXXKSE */
|
||||
frame = (struct i386_frame *)pcb->pcb_ebp;
|
||||
if (frame == NULL)
|
||||
frame = (struct i386_frame *)
|
||||
|
@ -1658,14 +1658,20 @@ init386(first)
|
||||
#endif
|
||||
struct pcpu *pc;
|
||||
|
||||
proc_linkup(&proc0);
|
||||
|
||||
proc0.p_uarea = proc0uarea;
|
||||
thread0 = &proc0.p_thread;
|
||||
thread0->td_kstack = proc0kstack;
|
||||
thread0->td_pcb = (struct pcb *)
|
||||
(thread0->td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
|
||||
thread0.td_kstack = proc0kstack;
|
||||
thread0.td_pcb = (struct pcb *)
|
||||
(thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
|
||||
atdevbase = ISA_HOLE_START + KERNBASE;
|
||||
|
||||
/*
|
||||
* This may be done better later if it gets more
|
||||
* high level components in it. If so just link td->td_proc
|
||||
* here.
|
||||
*/
|
||||
proc_linkup(&proc0, &proc0.p_ksegrp, &proc0.p_kse, &thread0);
|
||||
|
||||
metadata_missing = 0;
|
||||
if (bootinfo.bi_modulep) {
|
||||
preload_metadata = (caddr_t)bootinfo.bi_modulep + KERNBASE;
|
||||
@ -1721,9 +1727,9 @@ init386(first)
|
||||
PCPU_SET(prvspace, pc);
|
||||
|
||||
/* setup curproc so that mutexes work */
|
||||
PCPU_SET(curthread, thread0);
|
||||
PCPU_SET(curthread, &thread0);
|
||||
|
||||
LIST_INIT(&thread0->td_contested);
|
||||
LIST_INIT(&thread0.td_contested);
|
||||
|
||||
/*
|
||||
* Initialize mutexes.
|
||||
@ -1826,7 +1832,7 @@ init386(first)
|
||||
|
||||
/* make an initial tss so cpu can get interrupt stack on syscall! */
|
||||
/* Note: -16 is so we can grow the trapframe if we came from vm86 */
|
||||
PCPU_SET(common_tss.tss_esp0, thread0->td_kstack +
|
||||
PCPU_SET(common_tss.tss_esp0, thread0.td_kstack +
|
||||
KSTACK_PAGES * PAGE_SIZE - sizeof(struct pcb) - 16);
|
||||
PCPU_SET(common_tss.tss_ss0, GSEL(GDATA_SEL, SEL_KPL));
|
||||
gsel_tss = GSEL(GPROC0_SEL, SEL_KPL);
|
||||
@ -1883,10 +1889,10 @@ init386(first)
|
||||
_udatasel = LSEL(LUDATA_SEL, SEL_UPL);
|
||||
|
||||
/* setup proc 0's pcb */
|
||||
thread0->td_pcb->pcb_flags = 0; /* XXXKSE */
|
||||
thread0->td_pcb->pcb_cr3 = (int)IdlePTD;
|
||||
thread0->td_pcb->pcb_ext = 0;
|
||||
thread0->td_frame = &proc0_tf;
|
||||
thread0.td_pcb->pcb_flags = 0; /* XXXKSE */
|
||||
thread0.td_pcb->pcb_cr3 = (int)IdlePTD;
|
||||
thread0.td_pcb->pcb_ext = 0;
|
||||
thread0.td_frame = &proc0_tf;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -176,31 +176,34 @@ sw1b:
|
||||
#endif
|
||||
|
||||
/* switch address space */
|
||||
movl %cr3,%ebx
|
||||
movl %cr3,%ebx /* The same address space? */
|
||||
cmpl PCB_CR3(%edx),%ebx
|
||||
je 4f
|
||||
je 4f /* Yes, skip all that cruft */
|
||||
#if defined(SWTCH_OPTIM_STATS)
|
||||
decl swtch_optim_stats
|
||||
incl tlb_flush_count
|
||||
#endif
|
||||
movl PCB_CR3(%edx),%ebx
|
||||
movl %ebx,%cr3
|
||||
movl PCB_CR3(%edx),%ebx /* Tell the CPU about the */
|
||||
movl %ebx,%cr3 /* new address space */
|
||||
4:
|
||||
|
||||
movl PCPU(CPUID), %esi
|
||||
cmpl $0, PCB_EXT(%edx) /* has pcb extension? */
|
||||
je 1f
|
||||
je 1f /* If not, use the default */
|
||||
btsl %esi, private_tss /* mark use of private tss */
|
||||
movl PCB_EXT(%edx), %edi /* new tss descriptor */
|
||||
jmp 2f
|
||||
1:
|
||||
jmp 2f /* Load it up */
|
||||
|
||||
/* Update common_tss.tss_esp0 pointer. */
|
||||
1: /* Use the common default TSS instead of our own */
|
||||
/* Set our stack pointer into the TSS, it's set to just */
|
||||
/* below the PCB. In C, common_tss.tss_esp0 = &pcb - 16; */
|
||||
leal -16(%edx), %ebx /* leave space for vm86 */
|
||||
movl %ebx, PCPU(COMMON_TSS) + TSS_ESP0 /* stack is below pcb */
|
||||
movl %ebx, PCPU(COMMON_TSS) + TSS_ESP0
|
||||
|
||||
btrl %esi, private_tss
|
||||
jae 3f
|
||||
/* Test this CPU's bit in the bitmap to see if this */
|
||||
/* CPU was using a private TSS. */
|
||||
btrl %esi, private_tss /* Already using the common? */
|
||||
jae 3f /* if so, skip reloading */
|
||||
PCPU_ADDR(COMMON_TSSD, %edi)
|
||||
2:
|
||||
/* Move correct tss descriptor into GDT slot, then reload tr. */
|
||||
@ -213,7 +216,7 @@ sw1b:
|
||||
ltr %si
|
||||
3:
|
||||
/* Note in vmspace that this cpu is using it. */
|
||||
movl TD_PROC(%ecx),%eax /* XXXKSE proc from thread */
|
||||
movl TD_PROC(%ecx),%eax
|
||||
movl P_VMSPACE(%eax), %ebx
|
||||
movl PCPU(CPUID), %eax
|
||||
btsl %eax, VM_PMAP+PM_ACTIVE(%ebx)
|
||||
@ -302,7 +305,7 @@ badsw2:
|
||||
pushl $sw0_2
|
||||
call panic
|
||||
|
||||
sw0_2: .asciz "cpu_switch: not SRUN"
|
||||
sw0_2: .asciz "cpu_switch: not TDS_RUNQ"
|
||||
|
||||
badsw3:
|
||||
pushl $sw0_3
|
||||
|
@ -117,13 +117,13 @@ vm_fault_quick(v, prot)
|
||||
* ready to run and return to user mode.
|
||||
*/
|
||||
void
|
||||
cpu_fork(td1, p2, flags)
|
||||
cpu_fork(td1, p2, td2, flags)
|
||||
register struct thread *td1;
|
||||
register struct proc *p2;
|
||||
struct thread *td2;
|
||||
int flags;
|
||||
{
|
||||
register struct proc *p1;
|
||||
struct thread *td2;
|
||||
struct pcb *pcb2;
|
||||
struct mdproc *mdp2;
|
||||
#ifdef DEV_NPX
|
||||
@ -131,7 +131,6 @@ cpu_fork(td1, p2, flags)
|
||||
#endif
|
||||
|
||||
p1 = td1->td_proc;
|
||||
td2 = &p2->p_thread;
|
||||
if ((flags & RFPROC) == 0) {
|
||||
if ((flags & RFMEM) == 0) {
|
||||
/* unshare user LDT */
|
||||
|
@ -459,7 +459,8 @@ exec_pecoff_coff_prep_zmagic(struct image_params * imgp,
|
||||
sh = malloc(scnsiz, M_TEMP, M_WAITOK);
|
||||
|
||||
wp = (void *) ((char *) ap + sizeof(struct coff_aouthdr));
|
||||
error = pecoff_read_from(&imgp->proc->p_thread, imgp->vp, peofs + PECOFF_HDR_SIZE,
|
||||
error = pecoff_read_from(FIRST_THREAD_IN_PROC(imgp->proc),
|
||||
imgp->vp, peofs + PECOFF_HDR_SIZE,
|
||||
(caddr_t) sh, scnsiz);
|
||||
if ((error = exec_extract_strings(imgp)) != 0)
|
||||
goto fail;
|
||||
@ -475,8 +476,9 @@ exec_pecoff_coff_prep_zmagic(struct image_params * imgp,
|
||||
continue;
|
||||
if ((sh[i].s_flags & COFF_STYP_TEXT) != 0) {
|
||||
|
||||
error = pecoff_load_section(&imgp->proc->p_thread, vmspace,
|
||||
imgp->vp, sh[i].s_scnptr
|
||||
error = pecoff_load_section(
|
||||
FIRST_THREAD_IN_PROC(imgp->proc),
|
||||
vmspace, imgp->vp, sh[i].s_scnptr
|
||||
,(caddr_t) sh[i].s_vaddr, sh[i].s_paddr, sh[i].s_size
|
||||
,prot);
|
||||
DPRINTF(("ERROR%d\n", error));
|
||||
@ -487,10 +489,12 @@ exec_pecoff_coff_prep_zmagic(struct image_params * imgp,
|
||||
|
||||
}
|
||||
if ((sh[i].s_flags & (COFF_STYP_DATA|COFF_STYP_BSS)) != 0) {
|
||||
if (pecoff_load_section(&imgp->proc->p_thread,
|
||||
vmspace, imgp->vp, sh[i].s_scnptr
|
||||
,(caddr_t) sh[i].s_vaddr, sh[i].s_paddr, sh[i].s_size,
|
||||
prot) != 0)
|
||||
if (pecoff_load_section(
|
||||
FIRST_THREAD_IN_PROC(imgp->proc),
|
||||
vmspace, imgp->vp, sh[i].s_scnptr,
|
||||
(caddr_t) sh[i].s_vaddr,
|
||||
sh[i].s_paddr, sh[i].s_size,
|
||||
prot) != 0)
|
||||
goto fail;
|
||||
data_addr = min(trunc_page(sh[i].s_vaddr), data_addr);
|
||||
dsize = round_page(sh[i].s_vaddr + sh[i].s_paddr)
|
||||
@ -512,7 +516,8 @@ exec_pecoff_coff_prep_zmagic(struct image_params * imgp,
|
||||
argp->a_entry = wp->w_base + ap->a_entry;
|
||||
argp->a_end = data_addr + data_size;
|
||||
argp->a_subsystem = wp->w_subvers;
|
||||
error = pecoff_load_file(&imgp->proc->p_thread, "/usr/libexec/ld.so.dll", &ldbase, &imgp->entry_addr, &ldexport);
|
||||
error = pecoff_load_file(FIRST_THREAD_IN_PROC(imgp->proc),
|
||||
"/usr/libexec/ld.so.dll", &ldbase, &imgp->entry_addr, &ldexport);
|
||||
if (error)
|
||||
goto fail;
|
||||
|
||||
@ -623,14 +628,15 @@ imgact_pecoff(struct image_params * imgp)
|
||||
imgp->image_header;
|
||||
struct coff_filehdr *fp;
|
||||
int error, peofs;
|
||||
error = pecoff_signature(&imgp->proc->p_thread, imgp->vp, dp);
|
||||
error = pecoff_signature(FIRST_THREAD_IN_PROC(imgp->proc),
|
||||
imgp->vp, dp);
|
||||
if (error) {
|
||||
return -1;
|
||||
}
|
||||
peofs = dp->d_peofs + sizeof(signature) - 1;
|
||||
fp = malloc(PECOFF_HDR_SIZE, M_TEMP, M_WAITOK);
|
||||
error = pecoff_read_from(&imgp->proc->p_thread, imgp->vp, peofs, (caddr_t) fp,
|
||||
PECOFF_HDR_SIZE);
|
||||
error = pecoff_read_from(FIRST_THREAD_IN_PROC(imgp->proc),
|
||||
imgp->vp, peofs, (caddr_t) fp, PECOFF_HDR_SIZE);
|
||||
if (error) {
|
||||
free(fp, M_TEMP);
|
||||
return error;
|
||||
|
@ -114,7 +114,7 @@ db_ps(dummy1, dummy2, dummy3, dummy4)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
td = &p->p_thread;
|
||||
td = FIRST_THREAD_IN_PROC(p);
|
||||
if (td->td_wchan) {
|
||||
db_printf(" %6s %8p", td->td_wmesg,
|
||||
(void *)td->td_wchan);
|
||||
|
@ -190,7 +190,7 @@ procfs_control(struct proc *curp, struct proc *p, int op)
|
||||
/*
|
||||
* do single-step fixup if needed
|
||||
*/
|
||||
FIX_SSTEP(&p->p_thread); /* XXXKSE */
|
||||
FIX_SSTEP(FIRST_THREAD_IN_PROC(p)); /* XXXKSE */
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -242,10 +242,11 @@ procfs_control(struct proc *curp, struct proc *p, int op)
|
||||
|
||||
/*
|
||||
* Step. Let the target process execute a single instruction.
|
||||
* What does it mean to single step a threaded program?
|
||||
*/
|
||||
case PROCFS_CTL_STEP:
|
||||
PROC_UNLOCK(p);
|
||||
error = proc_sstep(&p->p_thread); /* XXXKSE */
|
||||
error = proc_sstep(FIRST_THREAD_IN_PROC(p)); /* XXXKSE */
|
||||
PRELE(p);
|
||||
if (error)
|
||||
return (error);
|
||||
@ -299,7 +300,7 @@ procfs_control(struct proc *curp, struct proc *p, int op)
|
||||
|
||||
mtx_lock_spin(&sched_lock);
|
||||
if (p->p_stat == SSTOP)
|
||||
setrunnable(&p->p_thread); /* XXXKSE */
|
||||
setrunnable(FIRST_THREAD_IN_PROC(p)); /* XXXKSE */
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
return (0);
|
||||
}
|
||||
@ -347,12 +348,14 @@ procfs_doprocctl(PFS_FILL_ARGS)
|
||||
printf("procfs: got a sig%s\n", sbuf_data(sb));
|
||||
PROC_LOCK(p);
|
||||
mtx_lock_spin(&sched_lock);
|
||||
|
||||
/* This is very broken XXXKSE */
|
||||
if (TRACE_WAIT_P(td->td_proc, p)) {
|
||||
p->p_xstat = nm->nm_val;
|
||||
#ifdef FIX_SSTEP
|
||||
FIX_SSTEP(&p->p_thread); /* XXXKSE */
|
||||
FIX_SSTEP(FIRST_THREAD_IN_PROC(p)); /* XXXKSE */
|
||||
#endif
|
||||
setrunnable(&p->p_thread); /* XXXKSE */
|
||||
setrunnable(FIRST_THREAD_IN_PROC(p)); /* XXXKSE */
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
} else {
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
|
@ -77,14 +77,14 @@ procfs_doprocdbregs(PFS_FILL_ARGS)
|
||||
if (kl < 0)
|
||||
error = EINVAL;
|
||||
else
|
||||
error = proc_read_dbregs(&p->p_thread, &r); /* XXXKSE */
|
||||
error = proc_read_dbregs(FIRST_THREAD_IN_PROC(p), &r); /* XXXKSE */
|
||||
if (error == 0)
|
||||
error = uiomove(kv, kl, uio);
|
||||
if (error == 0 && uio->uio_rw == UIO_WRITE) {
|
||||
if (p->p_stat != SSTOP)
|
||||
error = EBUSY;
|
||||
else
|
||||
error = proc_write_dbregs(&p->p_thread, &r); /* XXXKSE */
|
||||
error = proc_write_dbregs(FIRST_THREAD_IN_PROC(p), &r); /* XXXKSE */
|
||||
}
|
||||
|
||||
uio->uio_offset = 0;
|
||||
|
@ -76,14 +76,14 @@ procfs_doprocfpregs(PFS_FILL_ARGS)
|
||||
if (kl < 0)
|
||||
error = EINVAL;
|
||||
else
|
||||
error = proc_read_fpregs(&p->p_thread, &r);
|
||||
error = proc_read_fpregs(FIRST_THREAD_IN_PROC(p), &r);
|
||||
if (error == 0)
|
||||
error = uiomove(kv, kl, uio);
|
||||
if (error == 0 && uio->uio_rw == UIO_WRITE) {
|
||||
if (p->p_stat != SSTOP)
|
||||
error = EBUSY;
|
||||
else
|
||||
error = proc_write_fpregs(&p->p_thread, &r);
|
||||
error = proc_write_fpregs(FIRST_THREAD_IN_PROC(p), &r);
|
||||
}
|
||||
PRELE(p);
|
||||
|
||||
|
@ -96,7 +96,7 @@ procfs_ioctl(PFS_IOCTL_ARGS)
|
||||
p->p_step = 0;
|
||||
if (p->p_stat == SSTOP) {
|
||||
p->p_xstat = sig;
|
||||
setrunnable(&p->p_thread);
|
||||
setrunnable(FIRST_THREAD_IN_PROC(p));
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
} else {
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
|
@ -76,14 +76,14 @@ procfs_doprocregs(PFS_FILL_ARGS)
|
||||
if (kl < 0)
|
||||
error = EINVAL;
|
||||
else
|
||||
error = proc_read_regs(&p->p_thread, &r); /* XXXKSE */
|
||||
error = proc_read_regs(FIRST_THREAD_IN_PROC(p), &r); /* XXXKSE */
|
||||
if (error == 0)
|
||||
error = uiomove(kv, kl, uio);
|
||||
if (error == 0 && uio->uio_rw == UIO_WRITE) {
|
||||
if (p->p_stat != SSTOP)
|
||||
error = EBUSY;
|
||||
else
|
||||
error = proc_write_regs(&p->p_thread, &r); /* XXXKSE */
|
||||
error = proc_write_regs(FIRST_THREAD_IN_PROC(p), &r); /* XXXKSE */
|
||||
}
|
||||
PRELE(p);
|
||||
|
||||
|
@ -127,9 +127,11 @@ procfs_doprocstatus(PFS_FILL_ARGS)
|
||||
if (p->p_flag & P_KSES) {
|
||||
sbuf_printf(sb, " %s", "-kse- ");
|
||||
} else {
|
||||
struct thread *td;
|
||||
td = FIRST_THREAD_IN_PROC(p);
|
||||
sbuf_printf(sb, " %s",
|
||||
(p->p_thread.td_wchan && p->p_thread.td_wmesg) ?
|
||||
p->p_thread.td_wmesg : "nochan");
|
||||
(td->td_wchan && td->td_wmesg) ?
|
||||
td->td_wmesg : "nochan");
|
||||
}
|
||||
|
||||
cr = p->p_ucred;
|
||||
|
@ -337,7 +337,7 @@ db_stack_trace_cmd(addr, have_addr, count, modif)
|
||||
db_printf("pid %d swapped out\n", pid);
|
||||
return;
|
||||
}
|
||||
pcb = p->p_thread.td_pcb; /* XXXKSE */
|
||||
pcb = FIRST_THREAD_IN_PROC(p)->td_pcb; /* XXXKSE */
|
||||
frame = (struct i386_frame *)pcb->pcb_ebp;
|
||||
if (frame == NULL)
|
||||
frame = (struct i386_frame *)
|
||||
|
@ -1658,14 +1658,20 @@ init386(first)
|
||||
#endif
|
||||
struct pcpu *pc;
|
||||
|
||||
proc_linkup(&proc0);
|
||||
|
||||
proc0.p_uarea = proc0uarea;
|
||||
thread0 = &proc0.p_thread;
|
||||
thread0->td_kstack = proc0kstack;
|
||||
thread0->td_pcb = (struct pcb *)
|
||||
(thread0->td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
|
||||
thread0.td_kstack = proc0kstack;
|
||||
thread0.td_pcb = (struct pcb *)
|
||||
(thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
|
||||
atdevbase = ISA_HOLE_START + KERNBASE;
|
||||
|
||||
/*
|
||||
* This may be done better later if it gets more
|
||||
* high level components in it. If so just link td->td_proc
|
||||
* here.
|
||||
*/
|
||||
proc_linkup(&proc0, &proc0.p_ksegrp, &proc0.p_kse, &thread0);
|
||||
|
||||
metadata_missing = 0;
|
||||
if (bootinfo.bi_modulep) {
|
||||
preload_metadata = (caddr_t)bootinfo.bi_modulep + KERNBASE;
|
||||
@ -1721,9 +1727,9 @@ init386(first)
|
||||
PCPU_SET(prvspace, pc);
|
||||
|
||||
/* setup curproc so that mutexes work */
|
||||
PCPU_SET(curthread, thread0);
|
||||
PCPU_SET(curthread, &thread0);
|
||||
|
||||
LIST_INIT(&thread0->td_contested);
|
||||
LIST_INIT(&thread0.td_contested);
|
||||
|
||||
/*
|
||||
* Initialize mutexes.
|
||||
@ -1826,7 +1832,7 @@ init386(first)
|
||||
|
||||
/* make an initial tss so cpu can get interrupt stack on syscall! */
|
||||
/* Note: -16 is so we can grow the trapframe if we came from vm86 */
|
||||
PCPU_SET(common_tss.tss_esp0, thread0->td_kstack +
|
||||
PCPU_SET(common_tss.tss_esp0, thread0.td_kstack +
|
||||
KSTACK_PAGES * PAGE_SIZE - sizeof(struct pcb) - 16);
|
||||
PCPU_SET(common_tss.tss_ss0, GSEL(GDATA_SEL, SEL_KPL));
|
||||
gsel_tss = GSEL(GPROC0_SEL, SEL_KPL);
|
||||
@ -1883,10 +1889,10 @@ init386(first)
|
||||
_udatasel = LSEL(LUDATA_SEL, SEL_UPL);
|
||||
|
||||
/* setup proc 0's pcb */
|
||||
thread0->td_pcb->pcb_flags = 0; /* XXXKSE */
|
||||
thread0->td_pcb->pcb_cr3 = (int)IdlePTD;
|
||||
thread0->td_pcb->pcb_ext = 0;
|
||||
thread0->td_frame = &proc0_tf;
|
||||
thread0.td_pcb->pcb_flags = 0; /* XXXKSE */
|
||||
thread0.td_pcb->pcb_cr3 = (int)IdlePTD;
|
||||
thread0.td_pcb->pcb_ext = 0;
|
||||
thread0.td_frame = &proc0_tf;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -176,31 +176,34 @@ sw1b:
|
||||
#endif
|
||||
|
||||
/* switch address space */
|
||||
movl %cr3,%ebx
|
||||
movl %cr3,%ebx /* The same address space? */
|
||||
cmpl PCB_CR3(%edx),%ebx
|
||||
je 4f
|
||||
je 4f /* Yes, skip all that cruft */
|
||||
#if defined(SWTCH_OPTIM_STATS)
|
||||
decl swtch_optim_stats
|
||||
incl tlb_flush_count
|
||||
#endif
|
||||
movl PCB_CR3(%edx),%ebx
|
||||
movl %ebx,%cr3
|
||||
movl PCB_CR3(%edx),%ebx /* Tell the CPU about the */
|
||||
movl %ebx,%cr3 /* new address space */
|
||||
4:
|
||||
|
||||
movl PCPU(CPUID), %esi
|
||||
cmpl $0, PCB_EXT(%edx) /* has pcb extension? */
|
||||
je 1f
|
||||
je 1f /* If not, use the default */
|
||||
btsl %esi, private_tss /* mark use of private tss */
|
||||
movl PCB_EXT(%edx), %edi /* new tss descriptor */
|
||||
jmp 2f
|
||||
1:
|
||||
jmp 2f /* Load it up */
|
||||
|
||||
/* Update common_tss.tss_esp0 pointer. */
|
||||
1: /* Use the common default TSS instead of our own */
|
||||
/* Set our stack pointer into the TSS, it's set to just */
|
||||
/* below the PCB. In C, common_tss.tss_esp0 = &pcb - 16; */
|
||||
leal -16(%edx), %ebx /* leave space for vm86 */
|
||||
movl %ebx, PCPU(COMMON_TSS) + TSS_ESP0 /* stack is below pcb */
|
||||
movl %ebx, PCPU(COMMON_TSS) + TSS_ESP0
|
||||
|
||||
btrl %esi, private_tss
|
||||
jae 3f
|
||||
/* Test this CPU's bit in the bitmap to see if this */
|
||||
/* CPU was using a private TSS. */
|
||||
btrl %esi, private_tss /* Already using the common? */
|
||||
jae 3f /* if so, skip reloading */
|
||||
PCPU_ADDR(COMMON_TSSD, %edi)
|
||||
2:
|
||||
/* Move correct tss descriptor into GDT slot, then reload tr. */
|
||||
@ -213,7 +216,7 @@ sw1b:
|
||||
ltr %si
|
||||
3:
|
||||
/* Note in vmspace that this cpu is using it. */
|
||||
movl TD_PROC(%ecx),%eax /* XXXKSE proc from thread */
|
||||
movl TD_PROC(%ecx),%eax
|
||||
movl P_VMSPACE(%eax), %ebx
|
||||
movl PCPU(CPUID), %eax
|
||||
btsl %eax, VM_PMAP+PM_ACTIVE(%ebx)
|
||||
@ -302,7 +305,7 @@ badsw2:
|
||||
pushl $sw0_2
|
||||
call panic
|
||||
|
||||
sw0_2: .asciz "cpu_switch: not SRUN"
|
||||
sw0_2: .asciz "cpu_switch: not TDS_RUNQ"
|
||||
|
||||
badsw3:
|
||||
pushl $sw0_3
|
||||
|
@ -117,13 +117,13 @@ vm_fault_quick(v, prot)
|
||||
* ready to run and return to user mode.
|
||||
*/
|
||||
void
|
||||
cpu_fork(td1, p2, flags)
|
||||
cpu_fork(td1, p2, td2, flags)
|
||||
register struct thread *td1;
|
||||
register struct proc *p2;
|
||||
struct thread *td2;
|
||||
int flags;
|
||||
{
|
||||
register struct proc *p1;
|
||||
struct thread *td2;
|
||||
struct pcb *pcb2;
|
||||
struct mdproc *mdp2;
|
||||
#ifdef DEV_NPX
|
||||
@ -131,7 +131,6 @@ cpu_fork(td1, p2, flags)
|
||||
#endif
|
||||
|
||||
p1 = td1->td_proc;
|
||||
td2 = &p2->p_thread;
|
||||
if ((flags & RFPROC) == 0) {
|
||||
if ((flags & RFMEM) == 0) {
|
||||
/* unshare user LDT */
|
||||
|
@ -394,10 +394,12 @@ exec_coff_imgact(imgp)
|
||||
DPRINTF(("%s(%d): shared library %s\n",
|
||||
__FILE__, __LINE__, libname));
|
||||
strcpy(&libbuf[emul_path_len], libname);
|
||||
/* XXXKSE only 1:1 in coff */ error = coff_load_file(&imgp->proc->p_thread, libbuf);
|
||||
/* XXXKSE only 1:1 in coff */ error = coff_load_file(
|
||||
FIRST_THREAD_IN_PROC(imgp->proc), libbuf);
|
||||
if (error)
|
||||
error = coff_load_file(&imgp->proc->p_thread,
|
||||
libname);
|
||||
error = coff_load_file(
|
||||
FIRST_THREAD_IN_PROC(imgp->proc),
|
||||
libname);
|
||||
if (error)
|
||||
break;
|
||||
}
|
||||
|
@ -348,7 +348,8 @@ linux_clone(struct thread *td, struct linux_clone_args *args)
|
||||
|
||||
PROC_LOCK(p2);
|
||||
p2->p_sigparent = exit_signal;
|
||||
p2->p_thread.td_frame->tf_esp = (unsigned int)args->stack;
|
||||
FIRST_THREAD_IN_PROC(p2)->td_frame->tf_esp =
|
||||
(unsigned int)args->stack;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (ldebug(clone))
|
||||
@ -361,7 +362,7 @@ linux_clone(struct thread *td, struct linux_clone_args *args)
|
||||
*/
|
||||
mtx_lock_spin(&sched_lock);
|
||||
p2->p_stat = SRUN;
|
||||
setrunqueue(&p2->p_thread);
|
||||
setrunqueue(FIRST_THREAD_IN_PROC(p2));
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
PROC_UNLOCK(p2);
|
||||
}
|
||||
|
@ -784,7 +784,7 @@ exec_linux_imgact_try(imgp)
|
||||
if ((error = exec_shell_imgact(imgp)) == 0) {
|
||||
char *rpath = NULL;
|
||||
|
||||
linux_emul_find(&imgp->proc->p_thread, NULL,
|
||||
linux_emul_find(FIRST_THREAD_IN_PROC(imgp->proc), NULL,
|
||||
imgp->interpreter_name, &rpath, 0);
|
||||
if (rpath != imgp->interpreter_name) {
|
||||
int len = strlen(rpath) + 1;
|
||||
|
@ -114,8 +114,6 @@ ENTRY(__start, 1)
|
||||
;;
|
||||
movl out0=thread0
|
||||
;;
|
||||
ld8 out0=[out0]
|
||||
;;
|
||||
add out0=TD_PCB,out0
|
||||
;;
|
||||
ld8 out0=[out0]
|
||||
|
@ -114,8 +114,6 @@ ENTRY(__start, 1)
|
||||
;;
|
||||
movl out0=thread0
|
||||
;;
|
||||
ld8 out0=[out0]
|
||||
;;
|
||||
add out0=TD_PCB,out0
|
||||
;;
|
||||
ld8 out0=[out0]
|
||||
|
@ -650,17 +650,16 @@ ia64_init(u_int64_t arg1, u_int64_t arg2)
|
||||
|
||||
}
|
||||
|
||||
proc_linkup(&proc0);
|
||||
proc_linkup(&proc0, &proc0.p_ksegrp, &proc0.p_kse, &thread0);
|
||||
/*
|
||||
* Init mapping for u page(s) for proc 0
|
||||
*/
|
||||
proc0uarea = (struct user *)pmap_steal_memory(UAREA_PAGES * PAGE_SIZE);
|
||||
proc0kstack = (vm_offset_t)kstack;
|
||||
proc0.p_uarea = proc0uarea;
|
||||
thread0 = &proc0.p_thread;
|
||||
thread0->td_kstack = proc0kstack;
|
||||
thread0->td_pcb = (struct pcb *)
|
||||
(thread0->td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
|
||||
thread0.td_kstack = proc0kstack;
|
||||
thread0.td_pcb = (struct pcb *)
|
||||
(thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
|
||||
/*
|
||||
* Setup the global data for the bootstrap cpu.
|
||||
*/
|
||||
@ -682,14 +681,14 @@ ia64_init(u_int64_t arg1, u_int64_t arg2)
|
||||
*
|
||||
* XXX what is all this +/- 16 stuff?
|
||||
*/
|
||||
thread0->td_frame = (struct trapframe *)thread0->td_pcb - 1;
|
||||
thread0->td_pcb->pcb_sp = (u_int64_t)thread0->td_frame - 16;
|
||||
thread0->td_pcb->pcb_bspstore = (u_int64_t)proc0kstack;
|
||||
thread0.td_frame = (struct trapframe *)thread0.td_pcb - 1;
|
||||
thread0.td_pcb->pcb_sp = (u_int64_t)thread0.td_frame - 16;
|
||||
thread0.td_pcb->pcb_bspstore = (u_int64_t)proc0kstack;
|
||||
|
||||
/* Setup curproc so that mutexes work */
|
||||
PCPU_SET(curthread, thread0);
|
||||
PCPU_SET(curthread, &thread0);
|
||||
|
||||
LIST_INIT(&thread0->td_contested);
|
||||
LIST_INIT(&thread0.td_contested);
|
||||
|
||||
/*
|
||||
* Initialise mutexes.
|
||||
|
@ -462,7 +462,7 @@ pmap_bootstrap()
|
||||
* Set up proc0's PCB.
|
||||
*/
|
||||
#if 0
|
||||
thread0->td_pcb->pcb_hw.apcb_asn = 0;
|
||||
thread0.td_pcb->pcb_hw.apcb_asn = 0;
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -124,13 +124,13 @@ struct ia64_fdesc {
|
||||
* ready to run and return to user mode.
|
||||
*/
|
||||
void
|
||||
cpu_fork(td1, p2, flags)
|
||||
cpu_fork(td1, p2, td2, flags)
|
||||
register struct thread *td1;
|
||||
register struct proc *p2;
|
||||
register struct thread *td2;
|
||||
int flags;
|
||||
{
|
||||
struct proc *p1;
|
||||
struct thread *td2;
|
||||
struct trapframe *p2tf;
|
||||
u_int64_t bspstore, *p1bs, *p2bs, rnatloc, rnat;
|
||||
|
||||
@ -138,7 +138,6 @@ cpu_fork(td1, p2, flags)
|
||||
return;
|
||||
|
||||
p1 = td1->td_proc;
|
||||
td2 = &p2->p_thread;
|
||||
td2->td_pcb = (struct pcb *)
|
||||
(td2->td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
|
||||
td2->td_md.md_flags = td1->td_md.md_flags & (MDP_FPUSED | MDP_UAC_MASK);
|
||||
|
@ -82,7 +82,7 @@ void mi_startup(void); /* Should be elsewhere */
|
||||
static struct session session0;
|
||||
static struct pgrp pgrp0;
|
||||
struct proc proc0;
|
||||
struct thread *thread0;
|
||||
struct thread thread0;
|
||||
static struct procsig procsig0;
|
||||
static struct filedesc0 filedesc0;
|
||||
static struct plimit limit0;
|
||||
@ -273,15 +273,12 @@ proc0_init(void *dummy __unused)
|
||||
register struct filedesc0 *fdp;
|
||||
register unsigned i;
|
||||
struct thread *td;
|
||||
struct ksegrp *kg;
|
||||
struct kse *ke;
|
||||
|
||||
GIANT_REQUIRED;
|
||||
/*
|
||||
* This assumes the proc0 struct has already been linked
|
||||
* using proc_linkup() in the machine specific initialisation
|
||||
* e.g. i386_init()
|
||||
*/
|
||||
p = &proc0;
|
||||
td = thread0;
|
||||
td = &thread0;
|
||||
|
||||
/*
|
||||
* Initialize magic number.
|
||||
@ -289,7 +286,7 @@ proc0_init(void *dummy __unused)
|
||||
p->p_magic = P_MAGIC;
|
||||
|
||||
/*
|
||||
* Initialize process and pgrp structures.
|
||||
* Initialize thread, process and pgrp structures.
|
||||
*/
|
||||
procinit();
|
||||
|
||||
@ -323,6 +320,8 @@ proc0_init(void *dummy __unused)
|
||||
p->p_sysent = &aout_sysvec;
|
||||
#endif
|
||||
|
||||
ke = &proc0.p_kse; /* XXXKSE */
|
||||
kg = &proc0.p_ksegrp; /* XXXKSE */
|
||||
p->p_flag = P_SYSTEM;
|
||||
p->p_sflag = PS_INMEM;
|
||||
p->p_stat = SRUN;
|
||||
@ -624,7 +623,7 @@ create_init(const void *udata __unused)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = fork1(thread0, RFFDG | RFPROC | RFSTOPPED, &initproc);
|
||||
error = fork1(&thread0, RFFDG | RFPROC | RFSTOPPED, &initproc);
|
||||
if (error)
|
||||
panic("cannot fork init: %d\n", error);
|
||||
PROC_LOCK(initproc);
|
||||
@ -633,7 +632,7 @@ create_init(const void *udata __unused)
|
||||
mtx_lock_spin(&sched_lock);
|
||||
initproc->p_sflag |= PS_INMEM;
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
cpu_set_fork_handler(&initproc->p_thread, start_init, NULL);
|
||||
cpu_set_fork_handler(FIRST_THREAD_IN_PROC(initproc), start_init, NULL);
|
||||
}
|
||||
SYSINIT(init, SI_SUB_CREATE_INIT, SI_ORDER_FIRST, create_init, NULL)
|
||||
|
||||
@ -643,10 +642,12 @@ SYSINIT(init, SI_SUB_CREATE_INIT, SI_ORDER_FIRST, create_init, NULL)
|
||||
static void
|
||||
kick_init(const void *udata __unused)
|
||||
{
|
||||
struct thread *td;
|
||||
|
||||
td = FIRST_THREAD_IN_PROC(initproc);
|
||||
mtx_lock_spin(&sched_lock);
|
||||
initproc->p_stat = SRUN;
|
||||
setrunqueue(&initproc->p_thread); /* XXXKSE */
|
||||
setrunqueue(FIRST_THREAD_IN_PROC(initproc)); /* XXXKSE */
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
}
|
||||
SYSINIT(kickinit, SI_SUB_KTHREAD_INIT, SI_ORDER_FIRST, kick_init, NULL)
|
||||
|
@ -629,7 +629,7 @@ exec_new_vmspace(imgp)
|
||||
error = vm_map_find(&vmspace->vm_map, 0, 0, &bsaddr,
|
||||
4*PAGE_SIZE, 0,
|
||||
VM_PROT_ALL, VM_PROT_ALL, 0);
|
||||
imgp->proc->p_thread.td_md.md_bspstore = bsaddr;
|
||||
FIRST_THREAD_IN_PROC(imgp->proc)->td_md.md_bspstore = bsaddr;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -239,6 +239,9 @@ fork1(td, flags, procp)
|
||||
struct forklist *ep;
|
||||
struct filedesc *fd;
|
||||
struct proc *p1 = td->td_proc;
|
||||
struct thread *td2;
|
||||
struct kse *ke2;
|
||||
struct ksegrp *kg2;
|
||||
|
||||
GIANT_REQUIRED;
|
||||
|
||||
@ -251,7 +254,7 @@ fork1(td, flags, procp)
|
||||
* certain parts of a process from itself.
|
||||
*/
|
||||
if ((flags & RFPROC) == 0) {
|
||||
vm_forkproc(td, 0, flags);
|
||||
vm_forkproc(td, NULL, NULL, flags);
|
||||
|
||||
/*
|
||||
* Close all file descriptors.
|
||||
@ -414,37 +417,37 @@ fork1(td, flags, procp)
|
||||
LIST_INSERT_HEAD(PIDHASH(p2->p_pid), p2, p_hash);
|
||||
sx_xunlock(&allproc_lock);
|
||||
|
||||
|
||||
/*
|
||||
* Make a proc table entry for the new process.
|
||||
* Start by zeroing the section of proc that is zero-initialized,
|
||||
* then copy the section that is copied directly from the parent.
|
||||
*/
|
||||
td2 = thread_get(p2);
|
||||
ke2 = &p2->p_kse;
|
||||
kg2 = &p2->p_ksegrp;
|
||||
|
||||
#define RANGEOF(type, start, end) (offsetof(type, end) - offsetof(type, start))
|
||||
|
||||
bzero(&p2->p_startzero,
|
||||
(unsigned) ((caddr_t)&p2->p_endzero - (caddr_t)&p2->p_startzero));
|
||||
bzero(&p2->p_kse.ke_startzero,
|
||||
(unsigned) ((caddr_t)&p2->p_kse.ke_endzero
|
||||
- (caddr_t)&p2->p_kse.ke_startzero));
|
||||
bzero(&p2->p_thread.td_startzero,
|
||||
(unsigned) ((caddr_t)&p2->p_thread.td_endzero
|
||||
- (caddr_t)&p2->p_thread.td_startzero));
|
||||
bzero(&p2->p_ksegrp.kg_startzero,
|
||||
(unsigned) ((caddr_t)&p2->p_ksegrp.kg_endzero
|
||||
- (caddr_t)&p2->p_ksegrp.kg_startzero));
|
||||
(unsigned) RANGEOF(struct proc, p_startzero, p_endzero));
|
||||
bzero(&ke2->ke_startzero,
|
||||
(unsigned) RANGEOF(struct kse, ke_startzero, ke_endzero));
|
||||
bzero(&td2->td_startzero,
|
||||
(unsigned) RANGEOF(struct thread, td_startzero, td_endzero));
|
||||
bzero(&kg2->kg_startzero,
|
||||
(unsigned) RANGEOF(struct ksegrp, kg_startzero, kg_endzero));
|
||||
|
||||
PROC_LOCK(p1);
|
||||
bcopy(&p1->p_startcopy, &p2->p_startcopy,
|
||||
(unsigned) ((caddr_t)&p2->p_endcopy - (caddr_t)&p2->p_startcopy));
|
||||
|
||||
bcopy(&p1->p_kse.ke_startcopy, &p2->p_kse.ke_startcopy,
|
||||
(unsigned) ((caddr_t)&p2->p_kse.ke_endcopy
|
||||
- (caddr_t)&p2->p_kse.ke_startcopy));
|
||||
|
||||
bcopy(&p1->p_thread.td_startcopy, &p2->p_thread.td_startcopy,
|
||||
(unsigned) ((caddr_t)&p2->p_thread.td_endcopy
|
||||
- (caddr_t)&p2->p_thread.td_startcopy));
|
||||
|
||||
bcopy(&p1->p_ksegrp.kg_startcopy, &p2->p_ksegrp.kg_startcopy,
|
||||
(unsigned) ((caddr_t)&p2->p_ksegrp.kg_endcopy
|
||||
- (caddr_t)&p2->p_ksegrp.kg_startcopy));
|
||||
(unsigned) RANGEOF(struct proc, p_startcopy, p_endcopy));
|
||||
bcopy(&td->td_kse->ke_startcopy, &ke2->ke_startcopy,
|
||||
(unsigned) RANGEOF(struct kse, ke_startcopy, ke_endcopy));
|
||||
bcopy(&td->td_startcopy, &td2->td_startcopy,
|
||||
(unsigned) RANGEOF(struct thread, td_startcopy, td_endcopy));
|
||||
bcopy(&td->td_ksegrp->kg_startcopy, &kg2->kg_startcopy,
|
||||
(unsigned) RANGEOF(struct ksegrp, kg_startcopy, kg_endcopy));
|
||||
#undef RANGEOF
|
||||
PROC_UNLOCK(p1);
|
||||
|
||||
/*
|
||||
@ -452,7 +455,7 @@ fork1(td, flags, procp)
|
||||
* Others in the kernel would be 'aborted' in the child.
|
||||
* i.e return E*something*
|
||||
*/
|
||||
proc_linkup(p2);
|
||||
proc_linkup(p2, kg2, ke2, td2);
|
||||
|
||||
mtx_init(&p2->p_mtx, "process lock", MTX_DEF);
|
||||
PROC_LOCK(p2);
|
||||
@ -471,7 +474,7 @@ fork1(td, flags, procp)
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
PROC_LOCK(p1);
|
||||
p2->p_ucred = crhold(p1->p_ucred);
|
||||
p2->p_thread.td_ucred = crhold(p2->p_ucred); /* XXXKSE */
|
||||
td2->td_ucred = crhold(p2->p_ucred); /* XXXKSE */
|
||||
|
||||
if (p2->p_args)
|
||||
p2->p_args->ar_ref++;
|
||||
@ -579,10 +582,10 @@ fork1(td, flags, procp)
|
||||
sx_xunlock(&proctree_lock);
|
||||
PROC_LOCK(p2);
|
||||
LIST_INIT(&p2->p_children);
|
||||
LIST_INIT(&p2->p_thread.td_contested); /* XXXKSE only 1 thread? */
|
||||
LIST_INIT(&td2->td_contested); /* XXXKSE only 1 thread? */
|
||||
|
||||
callout_init(&p2->p_itcallout, 0);
|
||||
callout_init(&p2->p_thread.td_slpcallout, 1); /* XXXKSE */
|
||||
callout_init(&td2->td_slpcallout, 1); /* XXXKSE */
|
||||
|
||||
PROC_LOCK(p1);
|
||||
#ifdef KTRACE
|
||||
@ -623,7 +626,7 @@ fork1(td, flags, procp)
|
||||
* Finish creating the child process. It will return via a different
|
||||
* execution path later. (ie: directly into user mode)
|
||||
*/
|
||||
vm_forkproc(td, p2, flags);
|
||||
vm_forkproc(td, p2, td2, flags);
|
||||
|
||||
if (flags == (RFFDG | RFPROC)) {
|
||||
cnt.v_forks++;
|
||||
@ -659,7 +662,7 @@ fork1(td, flags, procp)
|
||||
if ((flags & RFSTOPPED) == 0) {
|
||||
mtx_lock_spin(&sched_lock);
|
||||
p2->p_stat = SRUN;
|
||||
setrunqueue(&p2->p_thread);
|
||||
setrunqueue(td2);
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ idle_setup(void *dummy)
|
||||
SLIST_FOREACH(pc, &cpuhead, pc_allcpu) {
|
||||
error = kthread_create(idle_proc, NULL, &p,
|
||||
RFSTOPPED | RFHIGHPID, "idle: cpu%d", pc->pc_cpuid);
|
||||
pc->pc_idlethread = &p->p_thread;
|
||||
pc->pc_idlethread = FIRST_THREAD_IN_PROC(p);
|
||||
if (pc->pc_curthread == NULL) {
|
||||
pc->pc_curthread = pc->pc_idlethread;
|
||||
pc->pc_idlethread->td_critnest = 0;
|
||||
@ -54,7 +54,7 @@ idle_setup(void *dummy)
|
||||
#else
|
||||
error = kthread_create(idle_proc, NULL, &p,
|
||||
RFSTOPPED | RFHIGHPID, "idle");
|
||||
PCPU_SET(idlethread, &p->p_thread);
|
||||
PCPU_SET(idlethread, FIRST_THREAD_IN_PROC(p));
|
||||
#endif
|
||||
if (error)
|
||||
panic("idle_setup: kthread_create error %d\n", error);
|
||||
|
@ -197,7 +197,7 @@ ithread_create(struct ithd **ithread, int vector, int flags,
|
||||
free(ithd, M_ITHREAD);
|
||||
return (error);
|
||||
}
|
||||
td = &p->p_thread; /* XXXKSE */
|
||||
td = FIRST_THREAD_IN_PROC(p); /* XXXKSE */
|
||||
td->td_ksegrp->kg_pri.pri_class = PRI_ITHD;
|
||||
td->td_ksegrp->kg_pri.pri_level = PRI_MAX_ITHD;
|
||||
p->p_stat = SWAIT;
|
||||
|
@ -81,7 +81,7 @@ kthread_create(void (*func)(void *), void *arg,
|
||||
if (!proc0.p_stats /* || proc0.p_stats->p_start.tv_sec == 0 */)
|
||||
panic("kthread_create called too soon");
|
||||
|
||||
error = fork1(thread0, RFMEM | RFFDG | RFPROC | RFSTOPPED | flags, &p2);
|
||||
error = fork1(&thread0, RFMEM | RFFDG | RFPROC | RFSTOPPED | flags, &p2);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
@ -102,14 +102,14 @@ kthread_create(void (*func)(void *), void *arg,
|
||||
va_end(ap);
|
||||
|
||||
/* call the processes' main()... */
|
||||
cpu_set_fork_handler(&p2->p_thread, func, arg); /* XXXKSE */
|
||||
cpu_set_fork_handler(FIRST_THREAD_IN_PROC(p2), func, arg);
|
||||
|
||||
/* Delay putting it on the run queue until now. */
|
||||
mtx_lock_spin(&sched_lock);
|
||||
p2->p_sflag |= PS_INMEM;
|
||||
if (!(flags & RFSTOPPED)) {
|
||||
p2->p_stat = SRUN;
|
||||
setrunqueue(&p2->p_thread); /* XXXKSE */
|
||||
setrunqueue(FIRST_THREAD_IN_PROC(p2)); /* XXXKSE */
|
||||
}
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/sysproto.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/filedesc.h>
|
||||
#include <sys/tty.h>
|
||||
@ -111,69 +112,86 @@ procinit()
|
||||
}
|
||||
|
||||
/*
|
||||
* link up a process structure and it's inbuilt threads etc.
|
||||
* Note that we do not link to the proc's ucred here
|
||||
* The thread is linked as if running but no KSE assigned
|
||||
*/
|
||||
static void
|
||||
thread_link(struct thread *td, struct ksegrp *kg)
|
||||
{
|
||||
struct proc *p = kg->kg_proc;
|
||||
|
||||
td->td_proc = p;
|
||||
td->td_ksegrp = kg;
|
||||
td->td_last_kse = NULL;
|
||||
|
||||
TAILQ_INSERT_HEAD(&p->p_threads, td, td_plist);
|
||||
TAILQ_INSERT_HEAD(&kg->kg_threads, td, td_kglist);
|
||||
td->td_critnest = 0;
|
||||
td->td_savecrit = 0;
|
||||
td->td_kse = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* KSE is linked onto the idle queue.
|
||||
*/
|
||||
static void
|
||||
kse_link(struct kse *ke, struct ksegrp *kg)
|
||||
{
|
||||
struct proc *p = kg->kg_proc;
|
||||
|
||||
TAILQ_INSERT_HEAD(&kg->kg_kseq, ke, ke_kglist);
|
||||
kg->kg_kses++;
|
||||
TAILQ_INSERT_HEAD(&kg->kg_iq, ke, ke_kgrlist);
|
||||
ke->ke_proc = p;
|
||||
ke->ke_ksegrp = kg;
|
||||
ke->ke_thread = NULL;
|
||||
ke->ke_oncpu = NOCPU;
|
||||
}
|
||||
|
||||
static void
|
||||
ksegrp_link(struct ksegrp *kg, struct proc *p)
|
||||
{
|
||||
TAILQ_INIT(&kg->kg_threads);
|
||||
TAILQ_INIT(&kg->kg_runq); /* links with td_runq */
|
||||
TAILQ_INIT(&kg->kg_slpq); /* links with td_runq */
|
||||
TAILQ_INIT(&kg->kg_kseq); /* all kses in ksegrp */
|
||||
TAILQ_INIT(&kg->kg_iq); /* all kses in ksegrp */
|
||||
kg->kg_proc = p;
|
||||
/* the following counters are in the -zero- section and may not need clearing */
|
||||
kg->kg_runnable = 0;
|
||||
kg->kg_kses = 0;
|
||||
kg->kg_runq_kses = 0; /* XXXKSE change name */
|
||||
/* link it in now that it's consitant */
|
||||
TAILQ_INSERT_HEAD(&p->p_ksegrps, kg, kg_ksegrp);
|
||||
}
|
||||
|
||||
/*
|
||||
* for a newly created process,
|
||||
* link up a the structure and its initial threads etc.
|
||||
*/
|
||||
void
|
||||
proc_linkup(struct proc *p)
|
||||
proc_linkup(struct proc *p, struct ksegrp *kg,
|
||||
struct kse *ke, struct thread *td)
|
||||
{
|
||||
struct thread *td;
|
||||
TAILQ_INIT(&p->p_ksegrps); /* all ksegrps in proc */
|
||||
TAILQ_INIT(&p->p_threads); /* all threads in proc */
|
||||
|
||||
td = &p->p_thread;
|
||||
ksegrp_link(kg, p);
|
||||
kse_link(ke, kg);
|
||||
thread_link(td, kg);
|
||||
/* link them together for 1:1 */
|
||||
td->td_kse = ke;
|
||||
ke->ke_thread = td;
|
||||
|
||||
/**** lists headed in the proc structure ****/
|
||||
/* ALL KSEGRPs in this process */
|
||||
TAILQ_INIT( &p->p_ksegrps); /* all ksegrps in proc */
|
||||
TAILQ_INSERT_HEAD(&p->p_ksegrps, &p->p_ksegrp, kg_ksegrp);
|
||||
}
|
||||
|
||||
/* All threads in this process (an optimisation) */
|
||||
TAILQ_INIT( &p->p_threads); /* all threads in proc */
|
||||
TAILQ_INSERT_HEAD(&p->p_threads, &p->p_thread, td_plist);
|
||||
/* temporary version is ultra simple while we are in 1:1 mode */
|
||||
struct thread *
|
||||
thread_get(struct proc *p)
|
||||
{
|
||||
struct thread *td = &p->p_xxthread;
|
||||
|
||||
/**** Lists headed in the KSEGROUP structure ****/
|
||||
/* all thread in this ksegroup */
|
||||
TAILQ_INIT( &p->p_ksegrp.kg_threads);
|
||||
TAILQ_INSERT_HEAD(&p->p_ksegrp.kg_threads, &p->p_thread, td_kglist);
|
||||
|
||||
/* All runnable threads not assigned to a particular KSE */
|
||||
/* XXXKSE THIS MAY GO AWAY.. KSEs are never unassigned */
|
||||
TAILQ_INIT( &p->p_ksegrp.kg_runq); /* links with td_runq */
|
||||
|
||||
/* All threads presently not runnable (Thread starts this way) */
|
||||
TAILQ_INIT( &p->p_ksegrp.kg_slpq); /* links with td_runq */
|
||||
TAILQ_INSERT_HEAD(&p->p_ksegrp.kg_slpq, &p->p_thread, td_runq);
|
||||
/*p->p_thread.td_flags &= ~TDF_ONRUNQ;*/
|
||||
|
||||
/* all KSEs in this ksegroup */
|
||||
TAILQ_INIT( &p->p_ksegrp.kg_kseq); /* all kses in ksegrp */
|
||||
TAILQ_INSERT_HEAD(&p->p_ksegrp.kg_kseq, &p->p_kse, ke_kglist);
|
||||
|
||||
/* KSE starts out idle *//* XXXKSE */
|
||||
TAILQ_INIT( &p->p_ksegrp.kg_rq); /* all kses in ksegrp */
|
||||
TAILQ_INIT( &p->p_ksegrp.kg_iq); /* all kses in ksegrp */
|
||||
#if 0
|
||||
TAILQ_INSERT_HEAD(&p->p_ksegrp.kg_iq, &p->p_kse, ke_kgrlist);
|
||||
#endif /* is running, not idle */
|
||||
/*p->p_kse.ke_flags &= &KEF_ONRUNQ;*/
|
||||
|
||||
/**** Lists headed in the KSE structure ****/
|
||||
/* runnable threads assigned to this kse */
|
||||
TAILQ_INIT( &p->p_kse.ke_runq); /* links with td_runq */
|
||||
|
||||
p->p_thread.td_proc = p;
|
||||
p->p_kse.ke_proc = p;
|
||||
p->p_ksegrp.kg_proc = p;
|
||||
|
||||
p->p_thread.td_ksegrp = &p->p_ksegrp;
|
||||
p->p_kse.ke_ksegrp = &p->p_ksegrp;
|
||||
|
||||
p->p_thread.td_last_kse = &p->p_kse;
|
||||
p->p_thread.td_kse = &p->p_kse;
|
||||
|
||||
p->p_kse.ke_thread = &p->p_thread;
|
||||
|
||||
p->p_ksegrp.kg_runnable = 1;
|
||||
p->p_ksegrp.kg_kses = 1;
|
||||
p->p_ksegrp.kg_runq_kses = 1; /* XXXKSE change name */
|
||||
return (td);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -473,6 +491,7 @@ fill_kinfo_proc(p, kp)
|
||||
|
||||
bzero(kp, sizeof(*kp));
|
||||
|
||||
td = FIRST_THREAD_IN_PROC(p);
|
||||
kp->ki_structsize = sizeof(*kp);
|
||||
kp->ki_paddr = p;
|
||||
PROC_LOCK(p);
|
||||
@ -512,6 +531,7 @@ fill_kinfo_proc(p, kp)
|
||||
kp->ki_dsize = vm->vm_dsize;
|
||||
kp->ki_ssize = vm->vm_ssize;
|
||||
}
|
||||
td = FIRST_THREAD_IN_PROC(p);
|
||||
if ((p->p_sflag & PS_INMEM) && p->p_stats) {
|
||||
kp->ki_start = p->p_stats->p_start;
|
||||
kp->ki_rusage = p->p_stats->p_ru;
|
||||
@ -520,11 +540,11 @@ fill_kinfo_proc(p, kp)
|
||||
kp->ki_childtime.tv_usec = p->p_stats->p_cru.ru_utime.tv_usec +
|
||||
p->p_stats->p_cru.ru_stime.tv_usec;
|
||||
}
|
||||
if (p->p_thread.td_wmesg != NULL)
|
||||
strncpy(kp->ki_wmesg, p->p_thread.td_wmesg, sizeof(kp->ki_wmesg) - 1);
|
||||
if (td->td_wmesg != NULL)
|
||||
strncpy(kp->ki_wmesg, td->td_wmesg, sizeof(kp->ki_wmesg) - 1);
|
||||
if (p->p_stat == SMTX) {
|
||||
kp->ki_kiflag |= KI_MTXBLOCK;
|
||||
strncpy(kp->ki_mtxname, p->p_thread.td_mtxname,
|
||||
strncpy(kp->ki_mtxname, td->td_mtxname,
|
||||
sizeof(kp->ki_mtxname) - 1);
|
||||
}
|
||||
kp->ki_stat = p->p_stat;
|
||||
@ -537,15 +557,15 @@ fill_kinfo_proc(p, kp)
|
||||
kp->ki_pctcpu = p->p_kse.ke_pctcpu;
|
||||
kp->ki_estcpu = p->p_ksegrp.kg_estcpu;
|
||||
kp->ki_slptime = p->p_ksegrp.kg_slptime;
|
||||
kp->ki_wchan = p->p_thread.td_wchan;
|
||||
kp->ki_wchan = td->td_wchan;
|
||||
kp->ki_pri = p->p_ksegrp.kg_pri;
|
||||
kp->ki_nice = p->p_ksegrp.kg_nice;
|
||||
kp->ki_rqindex = p->p_kse.ke_rqindex;
|
||||
kp->ki_oncpu = p->p_kse.ke_oncpu;
|
||||
kp->ki_lastcpu = p->p_thread.td_lastcpu;
|
||||
kp->ki_tdflags = p->p_thread.td_flags;
|
||||
kp->ki_pcb = p->p_thread.td_pcb;
|
||||
kp->ki_kstack = (void *)p->p_thread.td_kstack;
|
||||
kp->ki_lastcpu = td->td_lastcpu;
|
||||
kp->ki_tdflags = td->td_flags;
|
||||
kp->ki_pcb = td->td_pcb;
|
||||
kp->ki_kstack = (void *)td->td_kstack;
|
||||
/* ^^^ XXXKSE */
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
sp = NULL;
|
||||
|
@ -242,7 +242,7 @@ boot(int howto)
|
||||
waittime = 0;
|
||||
printf("\nsyncing disks... ");
|
||||
|
||||
sync(thread0, NULL);
|
||||
sync(&thread0, NULL);
|
||||
|
||||
/*
|
||||
* With soft updates, some buffers that are
|
||||
@ -267,12 +267,11 @@ boot(int howto)
|
||||
if (nbusy < pbusy)
|
||||
iter = 0;
|
||||
pbusy = nbusy;
|
||||
sync(thread0, NULL);
|
||||
sync(&thread0, NULL);
|
||||
if (curthread != NULL) {
|
||||
DROP_GIANT();
|
||||
for (subiter = 0; subiter < 50 * iter; subiter++) {
|
||||
mtx_lock_spin(&sched_lock);
|
||||
setrunqueue(curthread);
|
||||
curthread->td_proc->p_stats->p_ru.ru_nvcsw++;
|
||||
mi_switch(); /* Allow interrupt threads to run */
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
|
@ -1270,7 +1270,7 @@ psignal(p, sig)
|
||||
* For now there is one thread per proc.
|
||||
* Effectively select one sucker thread..
|
||||
*/
|
||||
td = &p->p_thread;
|
||||
td = FIRST_THREAD_IN_PROC(p);
|
||||
mtx_lock_spin(&sched_lock);
|
||||
if ((p->p_ksegrp.kg_nice > NZERO) && (action == SIG_DFL) &&
|
||||
(prop & SA_KILL) && ((p->p_flag & P_TRACED) == 0))
|
||||
@ -1411,7 +1411,7 @@ psignal(p, sig)
|
||||
}
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
} else {
|
||||
if (p->p_thread.td_wchan == NULL)
|
||||
if (td->td_wchan == NULL)
|
||||
goto run;
|
||||
p->p_stat = SSLEEP;
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
|
@ -128,7 +128,7 @@ int sched_setparam(struct thread *td,
|
||||
e = ESRCH;
|
||||
goto done2;
|
||||
}
|
||||
targettd = &targetp->p_thread; /* XXXKSE */
|
||||
targettd = FIRST_THREAD_IN_PROC(targetp); /* XXXKSE */
|
||||
}
|
||||
|
||||
e = p_cansched(td->td_proc, targetp);
|
||||
@ -164,7 +164,7 @@ int sched_getparam(struct thread *td,
|
||||
e = ESRCH;
|
||||
goto done2;
|
||||
}
|
||||
targettd = &targetp->p_thread; /* XXXKSE */
|
||||
targettd = FIRST_THREAD_IN_PROC(targetp); /* XXXKSE */
|
||||
}
|
||||
|
||||
e = p_cansee(td->td_proc, targetp);
|
||||
@ -206,7 +206,7 @@ int sched_setscheduler(struct thread *td,
|
||||
e = ESRCH;
|
||||
goto done2;
|
||||
}
|
||||
targettd = &targetp->p_thread; /* XXXKSE */
|
||||
targettd = FIRST_THREAD_IN_PROC(targetp); /* XXXKSE */
|
||||
}
|
||||
|
||||
e = p_cansched(td->td_proc, targetp);
|
||||
@ -241,7 +241,7 @@ int sched_getscheduler(struct thread *td,
|
||||
e = ESRCH;
|
||||
goto done2;
|
||||
}
|
||||
targettd = &targetp->p_thread; /* XXXKSE */
|
||||
targettd = FIRST_THREAD_IN_PROC(targetp); /* XXXKSE */
|
||||
}
|
||||
|
||||
e = p_cansee(td->td_proc, targetp);
|
||||
@ -317,7 +317,7 @@ int sched_rr_get_interval(struct thread *td,
|
||||
e = ESRCH;
|
||||
goto done2;
|
||||
}
|
||||
targettd = &targetp->p_thread; /* XXXKSE */
|
||||
targettd = FIRST_THREAD_IN_PROC(targetp); /* XXXKSE */
|
||||
}
|
||||
|
||||
e = p_cansee(td->td_proc, targetp);
|
||||
|
@ -1463,11 +1463,13 @@ DB_SHOW_COMMAND(locks, db_witness_list)
|
||||
db_printf("pid %d not found\n", pid);
|
||||
return;
|
||||
}
|
||||
td = &p->p_thread; /* XXXKSE */
|
||||
FOREACH_THREAD_IN_PROC(p, td) {
|
||||
witness_list(td);
|
||||
}
|
||||
} else {
|
||||
td = curthread;
|
||||
witness_list(td);
|
||||
}
|
||||
witness_list(td);
|
||||
}
|
||||
|
||||
DB_SHOW_COMMAND(witness, db_witness_display)
|
||||
|
@ -383,7 +383,7 @@ ptrace(struct thread *td, struct ptrace_args *uap)
|
||||
/*
|
||||
* Single step fixup ala procfs
|
||||
*/
|
||||
FIX_SSTEP(&p->p_thread); /* XXXKSE */
|
||||
FIX_SSTEP(FIRST_THREAD_IN_PROC(p)); /* XXXKSE */
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -425,7 +425,7 @@ ptrace(struct thread *td, struct ptrace_args *uap)
|
||||
PHOLD(p);
|
||||
|
||||
if (uap->req == PT_STEP) {
|
||||
if ((error = ptrace_single_step(&p->p_thread))) {
|
||||
if ((error = ptrace_single_step(FIRST_THREAD_IN_PROC(p)))) {
|
||||
PRELE(p);
|
||||
return (error);
|
||||
}
|
||||
@ -433,7 +433,7 @@ ptrace(struct thread *td, struct ptrace_args *uap)
|
||||
|
||||
if (uap->addr != (caddr_t)1) {
|
||||
fill_kinfo_proc(p, &p->p_uarea->u_kproc);
|
||||
if ((error = ptrace_set_pc(&p->p_thread,
|
||||
if ((error = ptrace_set_pc(FIRST_THREAD_IN_PROC(p),
|
||||
(u_long)(uintfptr_t)uap->addr))) {
|
||||
PRELE(p);
|
||||
return (error);
|
||||
@ -472,7 +472,7 @@ ptrace(struct thread *td, struct ptrace_args *uap)
|
||||
mtx_lock_spin(&sched_lock);
|
||||
if (p->p_stat == SSTOP) {
|
||||
p->p_xstat = uap->data;
|
||||
setrunnable(&p->p_thread); /* XXXKSE */
|
||||
setrunnable(FIRST_THREAD_IN_PROC(p)); /* XXXKSE */
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
} else {
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
@ -525,7 +525,7 @@ ptrace(struct thread *td, struct ptrace_args *uap)
|
||||
error = copyin(uap->addr, &r.reg, sizeof r.reg);
|
||||
if (error == 0) {
|
||||
PHOLD(p);
|
||||
error = proc_write_regs(&p->p_thread, &r.reg);
|
||||
error = proc_write_regs(FIRST_THREAD_IN_PROC(p), &r.reg);
|
||||
PRELE(p);
|
||||
}
|
||||
return (error);
|
||||
@ -534,7 +534,7 @@ ptrace(struct thread *td, struct ptrace_args *uap)
|
||||
#ifdef PT_GETREGS
|
||||
case PT_GETREGS:
|
||||
PHOLD(p);
|
||||
error = proc_read_regs(&p->p_thread, &r.reg);
|
||||
error = proc_read_regs(FIRST_THREAD_IN_PROC(p), &r.reg);
|
||||
PRELE(p);
|
||||
if (error == 0)
|
||||
error = copyout(&r.reg, uap->addr, sizeof r.reg);
|
||||
@ -546,7 +546,7 @@ ptrace(struct thread *td, struct ptrace_args *uap)
|
||||
error = copyin(uap->addr, &r.fpreg, sizeof r.fpreg);
|
||||
if (error == 0) {
|
||||
PHOLD(p);
|
||||
error = proc_write_fpregs(&p->p_thread, &r.fpreg);
|
||||
error = proc_write_fpregs(FIRST_THREAD_IN_PROC(p), &r.fpreg);
|
||||
PRELE(p);
|
||||
}
|
||||
return (error);
|
||||
@ -555,7 +555,7 @@ ptrace(struct thread *td, struct ptrace_args *uap)
|
||||
#ifdef PT_GETFPREGS
|
||||
case PT_GETFPREGS:
|
||||
PHOLD(p);
|
||||
error = proc_read_fpregs(&p->p_thread, &r.fpreg);
|
||||
error = proc_read_fpregs(FIRST_THREAD_IN_PROC(p), &r.fpreg);
|
||||
PRELE(p);
|
||||
if (error == 0)
|
||||
error = copyout(&r.fpreg, uap->addr, sizeof r.fpreg);
|
||||
@ -567,7 +567,7 @@ ptrace(struct thread *td, struct ptrace_args *uap)
|
||||
error = copyin(uap->addr, &r.dbreg, sizeof r.dbreg);
|
||||
if (error == 0) {
|
||||
PHOLD(p);
|
||||
error = proc_write_dbregs(&p->p_thread, &r.dbreg);
|
||||
error = proc_write_dbregs(FIRST_THREAD_IN_PROC(p), &r.dbreg);
|
||||
PRELE(p);
|
||||
}
|
||||
return (error);
|
||||
@ -576,7 +576,7 @@ ptrace(struct thread *td, struct ptrace_args *uap)
|
||||
#ifdef PT_GETDBREGS
|
||||
case PT_GETDBREGS:
|
||||
PHOLD(p);
|
||||
error = proc_read_dbregs(&p->p_thread, &r.dbreg);
|
||||
error = proc_read_dbregs(FIRST_THREAD_IN_PROC(p), &r.dbreg);
|
||||
PRELE(p);
|
||||
if (error == 0)
|
||||
error = copyout(&r.dbreg, uap->addr, sizeof r.dbreg);
|
||||
|
@ -2315,6 +2315,7 @@ ttyinfo(tp)
|
||||
const char *stmp;
|
||||
long ltmp;
|
||||
int tmp;
|
||||
struct thread *td;
|
||||
|
||||
if (ttycheckoutq(tp,0) == 0)
|
||||
return;
|
||||
@ -2332,13 +2333,16 @@ ttyinfo(tp)
|
||||
else {
|
||||
mtx_lock_spin(&sched_lock);
|
||||
|
||||
|
||||
/* Pick interesting process. */
|
||||
for (pick = NULL; p != 0; p = LIST_NEXT(p, p_pglist))
|
||||
if (proc_compare(pick, p))
|
||||
pick = p;
|
||||
|
||||
td = FIRST_THREAD_IN_PROC(pick);
|
||||
|
||||
stmp = pick->p_stat == SRUN ? "running" : /* XXXKSE */
|
||||
pick->p_thread.td_wmesg ? pick->p_thread.td_wmesg : "iowait";
|
||||
td->td_wmesg ? td->td_wmesg : "iowait";
|
||||
calcru(pick, &utime, &stime, NULL);
|
||||
ltmp = pick->p_stat == SIDL || pick->p_stat == SWAIT ||
|
||||
pick->p_stat == SZOMB ? 0 :
|
||||
|
@ -430,13 +430,13 @@ aio_free_entry(struct aiocblist *aiocbe)
|
||||
}
|
||||
|
||||
/* aiocbe is going away, we need to destroy any knotes */
|
||||
knote_remove(&p->p_thread, &aiocbe->klist); /* XXXKSE */
|
||||
/* XXXKSE Note the thread here is used to eventually find the
|
||||
* owning process again, but it is also used to do a fo_close
|
||||
* and that requires the thread. (but does it require the
|
||||
* OWNING thread? (or maby the running thread?)
|
||||
* OWNING thread? (or maybe the running thread?)
|
||||
* There is a semantic problem here...
|
||||
*/
|
||||
knote_remove(FIRST_THREAD_IN_PROC(p), &aiocbe->klist); /* XXXKSE */
|
||||
|
||||
if ((ki->kaio_flags & KAIO_WAKEUP) || ((ki->kaio_flags & KAIO_RUNDOWN)
|
||||
&& ((ki->kaio_buffer_count == 0) && (ki->kaio_queue_count == 0)))) {
|
||||
@ -838,7 +838,7 @@ aio_daemon(void *uproc)
|
||||
mycp->p_vmspace->vm_refcnt++;
|
||||
|
||||
/* Activate the new mapping. */
|
||||
pmap_activate(&mycp->p_thread);
|
||||
pmap_activate(FIRST_THREAD_IN_PROC(mycp));
|
||||
|
||||
/*
|
||||
* If the old address space wasn't the daemons
|
||||
@ -949,7 +949,7 @@ aio_daemon(void *uproc)
|
||||
mycp->p_vmspace = myvm;
|
||||
|
||||
/* Activate the daemon's address space. */
|
||||
pmap_activate(&mycp->p_thread);
|
||||
pmap_activate(FIRST_THREAD_IN_PROC(mycp));
|
||||
#ifdef DIAGNOSTIC
|
||||
if (tmpvm == myvm) {
|
||||
printf("AIOD: vmspace problem -- %d\n",
|
||||
|
@ -991,8 +991,6 @@ chroot_refuse_vdir_fds(fdp)
|
||||
{
|
||||
struct vnode *vp;
|
||||
struct file *fp;
|
||||
struct thread *td = curthread;
|
||||
int error;
|
||||
int fd;
|
||||
|
||||
FILEDESC_LOCK(fdp);
|
||||
|
@ -602,7 +602,7 @@ vnlru_proc(void)
|
||||
int s;
|
||||
int done;
|
||||
struct proc *p = vnlruproc;
|
||||
struct thread *td = &p->p_thread; /* XXXKSE */
|
||||
struct thread *td = FIRST_THREAD_IN_PROC(p); /* XXXKSE */
|
||||
|
||||
mtx_lock(&Giant);
|
||||
|
||||
@ -1217,7 +1217,7 @@ sched_sync(void)
|
||||
struct mount *mp;
|
||||
long starttime;
|
||||
int s;
|
||||
struct thread *td = &updateproc->p_thread; /* XXXKSE */
|
||||
struct thread *td = FIRST_THREAD_IN_PROC(updateproc); /* XXXKSE */
|
||||
|
||||
mtx_lock(&Giant);
|
||||
|
||||
@ -1315,8 +1315,8 @@ speedup_syncer()
|
||||
{
|
||||
|
||||
mtx_lock_spin(&sched_lock);
|
||||
if (updateproc->p_thread.td_wchan == &lbolt) /* XXXKSE */
|
||||
setrunnable(&updateproc->p_thread);
|
||||
if (FIRST_THREAD_IN_PROC(updateproc)->td_wchan == &lbolt) /* XXXKSE */
|
||||
setrunnable(FIRST_THREAD_IN_PROC(updateproc));
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
if (rushjob < syncdelay / 2) {
|
||||
rushjob += 1;
|
||||
@ -2560,7 +2560,8 @@ vfs_unmountall()
|
||||
if (curthread != NULL)
|
||||
td = curthread;
|
||||
else
|
||||
td = &initproc->p_thread; /* XXX XXX should this be proc0? */
|
||||
/* XXX XXX should this be proc0? */
|
||||
td = FIRST_THREAD_IN_PROC(initproc);
|
||||
/*
|
||||
* Since this only runs when rebooting, it is not interlocked.
|
||||
*/
|
||||
|
@ -991,8 +991,6 @@ chroot_refuse_vdir_fds(fdp)
|
||||
{
|
||||
struct vnode *vp;
|
||||
struct file *fp;
|
||||
struct thread *td = curthread;
|
||||
int error;
|
||||
int fd;
|
||||
|
||||
FILEDESC_LOCK(fdp);
|
||||
|
@ -549,7 +549,7 @@ ng_ksocket_constructor(node_p node)
|
||||
static int
|
||||
ng_ksocket_newhook(node_p node, hook_p hook, const char *name0)
|
||||
{
|
||||
struct thread *td = curthread ? curthread : thread0; /* XXX broken */
|
||||
struct thread *td = curthread ? curthread : &thread0; /* XXX broken */
|
||||
const priv_p priv = NG_NODE_PRIVATE(node);
|
||||
char *s1, *s2, name[NG_HOOKLEN+1];
|
||||
int family, type, protocol, error;
|
||||
@ -658,7 +658,7 @@ ng_ksocket_connect(hook_p hook)
|
||||
static int
|
||||
ng_ksocket_rcvmsg(node_p node, item_p item, hook_p lasthook)
|
||||
{
|
||||
struct thread *td = curthread ? curthread : thread0; /* XXX broken */
|
||||
struct thread *td = curthread ? curthread : &thread0; /* XXX broken */
|
||||
const priv_p priv = NG_NODE_PRIVATE(node);
|
||||
struct socket *const so = priv->so;
|
||||
struct ng_mesg *resp = NULL;
|
||||
@ -883,7 +883,7 @@ ng_ksocket_rcvmsg(node_p node, item_p item, hook_p lasthook)
|
||||
static int
|
||||
ng_ksocket_rcvdata(hook_p hook, item_p item)
|
||||
{
|
||||
struct thread *td = curthread ? curthread : thread0; /* XXX broken */
|
||||
struct thread *td = curthread ? curthread : &thread0; /* XXX broken */
|
||||
const node_p node = NG_HOOK_NODE(hook);
|
||||
const priv_p priv = NG_NODE_PRIVATE(node);
|
||||
struct socket *const so = priv->so;
|
||||
|
@ -615,7 +615,7 @@ syncache_socket(sc, lso)
|
||||
laddr6 = inp->in6p_laddr;
|
||||
if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
|
||||
inp->in6p_laddr = sc->sc_inc.inc6_laddr;
|
||||
if (in6_pcbconnect(inp, (struct sockaddr *)sin6, thread0)) {
|
||||
if (in6_pcbconnect(inp, (struct sockaddr *)sin6, &thread0)) {
|
||||
inp->in6p_laddr = laddr6;
|
||||
FREE(sin6, M_SONAME);
|
||||
goto abort;
|
||||
@ -647,7 +647,7 @@ syncache_socket(sc, lso)
|
||||
laddr = inp->inp_laddr;
|
||||
if (inp->inp_laddr.s_addr == INADDR_ANY)
|
||||
inp->inp_laddr = sc->sc_inc.inc_laddr;
|
||||
if (in_pcbconnect(inp, (struct sockaddr *)sin, thread0)) {
|
||||
if (in_pcbconnect(inp, (struct sockaddr *)sin, &thread0)) {
|
||||
inp->inp_laddr = laddr;
|
||||
FREE(sin, M_SONAME);
|
||||
goto abort;
|
||||
|
@ -223,7 +223,7 @@ spx_input(m, ipxp)
|
||||
laddr = ipxp->ipxp_laddr;
|
||||
if (ipx_nullhost(laddr))
|
||||
ipxp->ipxp_laddr = si->si_dna;
|
||||
if (ipx_pcbconnect(ipxp, (struct sockaddr *)sipx, thread0)) {
|
||||
if (ipx_pcbconnect(ipxp, (struct sockaddr *)sipx, &thread0)) {
|
||||
ipxp->ipxp_laddr = laddr;
|
||||
spx_istat.noconn++;
|
||||
goto drop;
|
||||
|
@ -158,7 +158,7 @@ nfs_connect(struct nfsmount *nmp, struct nfsreq *rep)
|
||||
int pktscale;
|
||||
struct sockaddr *saddr;
|
||||
struct sockaddr_in *sin;
|
||||
struct thread *td = thread0; /* only used for socreate and sobind */
|
||||
struct thread *td = &thread0; /* only used for socreate and sobind */
|
||||
|
||||
nmp->nm_so = (struct socket *)0;
|
||||
saddr = nmp->nm_nam;
|
||||
@ -1067,7 +1067,7 @@ nfs_timer(void *arg)
|
||||
struct nfsmount *nmp;
|
||||
int timeo;
|
||||
int s, error;
|
||||
struct thread *td = thread0; /* XXX for credentials, will break if sleep */
|
||||
struct thread *td = &thread0; /* XXX for credentials, will break if sleep */
|
||||
|
||||
s = splnet();
|
||||
TAILQ_FOREACH(rep, &nfs_reqq, r_chain) {
|
||||
|
@ -1715,12 +1715,11 @@ init386(first)
|
||||
#endif
|
||||
struct pcpu *pc;
|
||||
|
||||
proc_linkup(&proc0);
|
||||
proc_linkup(&proc0, &proc0.p_ksegrp, &proc0.p_kse, &thread0);
|
||||
proc0.p_uarea = proc0uarea;
|
||||
thread0 = &proc0.p_thread;
|
||||
thread0->td_kstack = proc0kstack;
|
||||
thread0->td_pcb = (struct pcb *)
|
||||
(thread0->td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
|
||||
thread0.td_kstack = proc0kstack;
|
||||
thread0.td_pcb = (struct pcb *)
|
||||
(thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
|
||||
atdevbase = ISA_HOLE_START + KERNBASE;
|
||||
|
||||
#ifdef PC98
|
||||
@ -1785,9 +1784,9 @@ init386(first)
|
||||
PCPU_SET(prvspace, pc);
|
||||
|
||||
/* setup curproc so that mutexes work */
|
||||
PCPU_SET(curthread, thread0);
|
||||
PCPU_SET(curthread, &thread0);
|
||||
|
||||
LIST_INIT(&thread0->td_contested);
|
||||
LIST_INIT(&thread0.td_contested);
|
||||
|
||||
/*
|
||||
* Initialize mutexes.
|
||||
@ -1890,7 +1889,7 @@ init386(first)
|
||||
|
||||
/* make an initial tss so cpu can get interrupt stack on syscall! */
|
||||
/* Note: -16 is so we can grow the trapframe if we came from vm86 */
|
||||
PCPU_SET(common_tss.tss_esp0, thread0->td_kstack +
|
||||
PCPU_SET(common_tss.tss_esp0, thread0.td_kstack +
|
||||
KSTACK_PAGES * PAGE_SIZE - sizeof(struct pcb) - 16);
|
||||
PCPU_SET(common_tss.tss_ss0, GSEL(GDATA_SEL, SEL_KPL));
|
||||
gsel_tss = GSEL(GPROC0_SEL, SEL_KPL);
|
||||
@ -1947,10 +1946,10 @@ init386(first)
|
||||
_udatasel = LSEL(LUDATA_SEL, SEL_UPL);
|
||||
|
||||
/* setup proc 0's pcb */
|
||||
thread0->td_pcb->pcb_flags = 0; /* XXXKSE */
|
||||
thread0->td_pcb->pcb_cr3 = (int)IdlePTD;
|
||||
thread0->td_pcb->pcb_ext = 0;
|
||||
thread0->td_frame = &proc0_tf;
|
||||
thread0.td_pcb->pcb_flags = 0; /* XXXKSE */
|
||||
thread0.td_pcb->pcb_cr3 = (int)IdlePTD;
|
||||
thread0.td_pcb->pcb_ext = 0;
|
||||
thread0.td_frame = &proc0_tf;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1715,12 +1715,11 @@ init386(first)
|
||||
#endif
|
||||
struct pcpu *pc;
|
||||
|
||||
proc_linkup(&proc0);
|
||||
proc_linkup(&proc0, &proc0.p_ksegrp, &proc0.p_kse, &thread0);
|
||||
proc0.p_uarea = proc0uarea;
|
||||
thread0 = &proc0.p_thread;
|
||||
thread0->td_kstack = proc0kstack;
|
||||
thread0->td_pcb = (struct pcb *)
|
||||
(thread0->td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
|
||||
thread0.td_kstack = proc0kstack;
|
||||
thread0.td_pcb = (struct pcb *)
|
||||
(thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
|
||||
atdevbase = ISA_HOLE_START + KERNBASE;
|
||||
|
||||
#ifdef PC98
|
||||
@ -1785,9 +1784,9 @@ init386(first)
|
||||
PCPU_SET(prvspace, pc);
|
||||
|
||||
/* setup curproc so that mutexes work */
|
||||
PCPU_SET(curthread, thread0);
|
||||
PCPU_SET(curthread, &thread0);
|
||||
|
||||
LIST_INIT(&thread0->td_contested);
|
||||
LIST_INIT(&thread0.td_contested);
|
||||
|
||||
/*
|
||||
* Initialize mutexes.
|
||||
@ -1890,7 +1889,7 @@ init386(first)
|
||||
|
||||
/* make an initial tss so cpu can get interrupt stack on syscall! */
|
||||
/* Note: -16 is so we can grow the trapframe if we came from vm86 */
|
||||
PCPU_SET(common_tss.tss_esp0, thread0->td_kstack +
|
||||
PCPU_SET(common_tss.tss_esp0, thread0.td_kstack +
|
||||
KSTACK_PAGES * PAGE_SIZE - sizeof(struct pcb) - 16);
|
||||
PCPU_SET(common_tss.tss_ss0, GSEL(GDATA_SEL, SEL_KPL));
|
||||
gsel_tss = GSEL(GPROC0_SEL, SEL_KPL);
|
||||
@ -1947,10 +1946,10 @@ init386(first)
|
||||
_udatasel = LSEL(LUDATA_SEL, SEL_UPL);
|
||||
|
||||
/* setup proc 0's pcb */
|
||||
thread0->td_pcb->pcb_flags = 0; /* XXXKSE */
|
||||
thread0->td_pcb->pcb_cr3 = (int)IdlePTD;
|
||||
thread0->td_pcb->pcb_ext = 0;
|
||||
thread0->td_frame = &proc0_tf;
|
||||
thread0.td_pcb->pcb_flags = 0; /* XXXKSE */
|
||||
thread0.td_pcb->pcb_cr3 = (int)IdlePTD;
|
||||
thread0.td_pcb->pcb_ext = 0;
|
||||
thread0.td_frame = &proc0_tf;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -128,7 +128,7 @@ int sched_setparam(struct thread *td,
|
||||
e = ESRCH;
|
||||
goto done2;
|
||||
}
|
||||
targettd = &targetp->p_thread; /* XXXKSE */
|
||||
targettd = FIRST_THREAD_IN_PROC(targetp); /* XXXKSE */
|
||||
}
|
||||
|
||||
e = p_cansched(td->td_proc, targetp);
|
||||
@ -164,7 +164,7 @@ int sched_getparam(struct thread *td,
|
||||
e = ESRCH;
|
||||
goto done2;
|
||||
}
|
||||
targettd = &targetp->p_thread; /* XXXKSE */
|
||||
targettd = FIRST_THREAD_IN_PROC(targetp); /* XXXKSE */
|
||||
}
|
||||
|
||||
e = p_cansee(td->td_proc, targetp);
|
||||
@ -206,7 +206,7 @@ int sched_setscheduler(struct thread *td,
|
||||
e = ESRCH;
|
||||
goto done2;
|
||||
}
|
||||
targettd = &targetp->p_thread; /* XXXKSE */
|
||||
targettd = FIRST_THREAD_IN_PROC(targetp); /* XXXKSE */
|
||||
}
|
||||
|
||||
e = p_cansched(td->td_proc, targetp);
|
||||
@ -241,7 +241,7 @@ int sched_getscheduler(struct thread *td,
|
||||
e = ESRCH;
|
||||
goto done2;
|
||||
}
|
||||
targettd = &targetp->p_thread; /* XXXKSE */
|
||||
targettd = FIRST_THREAD_IN_PROC(targetp); /* XXXKSE */
|
||||
}
|
||||
|
||||
e = p_cansee(td->td_proc, targetp);
|
||||
@ -317,7 +317,7 @@ int sched_rr_get_interval(struct thread *td,
|
||||
e = ESRCH;
|
||||
goto done2;
|
||||
}
|
||||
targettd = &targetp->p_thread; /* XXXKSE */
|
||||
targettd = FIRST_THREAD_IN_PROC(targetp); /* XXXKSE */
|
||||
}
|
||||
|
||||
e = p_cansee(td->td_proc, targetp);
|
||||
|
@ -415,15 +415,14 @@ powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, char *args)
|
||||
|
||||
pmap_setavailmem(startkernel, endkernel);
|
||||
|
||||
proc_linkup(&proc0);
|
||||
proc_linkup(&proc0, &proc0.p_ksegrp, &proc0.p_kse, &thread0);
|
||||
|
||||
proc0uarea = (struct user *)pmap_steal_memory(UAREA_PAGES * PAGE_SIZE);
|
||||
proc0kstack = pmap_steal_memory(KSTACK_PAGES * PAGE_SIZE);
|
||||
proc0.p_uarea = proc0uarea;
|
||||
thread0 = &proc0.p_thread;
|
||||
thread0->td_kstack = proc0kstack;
|
||||
thread0->td_pcb = (struct pcb *)
|
||||
(thread0->td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
|
||||
thread0.td_kstack = proc0kstack;
|
||||
thread0.td_pcb = (struct pcb *)
|
||||
(thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
|
||||
|
||||
pcpup = pmap_steal_memory(round_page(sizeof(struct pcpu)));
|
||||
|
||||
@ -440,9 +439,9 @@ powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, char *args)
|
||||
|
||||
/* setup curproc so the mutexes work */
|
||||
|
||||
PCPU_SET(curthread, thread0);
|
||||
PCPU_SET(curthread, &thread0);
|
||||
|
||||
LIST_INIT(&thread0->td_contested);
|
||||
LIST_INIT(&thread0.td_contested);
|
||||
|
||||
/* XXX: NetBSDism I _think_. Not sure yet. */
|
||||
#if 0
|
||||
@ -596,8 +595,8 @@ powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, char *args)
|
||||
PCPU_GET(next_asn) = 1; /* 0 used for proc0 pmap */
|
||||
|
||||
/* setup proc 0's pcb */
|
||||
thread0->td_pcb->pcb_flags = 0; /* XXXKSE */
|
||||
thread0->td_frame = &proc0_tf;
|
||||
thread0.td_pcb->pcb_flags = 0; /* XXXKSE */
|
||||
thread0.td_frame = &proc0_tf;
|
||||
}
|
||||
|
||||
static int N_mapping;
|
||||
|
@ -120,10 +120,9 @@ vm_fault_quick(v, prot)
|
||||
* ready to run and return to user mode.
|
||||
*/
|
||||
void
|
||||
cpu_fork(struct thread *td1, struct proc *p2, int flags)
|
||||
cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags)
|
||||
{
|
||||
struct proc *p1;
|
||||
struct thread *td2;
|
||||
struct trapframe *tf;
|
||||
struct callframe *cf;
|
||||
struct switchframe *sf;
|
||||
@ -136,7 +135,6 @@ cpu_fork(struct thread *td1, struct proc *p2, int flags)
|
||||
return;
|
||||
|
||||
p1 = td1->td_proc;
|
||||
td2 = &p2->p_thread;
|
||||
|
||||
/* Point the pcb to the top of the stack */
|
||||
pcb2 = (struct pcb *)(td2->td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
|
||||
|
@ -415,15 +415,14 @@ powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, char *args)
|
||||
|
||||
pmap_setavailmem(startkernel, endkernel);
|
||||
|
||||
proc_linkup(&proc0);
|
||||
proc_linkup(&proc0, &proc0.p_ksegrp, &proc0.p_kse, &thread0);
|
||||
|
||||
proc0uarea = (struct user *)pmap_steal_memory(UAREA_PAGES * PAGE_SIZE);
|
||||
proc0kstack = pmap_steal_memory(KSTACK_PAGES * PAGE_SIZE);
|
||||
proc0.p_uarea = proc0uarea;
|
||||
thread0 = &proc0.p_thread;
|
||||
thread0->td_kstack = proc0kstack;
|
||||
thread0->td_pcb = (struct pcb *)
|
||||
(thread0->td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
|
||||
thread0.td_kstack = proc0kstack;
|
||||
thread0.td_pcb = (struct pcb *)
|
||||
(thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
|
||||
|
||||
pcpup = pmap_steal_memory(round_page(sizeof(struct pcpu)));
|
||||
|
||||
@ -440,9 +439,9 @@ powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, char *args)
|
||||
|
||||
/* setup curproc so the mutexes work */
|
||||
|
||||
PCPU_SET(curthread, thread0);
|
||||
PCPU_SET(curthread, &thread0);
|
||||
|
||||
LIST_INIT(&thread0->td_contested);
|
||||
LIST_INIT(&thread0.td_contested);
|
||||
|
||||
/* XXX: NetBSDism I _think_. Not sure yet. */
|
||||
#if 0
|
||||
@ -596,8 +595,8 @@ powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, char *args)
|
||||
PCPU_GET(next_asn) = 1; /* 0 used for proc0 pmap */
|
||||
|
||||
/* setup proc 0's pcb */
|
||||
thread0->td_pcb->pcb_flags = 0; /* XXXKSE */
|
||||
thread0->td_frame = &proc0_tf;
|
||||
thread0.td_pcb->pcb_flags = 0; /* XXXKSE */
|
||||
thread0.td_frame = &proc0_tf;
|
||||
}
|
||||
|
||||
static int N_mapping;
|
||||
|
@ -120,10 +120,9 @@ vm_fault_quick(v, prot)
|
||||
* ready to run and return to user mode.
|
||||
*/
|
||||
void
|
||||
cpu_fork(struct thread *td1, struct proc *p2, int flags)
|
||||
cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags)
|
||||
{
|
||||
struct proc *p1;
|
||||
struct thread *td2;
|
||||
struct trapframe *tf;
|
||||
struct callframe *cf;
|
||||
struct switchframe *sf;
|
||||
@ -136,7 +135,6 @@ cpu_fork(struct thread *td1, struct proc *p2, int flags)
|
||||
return;
|
||||
|
||||
p1 = td1->td_proc;
|
||||
td2 = &p2->p_thread;
|
||||
|
||||
/* Point the pcb to the top of the stack */
|
||||
pcb2 = (struct pcb *)(td2->td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
|
||||
|
@ -627,7 +627,7 @@ static int
|
||||
lomac_do_recwd(struct proc *p) {
|
||||
struct nameidata nd;
|
||||
struct filedesc *fdp = curthread->td_proc->p_fd;
|
||||
struct thread *td = &p->p_thread;
|
||||
struct thread *td = FIRST_THREAD_IN_PROC(p); /* XXXKSE Only one? */
|
||||
char *nbuf;
|
||||
struct vnode *cdir, *rdir, *vp;
|
||||
int error;
|
||||
|
@ -141,7 +141,7 @@ db_stack_trace_cmd(db_expr_t addr, boolean_t have_addr, db_expr_t count,
|
||||
db_printf("pid %d swapped out\n", pid);
|
||||
return;
|
||||
}
|
||||
td = &p->p_thread; /* XXXKSE */
|
||||
td = FIRST_THREAD_IN_PROC(p); /* XXXKSE */
|
||||
addr = td->td_pcb->pcb_fp;
|
||||
}
|
||||
}
|
||||
|
@ -275,17 +275,16 @@ sparc64_init(caddr_t mdp, u_int *state, u_int mid, u_int bootmid,
|
||||
/*
|
||||
* Initialize proc0 stuff (p_contested needs to be done early).
|
||||
*/
|
||||
proc_linkup(&proc0);
|
||||
proc_linkup(&proc0, &proc0.p_ksegrp, &proc0.p_kse, &thread0);
|
||||
proc0.p_md.md_utrap = NULL;
|
||||
proc0.p_uarea = (struct user *)uarea0;
|
||||
proc0.p_stats = &proc0.p_uarea->u_stats;
|
||||
thread0 = &proc0.p_thread;
|
||||
thread0->td_kstack = kstack0;
|
||||
thread0->td_pcb = (struct pcb *)
|
||||
(thread0->td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
|
||||
thread0.td_kstack = kstack0;
|
||||
thread0.td_pcb = (struct pcb *)
|
||||
(thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
|
||||
frame0.tf_tstate = TSTATE_IE | TSTATE_PEF;
|
||||
thread0->td_frame = &frame0;
|
||||
LIST_INIT(&thread0->td_contested);
|
||||
thread0.td_frame = &frame0;
|
||||
LIST_INIT(&thread0.td_contested);
|
||||
|
||||
/*
|
||||
* Prime our per-cpu data page for use. Note, we are using it for our
|
||||
@ -294,8 +293,8 @@ sparc64_init(caddr_t mdp, u_int *state, u_int mid, u_int bootmid,
|
||||
*/
|
||||
pc = (struct pcpu *)(pcpu0 + PAGE_SIZE) - 1;
|
||||
pcpu_init(pc, 0, sizeof(struct pcpu));
|
||||
pc->pc_curthread = thread0;
|
||||
pc->pc_curpcb = thread0->td_pcb;
|
||||
pc->pc_curthread = &thread0;
|
||||
pc->pc_curpcb = &thread0.td_pcb;
|
||||
pc->pc_mid = mid;
|
||||
|
||||
/*
|
||||
|
@ -88,15 +88,14 @@ cpu_exit(struct thread *td)
|
||||
* ready to run and return to user mode.
|
||||
*/
|
||||
void
|
||||
cpu_fork(struct thread *td1, struct proc *p2, int flags)
|
||||
cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags)
|
||||
{
|
||||
struct thread *td2;
|
||||
struct md_utrap *ut;
|
||||
struct trapframe *tf;
|
||||
struct frame *fp;
|
||||
struct pcb *pcb;
|
||||
|
||||
KASSERT(td1 == curthread || td1 == thread0,
|
||||
KASSERT(td1 == curthread || td1 == &thread0,
|
||||
("cpu_fork: p1 not curproc and not proc0"));
|
||||
|
||||
if ((flags & RFPROC) == 0)
|
||||
@ -106,7 +105,6 @@ cpu_fork(struct thread *td1, struct proc *p2, int flags)
|
||||
ut->ut_refcnt++;
|
||||
p2->p_md.md_utrap = ut;
|
||||
|
||||
td2 = &p2->p_thread;
|
||||
/* The pcb must be aligned on a 64-byte boundary. */
|
||||
pcb = (struct pcb *)((td2->td_kstack + KSTACK_PAGES * PAGE_SIZE -
|
||||
sizeof(struct pcb)) & ~0x3fUL);
|
||||
|
@ -368,7 +368,7 @@ struct proc {
|
||||
|
||||
struct ksegrp p_ksegrp;
|
||||
struct kse p_kse;
|
||||
struct thread p_thread;
|
||||
struct thread p_xxthread;
|
||||
|
||||
/*
|
||||
* The following don't make too much sense..
|
||||
@ -523,6 +523,12 @@ MALLOC_DECLARE(M_ZOMBIE);
|
||||
#define FOREACH_THREAD_IN_PROC(p, td) \
|
||||
TAILQ_FOREACH((td), &(p)->p_threads, td_plist)
|
||||
|
||||
/* XXXKSE the lines below should probably only be used in 1:1 code */
|
||||
#define FIRST_THREAD_IN_PROC(p) TAILQ_FIRST(&p->p_threads)
|
||||
#define FIRST_KSEGRP_IN_PROC(p) TAILQ_FIRST(&p->p_ksegrps)
|
||||
#define FIRST_KSE_IN_KSEGRP(kg) TAILQ_FIRST(&kg->kg_kseq)
|
||||
#define FIRST_KSE_IN_PROC(p) FIRST_KSE_IN_KSEGRP(FIRST_KSEGRP_IN_PROC(p))
|
||||
|
||||
static __inline int
|
||||
sigonstack(size_t sp)
|
||||
{
|
||||
@ -618,7 +624,7 @@ extern u_long pgrphash;
|
||||
extern struct sx allproc_lock;
|
||||
extern struct sx proctree_lock;
|
||||
extern struct proc proc0; /* Process slot for swapper. */
|
||||
extern struct thread *thread0; /* Primary thread in proc0 */
|
||||
extern struct thread thread0; /* Primary thread in proc0 */
|
||||
extern int hogticks; /* Limit on kernel cpu hogs. */
|
||||
extern int nprocs, maxproc; /* Current and max number of procs. */
|
||||
extern int maxprocperuid; /* Max procs per uid. */
|
||||
@ -673,7 +679,8 @@ int p_cansee __P((struct proc *p1, struct proc *p2));
|
||||
int p_cansched __P((struct proc *p1, struct proc *p2));
|
||||
int p_cansignal __P((struct proc *p1, struct proc *p2, int signum));
|
||||
void procinit __P((void));
|
||||
void proc_linkup __P((struct proc *p));
|
||||
void proc_linkup __P((struct proc *p, struct ksegrp *kg,
|
||||
struct kse *ke, struct thread *td));
|
||||
void proc_reparent __P((struct proc *child, struct proc *newparent));
|
||||
int procrunnable __P((void));
|
||||
void remrunqueue __P((struct thread *));
|
||||
@ -697,11 +704,12 @@ void maybe_resched __P((struct ksegrp *));
|
||||
|
||||
void cpu_exit __P((struct thread *));
|
||||
void exit1 __P((struct thread *, int)) __dead2;
|
||||
void cpu_fork __P((struct thread *, struct proc *, int));
|
||||
void cpu_fork __P((struct thread *, struct proc *, struct thread *, int));
|
||||
void cpu_set_fork_handler __P((struct thread *, void (*)(void *), void *));
|
||||
int trace_req __P((struct proc *));
|
||||
void cpu_wait __P((struct proc *));
|
||||
int cpu_coredump __P((struct thread *, struct vnode *, struct ucred *));
|
||||
struct thread *thread_get(struct proc *);
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* !_SYS_PROC_H_ */
|
||||
|
@ -575,7 +575,7 @@ int lease_check __P((struct vop_lease_args *ap));
|
||||
int spec_vnoperate __P((struct vop_generic_args *));
|
||||
int speedup_syncer __P((void));
|
||||
#define textvp_fullpath(p, rb, rfb) \
|
||||
vn_fullpath(&(p)->p_thread, (p)->p_textvp, rb, rfb)
|
||||
vn_fullpath(FIRST_THREAD_IN_PROC(p), (p)->p_textvp, rb, rfb)
|
||||
int vn_fullpath __P((struct thread *td, struct vnode *vn,
|
||||
char **retbuf, char **freebuf));
|
||||
int vaccess __P((enum vtype type, mode_t file_mode, uid_t uid, gid_t gid,
|
||||
|
@ -80,7 +80,7 @@ void vm_fault_copy_entry __P((vm_map_t, vm_map_t, vm_map_entry_t, vm_map_entry_t
|
||||
void vm_fault_unwire __P((vm_map_t, vm_offset_t, vm_offset_t));
|
||||
int vm_fault_wire __P((vm_map_t, vm_offset_t, vm_offset_t));
|
||||
int vm_fault_user_wire __P((vm_map_t, vm_offset_t, vm_offset_t));
|
||||
void vm_forkproc __P((struct thread *, struct proc *, int));
|
||||
void vm_forkproc __P((struct thread *, struct proc *, struct thread *, int));
|
||||
void vm_waitproc __P((struct proc *));
|
||||
int vm_mmap __P((vm_map_t, vm_offset_t *, vm_size_t, vm_prot_t, vm_prot_t, int, void *, vm_ooffset_t));
|
||||
vm_offset_t vm_page_alloc_contig __P((vm_offset_t, vm_offset_t, vm_offset_t, vm_offset_t));
|
||||
|
@ -209,9 +209,10 @@ vsunlock(addr, len)
|
||||
* to user mode to avoid stack copying and relocation problems.
|
||||
*/
|
||||
void
|
||||
vm_forkproc(td, p2, flags)
|
||||
vm_forkproc(td, p2, td2, flags)
|
||||
struct thread *td;
|
||||
struct proc *p2;
|
||||
struct thread *td2;
|
||||
int flags;
|
||||
{
|
||||
struct proc *p1 = td->td_proc;
|
||||
@ -230,7 +231,7 @@ vm_forkproc(td, p2, flags)
|
||||
vmspace_unshare(p1);
|
||||
}
|
||||
}
|
||||
cpu_fork(td, p2, flags);
|
||||
cpu_fork(td, p2, td2, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -253,7 +254,7 @@ vm_forkproc(td, p2, flags)
|
||||
}
|
||||
|
||||
pmap_new_proc(p2);
|
||||
pmap_new_thread(&p2->p_thread); /* Initial thread */
|
||||
pmap_new_thread(td2); /* Initial thread */
|
||||
|
||||
/* XXXKSE this is unsatisfactory but should be adequate */
|
||||
up = p2->p_uarea;
|
||||
@ -286,7 +287,7 @@ vm_forkproc(td, p2, flags)
|
||||
* cpu_fork will copy and update the pcb, set up the kernel stack,
|
||||
* and make the child ready to run.
|
||||
*/
|
||||
cpu_fork(td, p2, flags);
|
||||
cpu_fork(td, p2, td2, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user