00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include<linux/sched.h>
00012 #include <asmlink.h>
00013 #include<asm/hw_irq.h>
00014
00015 #include<sysgen.h>
00016 #include<rse.h>
00017 #include<pridef.h>
00018 #include<evtdef.h>
00019 #include<statedef.h>
00020 #include<cpudef.h>
00021 #include<system_data_cells.h>
00022 #include<ipl.h>
00023 #include<internals.h>
00024 #include <exe_routines.h>
00025 #include <sch_routines.h>
00026 #include <smp_routines.h>
00027 #include <misc_routines.h>
00028 #include<queue.h>
00029 #include<ipldef.h>
00030 #include<cpbdef.h>
00031
00032 extern int mydebug;
00033
00034 void sch_unwait(struct _pcb * p);
00035 void sch_rse(struct _pcb * p, unsigned char class, unsigned char event);
00036 void sch_swpwake(void);
00037 void sch_chsep(struct _pcb * p,unsigned char newpri);
00038 void sch_change_cur_priority(struct _pcb *p, unsigned char newpri);
00039
00040 int sch_qend(struct _pcb * p) {
00041 int cpuid=smp_processor_id();
00042 struct _cpu * cpu=smp_gl_cpu_data[cpuid];
00043 vmslock(&SPIN_SCHED,IPL__SCHED);
00044
00045 p->pcb_l_pixhist=p->pcb$l_pixhist << 1;
00046 p->pcb_w_quant = -QUANTUM;
00047 p->pcb_l_onqtime=exe$gl_abstim_tics;
00048 p->pcb_l_sts=p->pcb$l_sts & ( ~ PCB$M_INQUAN );
00049 #if 0
00050
00051 if (ffs(sch_gl_comoqs)) {
00052 p->pcb_b_pri=p->pcb$b_prib;
00053
00054
00055
00056 }
00057 #endif
00058 {
00059
00060 struct _pcb * e, * next;
00061 unsigned char c;
00062 int tmppri;
00063
00064
00065
00066
00067
00068
00069 tmppri=ffs(sch_gl_comqs);
00070 tmppri--;
00071 if (tmppri<=p->pcb_b_pri) {
00072 if (p->pcb_b_pri != p->pcb$b_prib)
00073 sch_change_cur_priority(p,p->pcb$b_pri+1);
00074
00075
00076
00077
00078 }
00079 else
00080 {
00081
00082 #if 1
00083 SOFTINT_RESCHED_VECTOR;
00084 #else
00085 sch_gl_idle_cpus &= ~(1<<p->pcb$l_cpu_id);
00086 #endif
00087 }
00088 }
00089 vmsunlock(&SPIN_SCHED,-1);
00090 return 1;
00091 }
00092
00093
00094
00095
00096
00097 int sch_pixscan(void) {
00098 unsigned long tmp;
00099 struct _pcb *tmp2;
00100 unsigned long comqs=sch_gl_comqs & 0x7fff0000;
00101 int tmppri,i,scanned=sgn_gw_pixscan;
00102
00103
00104
00105
00106 if (!sgn_gw_pixscan) return;
00107
00108 vmslock(&SPIN_SCHED,-1);
00109
00110
00111 if (!((sch_gl_comqs & 0x7fff0000) || (sch$gl_comoqs & 0x7fff0000))) goto out;
00112 tmppri=ffs(comqs);
00113 tmppri--;
00114
00115
00116
00117 goto out;
00118
00119
00120
00121
00122 for(i=30;i>tmppri && scanned;i--) {
00123 tmp=*(unsigned long *)&sch_aq_comh[i];
00124 if(*(unsigned long *)tmp == tmp) {; } else {
00125 tmp2=tmp;
00126 do {
00127
00128 if (!(tmp2>=&sch_aq_comh[0] && tmp2<=&sch$aq_comh[33])) {
00129
00130 if (tmp2->pcb_l_onqtime+100*sch$gw_dormantwait<exe$gl_abstim_tics) {
00131
00132 tmp2->pcb_l_pixhist|=1;
00133
00134 sch_chsep(tmp2,tmppri);
00135 scanned--;
00136 if (!scanned) goto out;
00137 } else {
00138 goto out;
00139 }
00140 }
00141 tmp2=tmp2->pcb_l_sqfl;
00142 } while (tmp2!=tmp);
00143 }
00144 }
00145 out:
00146
00147
00148 vmsunlock(&SPIN_SCHED,-1);
00149 return;
00150 }
00151
00152 int myp3, myp2, mycomq, mypri, sqfl;
00153
00154
00155
00156
00157
00158 void sch_chsep(struct _pcb * p,unsigned char newpri) {
00159 int ipl = getipl();
00160 if (ipl != 8 || SPIN_SCHED.spl_l_spinlock == 0)
00161 panic("rse %x %x\n",ipl,SPIN_SCHED.spl_l_spinlock);
00162 struct _pcb * p2, *p3 , *dummy = 0;
00163 p3=p->pcb_l_sqfl;
00164 myp3=p3;
00165 mycheckaddr(0);
00166 p2=remque(p,dummy);
00167 myp2=p2;
00168 mycomq=sch_gl_comqs;
00169 mypri=p2->pcb_b_pri;
00170 sqfl=p3->pcb_l_sqfl;
00171
00172 if (p3==p3->pcb_l_sqfl) {
00173 if (p2->pcb_w_state==SCH$C_COM) {
00174 sch_gl_comqs&=(~(1 << p2->pcb$b_pri));
00175 } else if (p2->pcb_w_state==SCH$C_COMO) {
00176 sch_gl_comoqs&=(~(1 << p2->pcb$b_pri));
00177 }
00178 }
00179 mycheckaddr(0);
00180 p->pcb_b_pri=newpri;
00181
00182
00183 if (0) {
00184 sch_swpwake();
00185 p2->pcb_w_state=SCH$C_COMO;
00186 p2->state=TASK_RUNNING;
00187 mycheckaddr(0);
00188 #ifdef __i386__
00189 insque(p2,*(unsigned long *)&sch_aq_comot[newpri]);
00190 #else
00191 insque(p2,*(unsigned long *)&sch_aq_comoh[newpri][1]);
00192 #endif
00193 sch_gl_comoqs|=(1 << newpri);
00194 mycheckaddr(0);
00195 return;
00196 }
00197
00198 p2->pcb_w_state=SCH$C_COM;
00199 p2->state=TASK_RUNNING;
00200 mycheckaddr(0);
00201 if (task_on_comqueue(p2))
00202 panic("t\n");
00203 #if 0
00204 if (p2==ctl_gl_pcb)
00205 panic("t2\n");
00206 #endif
00207
00208 if (sch_gl_idle_cpus || sch$gl_capability_sequence != p2->pcb$l_capability_seq) {
00209
00210
00211 if (sch_gl_capability_sequence != p2->pcb$l_capability_seq)
00212 p2->pcb_l_current_affinity = sch$calculate_affinity(p2->pcb$l_affinity);
00213
00214 if (p2->pcb_l_current_affinity & sch$gl_idle_cpus) {
00215 if (p2->pcb_l_capability & CPB$M_IMPLICIT_AFFINITY) {
00216 int isset = sch_gl_idle_cpus & (1<<p2->pcb$l_affinity);
00217 sch_gl_idle_cpus &= ~(1<<p2->pcb$l_affinity);
00218 if (isset)
00219 goto do_return;
00220 }
00221 sch_gl_idle_cpus &= ~p2->pcb$l_current_affinity;
00222 goto do_return;
00223 }
00224
00225
00226 if (sch_gl_active_priority & ((1<<(31-newpri))-1) & (1<<(31-mypri)-1)) {
00227 int lowpri=ffs(sch_gl_active_priority);
00228 lowpri--;
00229 int cpus=sch_al_cpu_priority[31-lowpri];
00230 if ((cpus & p2->pcb_l_current_affinity) == 0) {
00231 do {
00232 int tmp = (sch_gl_active_priority & ((1<<(31-newpri))-1));
00233 tmp &= ~(1<<lowpri);
00234 lowpri=ffs(tmp);
00235 if(lowpri == 0)
00236 goto do_return;
00237 lowpri--;
00238 int cpus=sch_al_cpu_priority[31-lowpri];
00239 } while ((cpus & p2->pcb_l_current_affinity) == 0);
00240 }
00241 int wanted;
00242 if (p2->pcb_l_capability & CPB$M_IMPLICIT_AFFINITY)
00243 wanted = p2->pcb_l_affinity;
00244 else
00245 wanted = ctl_gl_pcb->pcb$l_cpu_id;
00246 #if 1
00247 if (wanted != smp_processor_id())
00248 smp_send_work(CPU_M_RESCHED, wanted);
00249 else
00250 SOFTINT_RESCHED_VECTOR;
00251 #else
00252 sch_gl_idle_cpus &= ~(1<<p->pcb$l_cpu_id);
00253 #endif
00254 goto do_return;
00255 }
00256 }
00257 #if 0
00258 do_resched:
00259 mycheckaddr(0);
00260
00261 #if 1
00262 SOFTINT_RESCHED_VECTOR;
00263 #else
00264 sch_gl_idle_cpus &= ~(1<<p2->pcb$l_cpu_id);
00265 #endif
00266 #endif
00267
00268 do_return:
00269 #ifdef __i386__
00270 insque(p2,*(unsigned long *)&sch_aq_comt[newpri]);
00271 #else
00272 insque(p2,*(unsigned long *)&sch_aq_comh[newpri][1]);
00273 #endif
00274 sch_gl_comqs|=(1 << newpri);
00275 #if 0
00276 p->pcb_l_sts&=~PCB$M_WAKEPEN;
00277 #endif
00278 }
00279
00280
00281
00282
00283
00284
00285 void sch_chse(struct _pcb * p, unsigned char class) {
00286 unsigned char pri=0,newpri;
00287
00288
00289
00290 switch (class) {
00291 case PRI__NULL:
00292 pri=0;
00293 break;
00294 case PRI__IOCOM:
00295 pri=2;
00296 break;
00297 case PRI__TIMER:
00298 case PRI__RESAVL:
00299 pri=3;
00300 break;
00301 case PRI__TOCOM:
00302 pri=4;
00303 break;
00304 case PRI__TICOM:
00305 pri=6;
00306 break;
00307 }
00308 newpri=p->pcb_b_prib-pri;
00309 if (newpri>p->pcb_b_pri) newpri=p->pcb$b_pri;
00310 if (p->pcb_b_pri<16) newpri=p->pcb$b_prib;
00311 sch_chsep(p,newpri);
00312 }
00313
00314
00315
00316
00317
00318 void sch_wake(unsigned long pid) {
00319 struct _pcb * p=exe_ipid_to_pcb(pid);
00320 if (!p) return;
00321
00322 p->pcb_l_sts |= PCB$M_WAKEPEN;
00323
00324 sch_rse(p,PRI$_RESAVL,EVT$_WAKE);
00325 }
00326
00327 void sch_swpwake(void) {
00328 if (sch_gl_comoqs) goto wake;
00329
00330 if (sch_gl_mfycnt>0) goto wake;
00331
00332 return;
00333 wake:
00334 sch_wake(sch$gl_swppid);
00335 return;
00336 }
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346 void sch_rse(struct _pcb * p, unsigned char class, unsigned char event) {
00347 unsigned long dummy = 0;
00348 struct _pcb *p2;
00349 int ipl = getipl();
00350 if (ipl != 8 || SPIN_SCHED.spl_l_spinlock == 0)
00351 panic("rse %x %x\n",ipl,SPIN_SCHED.spl_l_spinlock);
00352
00353
00354
00355
00356
00357
00358 switch (event) {
00359 case EVT__AST:
00360 switch (p->pcb_w_state) {
00361 case SCH_C_SUSP:
00362 case SCH_C_SUSPO:
00363 case SCH_C_COM:
00364 case SCH_C_COMO:
00365 case SCH_C_CUR:
00366 break;
00367 default:
00368 goto ast;
00369 }
00370
00371 case EVT__EVENT: {
00372 if (p->pcb_w_state==SCH$C_LEF) goto event;
00373 if (p->pcb_w_state==SCH$C_CEF) goto cef;
00374 if (p->pcb_w_state==SCH$C_LEFO) goto lefo;
00375 }
00376
00377 case EVT__CEF: {
00378 if (p->pcb_w_state==SCH$C_CEF) goto cef;
00379 if (p->pcb_w_state==SCH$C_LEFO) goto lefo;
00380 }
00381
00382 case EVT__LEFO:
00383 if (p->pcb_w_state==SCH$C_LEFO) goto lefo;
00384
00385 case EVT__FPGA:
00386 if (p->pcb_w_state==SCH$C_FPG) goto fpga;
00387
00388
00389
00390 case EVT__WAKE:
00391 switch (p->pcb_w_state) {
00392 case SCH_C_HIB:
00393 case SCH_C_HIBO:
00394 goto wake;
00395 }
00396
00397 case EVT__RESUME:
00398 switch (p->pcb_w_state) {
00399 case SCH_C_SUSP:
00400 case SCH_C_SUSPO:
00401 goto resume;
00402 }
00403
00404 case EVT__PFCOM:
00405 if (p->pcb_w_state==SCH$C_PFW) goto pfcom;
00406
00407 case EVT__SETPRI:
00408 switch (p->pcb_w_state) {
00409 case SCH_C_COM:
00410 case SCH_C_COMO:
00411 goto setpri;
00412 }
00413
00414
00415
00416 case EVT__SWPOUT:
00417 switch (p->pcb_w_state) {
00418 case SCH_C_COM:
00419 case SCH_C_HIB:
00420 case SCH_C_LEF:
00421 case SCH_C_SUSP:
00422 goto swpout;
00423 }
00424 }
00425
00426
00427
00428 return;
00429
00430 cef:
00431
00432 if (!(p->pcb_l_sts & PCB$M_RES)) goto lefo;
00433 event:
00434
00435
00436 goto lefo;
00437
00438 lefo:
00439 goto common;
00440
00441 ast:
00442 colpga:
00443 fpga:
00444 wake:
00445 resume:
00446 pfcom:
00447 setpri:
00448
00449
00450 common:
00451
00452
00453
00454
00455 if (p->pcb_w_state < SCH$C_COM)
00456 sch_aq_wqhdr[p->pcb$w_state].wqh$l_wqcnt--;
00457
00458 p->pcb_l_onqtime+=(exe$gl_abstim_tics-p->pcb$l_waitime);
00459 sch_unwait(p);
00460
00461 sch_chse(p,class);
00462 return;
00463
00464
00465 swpout:
00466 if (p->pcb_w_state!=SCH$C_COM) {
00467
00468
00469 p2=remque(p,dummy);
00470
00471 sch_aq_wqhdr[p->pcb$w_state].wqh$l_wqcnt--;
00472
00473
00474 (p->pcb_w_state)++;
00475 insque(p,sch_aq_wqhdr[p->pcb$w_state].wqh$l_wqfl);
00476
00477 sch_aq_wqhdr[p->pcb$w_state].wqh$l_wqcnt++;
00478 } else {
00479
00480 int tmppri=p->pcb_b_pri;
00481 unsigned long qhead;
00482
00483 mycheckaddr(0);
00484
00485 p2=remque(p,dummy);
00486
00487 if (sch_aq_comh[tmppri]==&sch$aq_comh[tmppri])
00488 sch_gl_comqs=sch$gl_comqs & (~(1 << tmppri));
00489
00490 (p->pcb_w_state)++;
00491 mycheckaddr(0);
00492
00493 sch_gl_comoqs=sch$gl_comoqs | (1 << tmppri);
00494
00495 #ifdef __i386__
00496 qhead=*(unsigned long *)&sch_aq_comot[tmppri];
00497 #else
00498 qhead=*(unsigned long *)&sch_aq_comoh[tmppri][1];
00499 #endif
00500 insque(p,qhead);
00501 mycheckaddr(0);
00502 }
00503 return;
00504 }
00505
00506
00507
00508
00509
00510 void sch_change_cur_priority(struct _pcb *p, unsigned char newpri) {
00511
00512 int tmppri;
00513 struct _pcb * p2 = p;
00514 int cpuid = p2->pcb_l_cpu_id;
00515 struct _cpu * cpu=smp_gl_cpu_data[cpuid];
00516
00517
00518 sch_al_cpu_priority[cpu->cpu$b_cur_pri]=sch$al_cpu_priority[cpu->cpu$b_cur_pri] & (~cpu->cpu$l_cpuid_mask);
00519
00520 if (sch_al_cpu_priority[cpu->cpu$b_cur_pri] == 0)
00521 sch_gl_active_priority &= ~(1<<(31-cpu->cpu$b_cur_pri));
00522
00523 cpu->cpu_b_cur_pri=newpri;
00524 p2->pcb_b_pri=newpri;
00525
00526 sch_al_cpu_priority[cpu->cpu$b_cur_pri]=sch$al_cpu_priority[cpu->cpu$b_cur_pri] & (~cpu->cpu$l_cpuid_mask);
00527
00528 if (sch_al_cpu_priority[cpu->cpu$b_cur_pri] == 0)
00529 sch_gl_active_priority &= ~(1<<(31-cpu->cpu$b_cur_pri));
00530
00531 tmppri=ffs(sch_gl_comqs);
00532 tmppri--;
00533
00534 if (newpri>=tmppri) return;
00535 #if 1
00536
00537 if (cpuid != smp_processor_id())
00538 smp_send_work(CPU_M_RESCHED, cpuid);
00539 else
00540 SOFTINT_RESCHED_VECTOR;
00541 #else
00542 sch_gl_idle_cpus &= ~(1<<p->pcb$l_cpu_id);
00543 #endif
00544
00545 }
00546
00547
00548
00549
00550
00551 void sch_one_sec(void) {
00552
00553 sch_pixscan();
00554 }
00555
00556 int sch_waitm(struct _pcb * p, struct _wqh * wq) {
00557
00558 p->pcb_l_waitime=exe$gl_abstim_tics;
00559
00560 if (p->phd_b_astlvl==4) {
00561 sch_sched(0);
00562 return;
00563 }
00564
00565
00566 if (!(p->psl_cur_mod >= p->pr_astlvl)) {
00567 sch_sched(0);
00568 return;
00569 }
00570
00571 {
00572 union {
00573 struct {
00574 unsigned psl_cur_mod:2;
00575 unsigned psl_prv_mod:2;
00576 unsigned psl_ipl:5;
00577 unsigned psl_is:1;
00578 unsigned psl_intr:1;
00579 };
00580 unsigned short psl;
00581 } savpsl;
00582 savpsl.psl=p->pslstk[p->pslindex-1];
00583 if (savpsl.psl_ipl) {
00584 sch_sched(0);
00585 return;
00586 }
00587 }
00588 sch_rse(p,PRI$_NULL,EVT$_AST);
00589 sch_sched(0);
00590 }
00591
00592 int sch_waitl(struct _pcb * p, struct _wqh * wq) {
00593
00594 return sch_waitm(p,wq);
00595 }
00596
00597 int sch_waitk(struct _pcb * p, struct _wqh * wq) {
00598 p->pcb_w_state=wq->wqh$l_wqstate;
00599 p->state=TASK_UNINTERRUPTIBLE;
00600 #if 0
00601 if (!task_on_comqueue(p)) {
00602 panic("toc\n");
00603 }
00604 #endif
00605 #if 0
00606
00607
00608 {
00609 struct _pcb * p3=p->pcb_l_sqfl;
00610 remque(p,0);
00611 qhead_init(p);
00612 if (p3==p3->pcb_l_sqfl) {
00613 sch_gl_comqs&=(~(1 << p->pcb$b_pri));
00614 }
00615 }
00616 #endif
00617 insque(p,&wq->wqh_l_wqfl);
00618
00619 wq->wqh_l_wqcnt++;
00620 return sch_waitl(p,wq);
00621 }
00622
00623 int sch_wait(struct _pcb * p, struct _wqh * wq) {
00624
00625 return sch_waitk(p,wq);
00626 }
00627
00628 void sch_chsep2(struct _pcb * p,unsigned char newpri) {
00629 int ipl = getipl();
00630 if (ipl != 8 || SPIN_SCHED.spl_l_spinlock == 0)
00631 panic("rse %x %x\n",ipl,SPIN_SCHED.spl_l_spinlock);
00632 struct _pcb * p2, *p3 , *dummy;
00633 p3=p->pcb_l_sqfl;
00634 p2=p;
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644 p->pcb_b_pri=newpri;
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663 p2->state=TASK_RUNNING;
00664 p2->pcb_w_state = SCH$C_CUR;
00665 mycheckaddr(0);
00666 #ifdef __i386__
00667 insque(p2,*(unsigned long *)&sch_aq_comt[newpri]);
00668 #else
00669 insque(p2,*(unsigned long *)&sch_aq_comh[newpri][1]);
00670 #endif
00671 sch_gl_comqs|=(1 << newpri);
00672 mycheckaddr(0);
00673 }
00674
00675
00676 void sch_chse2(struct _pcb * p, unsigned char class) {
00677 unsigned char pri=0,newpri;
00678
00679 switch (class) {
00680 case PRI__NULL:
00681 pri=0;
00682 break;
00683 case PRI__IOCOM:
00684 pri=2;
00685 break;
00686 case PRI__TIMER:
00687 case PRI__RESAVL:
00688 pri=3;
00689 break;
00690 case PRI__TOCOM:
00691 pri=4;
00692 break;
00693 case PRI__TICOM:
00694 pri=6;
00695 break;
00696 }
00697 newpri=p->pcb_b_prib-pri;
00698 if (newpri>p->pcb_b_pri) newpri=p->pcb$b_pri;
00699 if (p->pcb_b_pri<16) p->pcb$b_pri=p->pcb$b_prib;
00700 sch_chsep2(p,newpri);
00701 }
00702
00703 void sch_unwait(struct _pcb * p) {
00704
00705 }
00706