From owner-p4-projects@FreeBSD.ORG Tue Jul 6 06:05:50 2004 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 1A81F16A4D0; Tue, 6 Jul 2004 06:05:50 +0000 (GMT) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id D22EA16A4CE for ; Tue, 6 Jul 2004 06:05:49 +0000 (GMT) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id C836143D2D for ; Tue, 6 Jul 2004 06:05:49 +0000 (GMT) (envelope-from julian@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.11/8.12.11) with ESMTP id i6665nv9007842 for ; Tue, 6 Jul 2004 06:05:49 GMT (envelope-from julian@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.11/8.12.11/Submit) id i6665nGL007839 for perforce@freebsd.org; Tue, 6 Jul 2004 06:05:49 GMT (envelope-from julian@freebsd.org) Date: Tue, 6 Jul 2004 06:05:49 GMT Message-Id: <200407060605.i6665nGL007839@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to julian@freebsd.org using -f From: Julian Elischer To: Perforce Change Reviews Subject: PERFORCE change 56588 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 06 Jul 2004 06:05:50 -0000 http://perforce.freebsd.org/chv.cgi?CH=56588 Change 56588 by julian@julian_jules1 on 2004/07/06 06:05:28 cleaned up version of sched.4bsd.c that compiles but not tested.. thr now is scope_process. Affected files ... .. //depot/projects/nsched/sys/kern/kern_kse.c#17 edit .. //depot/projects/nsched/sys/kern/kern_thr.c#9 edit .. //depot/projects/nsched/sys/kern/sched_4bsd.c#22 edit .. //depot/projects/nsched/sys/sys/proc.h#19 edit Differences ... ==== //depot/projects/nsched/sys/kern/kern_kse.c#17 (text+ko) ==== ==== //depot/projects/nsched/sys/kern/kern_thr.c#9 (text+ko) ==== @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -43,6 +44,7 @@ #include +extern int virtual_cpu; /* * Back end support functions. */ @@ -118,6 +120,7 @@ ucontext_t ctx; long id; int error; + int ncpus; if ((error = copyin(uap->ctx, &ctx, sizeof(ctx)))) return (error); @@ -143,7 +146,14 @@ td0->td_proc = td->td_proc; PROC_LOCK(td->td_proc); td0->td_sigmask = td->td_sigmask; - td->td_proc->p_flag |= P_HADTHREADS; + /* First time through? */ + if ((td->td_proc->p_flag & P_HADTHREADS) == 0) { + ncpus = mp_ncpus; + if (virtual_cpu != 0) + ncpus = virtual_cpu; + sched_set_concurrancy(td->td_ksegrp, ncpus); + td->td_proc->p_flag |= P_HADTHREADS; + } PROC_UNLOCK(td->td_proc); td0->td_ucred = crhold(td->td_ucred); ==== //depot/projects/nsched/sys/kern/sched_4bsd.c#22 (text+ko) ==== @@ -102,7 +102,6 @@ #define td_rqindex td_sched->std_rqindex #define td_state td_sched->std_state #define td_cpticks td_sched->std_cpticks -#define td_runq td_sched->std_runq /* flags kept in ke_flags */ @@ -120,12 +119,13 @@ #define kg_last_assigned kg_sched->skg_last_assigned #define kg_runq_threads kg_sched->skg_runq_threads #define kg_avail_opennings kg_sched->skg_avail_opennings +#define kg_concurrancy kg_sched->skg_concurrancy /**************************************************************** * function prototypes */ -static void recycle_slot(struct ksegrp *kg); /* was kse_reassign */ +static void slot_fill(struct ksegrp *kg); /* was kse_reassign */ #define KTR_4BSD 0x0 #define RANGEOF(type, start, end) (offsetof(type, end) - offsetof(type, start)) @@ -145,7 +145,7 @@ #define NICE_WEIGHT 1 /* Priorities per nice level. */ #define STD_RUNQ_PCPU(std) \ - ((std)->std_runq != 0 && (std)->std_runq != &runq) + (((std)->std_runq != 0) && ((std)->std_runq != &runq)) /* * TD_CAN_MIGRATE macro returns true if the thread can migrate between @@ -163,14 +163,13 @@ static void setup_runqs(void); static void roundrobin(void *arg); static void schedcpu(void); -static void schedcpu_thread(void); +static void schedcpu_kthread(void); static void sched_setup(void *dummy); static void maybe_resched(struct thread *td); static void updatepri(struct ksegrp *kg); static void resetpriority(struct ksegrp *kg); static void sched_add(struct thread *td); static void sched_rem(struct thread *td); -static struct td_sched * sched_choose(void); static void adjustrunqueue( struct thread *td, int newpri) ; @@ -180,7 +179,7 @@ static struct kproc_desc sched_kp = { "schedcpu", - schedcpu_thread, + schedcpu_kthread, NULL }; SYSINIT(schedcpu, SI_SUB_RUN_SCHEDULER, SI_ORDER_FIRST, kproc_start, &sched_kp) @@ -252,11 +251,11 @@ struct rqhead rq_queues[RQ_NQS]; }; -static void runq_add(struct runq *, struct thread *); +static void runq_add(struct runq *, struct td_sched *); static int runq_check(struct runq *); static struct td_sched *runq_choose(struct runq *); static void runq_init(struct runq *); -static void runq_remove(struct runq *, struct thread *); +static void runq_remove(struct runq *, struct td_sched *); #endif /* end of Jake copyright file */ /* @@ -441,7 +440,7 @@ * Recompute process priorities, every hz ticks. * MP-safe, called without the Giant mutex. * Called from: - * schedcpu_thread() which is a kthread that awakens once per second. + * schedcpu_kthread() which is a kthread that awakens once per second. */ /* ARGSUSED */ static void @@ -450,7 +449,7 @@ register fixpt_t loadfac = loadfactor(averunnable.ldavg[0]); struct thread *td; struct proc *p; - struct td_sched *ts; + struct td_sched *std; struct ksegrp *kg; int awake, realstathz; @@ -468,8 +467,8 @@ p->p_swtime++; FOREACH_KSEGRP_IN_PROC(p, kg) { awake = 0; - FOREACH_THREAD(kg, td) { - ts = td->td_sched; + FOREACH_THREAD_IN_GROUP(kg, td) { + std = td->td_sched; /* * Increment sleep time (if sleeping). We * ignore overflow, as above. @@ -560,7 +559,7 @@ * This is a kthread that runs forever.. */ static void -schedcpu_thread(void) +schedcpu_kthread(void) { int nowake; @@ -723,12 +722,13 @@ /* * charge childs scheduling cpu usage to parent. * - * XXXKSE assume only one thread & ksegrp keep estcpu in each ksegrp. + * XXXKSE assume only one thread & ksegrp. Keep estcpu in each ksegrp. * Charge it to the ksegrp that did the wait since process estcpu is sum of * all ksegrps, this is strictly as expected. Assume that the child process * aggregated all the estcpu into the 'built-in' ksegrp. * Called from: * exit() + * XXXKSE add a sched_wait() to transfer estcpu..? */ void sched_exit(struct proc *parent, struct thread *td) @@ -747,13 +747,12 @@ * We should give the estcpu to someone, but WHO? * Only called on exit of last thread in the ksegrp. * Called from: - * thread_exit() (for threaded programs only) + * thread_exit() (for threaded programs only when last thread exits) */ void sched_exit_ksegrp(struct proc *parent, struct thread *td) { /* free any resources we had on this ksegrp */ - sched_set_concurrancy(td->td_ksegrp, 0); } /* @@ -765,9 +764,9 @@ sched_thread_exit(struct thread *td) { - if (td->td_proc->p_flag & P_SA) { + if (td->td_proc->p_flag & P_HADTHREADS) { td->td_ksegrp->kg_avail_opennings++; - recycle_slot(td->td_ksegrp); + slot_fill(td->td_ksegrp); } if ((td->td_proc->p_flag & P_NOLOAD) == 0) sched_tdcnt--; @@ -785,11 +784,14 @@ sched_thr_exit(struct thread *td) { + if (td->td_proc->p_flag & P_HADTHREADS) { + td->td_ksegrp->kg_avail_opennings++; + slot_fill(td->td_ksegrp); + } if ((td->td_proc->p_flag & P_NOLOAD) == 0) sched_tdcnt--; } - /* * Allocate any resources the scheduler needs to allocate or set up * on a new process at fork() time. Set up our scheduler specifi extensions. @@ -811,7 +813,7 @@ newtd->td_ksegrp->kg_concurrancy = 1; /* non threaded process. ignore thread fairness stuff */ - newtd->td_ksegrp->kg_avail_opennings = 0; + newtd->td_ksegrp->kg_avail_opennings = 1; /* Our child inherrits our estimated cpu requirement */ newtd->td_ksegrp->kg_estcpu = td->td_ksegrp->kg_estcpu; } @@ -935,19 +937,20 @@ */ if (td == PCPU_GET(idlethread)) TD_SET_CAN_RUN(td); - else if (TD_IS_RUNNING(td)) { - /* Put us back on the run queue. */ - if (p->p_flag & P_SA) - kg->kg_avail_opennings++; - setrunqueue(td); - } else if (p->p_flag & P_SA) { - /* - * We will not be on the run queue. So we must be - * sleeping or similar. As it's available, - * another thread could use our 'slot'. - */ - kg->kg_avail_opennings++; - recycle_slot(kg); + else { + td->td_ksegrp->kg_avail_opennings++; + if (TD_IS_RUNNING(td)) { + /* Put us back on the run queue. */ + setrunqueue(td); + } else if (p->p_flag & P_HADTHREADS) { + /* + * We will not be on the run queue. So we must be + * sleeping or similar. As it's available, + * another thread could use our 'slot'. + * (don't bother if there are no other threads) + */ + slot_fill(td->td_ksegrp); + } } if (newtd == NULL) newtd = choosethread(flags); @@ -985,7 +988,7 @@ * the fact that the thread is becoming runnable, * and decide which run queue to use. * Called from: - * recycle_slot() (local) + * slot_fill() (local) * adjustrunqueue() (local) * setrunqueue() (local) */ @@ -998,8 +1001,8 @@ mtx_assert(&sched_lock, MA_OWNED); KASSERT(std->std_state != STDS_ONRUNQ, ("sched_add: kse %p (%s) already in run queue", std, - std->std_proc->p_comm)); - KASSERT(std->std_proc->p_sflag & PS_INMEM, + td->td_proc->p_comm)); + KASSERT(td->td_proc->p_sflag & PS_INMEM, ("sched_add: process swapped out")); #ifdef SMP @@ -1044,7 +1047,7 @@ struct td_sched *std; std = td->td_sched; - KASSERT(std->std_proc->p_sflag & PS_INMEM, + KASSERT(td->td_proc->p_sflag & PS_INMEM, ("sched_rem: process swapped out")); KASSERT((std->std_state == STDS_ONRUNQ), ("sched_rem: KSE not on run queue")); @@ -1055,7 +1058,7 @@ runq_remove(std->std_runq, std); std->std_state = STDS_THREAD; - std->std_ksegrp->kg_runq_threads--; + td->td_ksegrp->kg_runq_threads--; } /* @@ -1205,9 +1208,9 @@ /* * and set it up as if running */ - std->std_oncpu = NOCPU; /* wrong.. can we use PCPU(cpuid) yet? */ + td_sched0.std_oncpu = NOCPU; /* wrong.. can we use PCPU(cpuid) yet? */ td_sched0.std_state = STDS_THREAD; - kg_sched0.concurrancy = 1; + kg_sched0.skg_concurrancy = 1; kg_sched0.skg_avail_opennings = 0; /* we are already running */ } @@ -1221,6 +1224,8 @@ int sched_thr_newthread(struct thread *td, struct thread *newtd, int flags) { + struct td_sched *newstd; + newstd = newtd->td_sched; bzero(&newstd->std_startzero, RANGEOF(struct td_sched, std_startzero, std_endzero)); @@ -1230,7 +1235,7 @@ thread_link(newtd, td->td_ksegrp); - std->std_oncpu = NOCPU; + newstd->std_oncpu = NOCPU; newstd->std_state = STDS_THREAD; newstd->std_cpticks = 0; @@ -1300,7 +1305,6 @@ sched_destroyproc(struct proc *p) { struct ksegrp *kg; - struct kg_sched *skg; KASSERT((p->p_numthreads == 1), ("Cached proc with > 1 thread ")); KASSERT((p->p_numksegrps == 1), ("Cached proc with > 1 ksegrp ")); @@ -1333,16 +1337,17 @@ if (concurrancy > skg->skg_concurrancy) { skg->skg_concurrancy = concurrancy; skg->skg_avail_opennings += concurrancy - skg->skg_concurrancy; - recycle_slot(kg); + slot_fill(kg); } else { /* * don't remove things from the queue. * they'll just get used up as they run. + * XXXKSE Make this a true statement.. */ skg->skg_concurrancy = concurrancy; skg->skg_avail_opennings += concurrancy - skg->skg_concurrancy; if (skg->skg_avail_opennings < 0) - skg->skg_avail_opennings == 0; + skg->skg_avail_opennings = 0; } mtx_unlock_spin(&sched_lock); } @@ -1394,7 +1399,7 @@ system run queue as those that were are activly running, or because there are no threads queued, that pointer is NULL. -/*** warning.. nmo longer true with multiple run queues ***/ +*** warning.. no longer true with multiple run queues *** When a thread is removed from the run queue to become run, we know it was the highest priority thread in the queue (at the head of the queue). If it is also the last assigned we know M was 1 and must @@ -1508,14 +1513,14 @@ #endif if (std != NULL) { - KASSERT(std->std_proc->p_sflag & PS_INMEM, - ("sched_choose: process swapped out")); runq_remove(rq, std); std->std_state = STDS_THREAD; td = std->std_thread; - kg = std->std_ksegrp; + KASSERT(td->td_proc->p_sflag & PS_INMEM, + ("choosethread: process swapped out")); + kg = td->td_ksegrp; kg->kg_runq_threads--; - if (td->td_proc->p_flag & P_SA) { + if (td->td_proc->p_flag & P_HADTHREADS) { if (kg->kg_last_assigned == td) { kg->kg_last_assigned = TAILQ_PREV(td, threadqueue, td_runq); @@ -1558,12 +1563,12 @@ * remrunqueue() (local) (commented out) */ static void -recycle_slot(struct ksegrp *kg) +slot_fill(struct ksegrp *kg) { struct thread *td; - while (kg->kg_avail_opennings) { - mtx_assert(&sched_lock, MA_OWNED); + mtx_assert(&sched_lock, MA_OWNED); + while (kg->kg_avail_opennings > 0) { /* * Find the first unassigned thread */ @@ -1579,21 +1584,20 @@ kg->kg_last_assigned = td; kg->kg_avail_opennings--; sched_add(td); - CTR2(KTR_RUNQ, "recycle_slot: std%p -> td%p", std, td); + CTR2(KTR_RUNQ, "slot_fill: std%p -> td%p", std, td); } else { /* no threads to use up the slots. quit now */ - break + break; } } - return; } #if 0 /* * Remove a thread from its KSEGRP's run queue. - * This in turn may remove it from a KSE if it was already assigned - * to one, possibly causing a new thread to be assigned to the KSE - * and the KSE getting a new priority. + * This in turn may remove it from the system run queue if it was + * on it to one, possibly causing a new thread to be assigned to the slot + * with a different priority. * Called from: * Not used */ @@ -1614,9 +1618,10 @@ /* * If it is not a threaded process, take the shortcut. */ - if ((td->td_proc->p_flag & P_SA) == 0) { + if ((td->td_proc->p_flag & P_HADTHREADS) == 0) { /* Bring its kse with it, leave the thread attached */ sched_rem(td); + kg->kg_avail_opennings++; return; } td3 = TAILQ_PREV(td, threadqueue, td_runq); @@ -1635,7 +1640,7 @@ KASSERT((td2 != NULL), ("last assigned has wrong value")); if (td2 == td) kg->kg_last_assigned = td3; - recycle_slot(kg); + slot_fill(kg); } } #endif @@ -1659,8 +1664,7 @@ /* * If it is not a threaded process, take the shortcut. */ - if ((td->td_proc->p_flag & P_SA) == 0) { - /* We only care about the kse in the run queue. */ + if ((td->td_proc->p_flag & P_HADTHREADS) == 0) { td->td_priority = newpri; if (std->std_rqindex != (newpri / RQ_PPQ)) { sched_rem(td); @@ -1709,7 +1713,6 @@ void setrunqueue(struct thread *td) { - struct td_sched *std; struct ksegrp *kg; struct thread *td2; struct thread *tda; @@ -1721,12 +1724,13 @@ TD_SET_RUNQ(td); kg = td->td_ksegrp; kg->kg_runnable++; - if ((td->td_proc->p_flag & P_SA) == 0) { + if ((td->td_proc->p_flag & P_HADTHREADS) == 0) { /* * Common path optimisation: Only one of everything * and the KSE is always already attached. * Totally ignore the ksegrp run queue. */ + kg->kg_avail_opennings--; sched_add(td); return; } @@ -1784,7 +1788,6 @@ */ td = TAILQ_NEXT(tda, td_runq); tda = kg->kg_last_assigned = td; - std->std_thread = td; } kg->kg_avail_opennings--; sched_add(td); @@ -1792,7 +1795,6 @@ } } ---got to here -- /************************************************************************ * Critical section marker functions * @@ -1927,7 +1929,7 @@ runq_setbit(rq, pri); rqh = &rq->rq_queues[pri]; CTR4(KTR_RUNQ, "runq_add: p=%p pri=%d %d rqh=%p", - std->std_proc, std->std_thread->td_priority, pri, rqh); + std->std_thread->td_proc, std->std_thread->td_priority, pri, rqh); TAILQ_INSERT_TAIL(rqh, std, std_procq); } @@ -1970,7 +1972,8 @@ std = TAILQ_FIRST(rqh); KASSERT(std != NULL, ("runq_choose: no proc on busy queue")); CTR3(KTR_RUNQ, - "runq_choose: pri=%d kse=%p rqh=%p", pri, std, rqh); + "runq_choose: pri=%d td=%p rqh=%p", + pri, std->std_thread, rqh); return (std); } CTR1(KTR_RUNQ, "runq_choose: idleproc pri=%d", pri); @@ -1989,7 +1992,7 @@ struct rqhead *rqh; int pri; - KASSERT(std->std_proc->p_sflag & PS_INMEM, + KASSERT(std->std_thread->td_proc->p_sflag & PS_INMEM, ("runq_remove: process swapped out")); pri = std->std_rqindex; rqh = &rq->rq_queues[pri]; ==== //depot/projects/nsched/sys/sys/proc.h#19 (text+ko) ==== @@ -568,7 +568,7 @@ #define P_CONTINUED 0x10000 /* Proc has continued from a stopped state. */ #define P_STOPPED_SIG 0x20000 /* Stopped due to SIGSTOP/SIGTSTP. */ #define P_STOPPED_TRACE 0x40000 /* Stopped because of tracing. */ -#define P_STOPPED_SINGLE 0x80000 /* Only one thread can continue */ +#define P_STOPPED_SINGLE 0x80000 /* Only one thread can continue */ /* (not to user) */ #define P_PROTECTED 0x100000 /* Do not kill on memory overcommit. */ #define P_SIGEVENT 0x200000 /* Process pending signals changed. */