32 |
32 |
33 ProcessorScheduler comment:' |
33 ProcessorScheduler comment:' |
34 COPYRIGHT (c) 1993 by Claus Gittinger |
34 COPYRIGHT (c) 1993 by Claus Gittinger |
35 All Rights Reserved |
35 All Rights Reserved |
36 |
36 |
37 $Header: /cvs/stx/stx/libbasic/ProcessorScheduler.st,v 1.37 1995-05-04 12:48:05 claus Exp $ |
37 $Header: /cvs/stx/stx/libbasic/ProcessorScheduler.st,v 1.38 1995-05-08 03:30:32 claus Exp $ |
38 '! |
38 '! |
39 |
39 |
40 Smalltalk at:#Processor put:nil! |
40 Smalltalk at:#Processor put:nil! |
41 |
41 |
42 !ProcessorScheduler class methodsFor:'documentation'! |
42 !ProcessorScheduler class methodsFor:'documentation'! |
256 __threadInterrupt(_intVal(id)); |
256 __threadInterrupt(_intVal(id)); |
257 } |
257 } |
258 %} |
258 %} |
259 ! |
259 ! |
260 |
260 |
261 threadCreate:aProcess |
261 threadCreate:aProcess withId:id |
262 "physical creation of a process. |
262 "physical creation of a process. |
263 (warning: low level entry, no administration done). |
263 (warning: low level entry, no administration done). |
264 This may return nil, if a VM process could not be created." |
264 This may raise an exception, if a VM process could not be created." |
265 |
265 |
266 %{ /* NOCONTEXT */ |
266 %{ /* NOCONTEXT */ |
267 int tid; |
267 int tid; |
268 extern int __threadCreate(); |
268 extern int __threadCreate(); |
269 |
269 |
270 tid = __threadCreate(aProcess, 0 /* stackSize no longer needed */); |
270 tid = __threadCreate(aProcess, |
271 if (tid != 0) { |
271 0 /* stackSize: no longer needed */, |
|
272 __isSmallInteger(id) ? _intVal(id) /* assign id */ |
|
273 : -1 /* let VM assign one */ ); |
|
274 if (tid) { |
272 RETURN ( _MKSMALLINT(tid)); |
275 RETURN ( _MKSMALLINT(tid)); |
273 } |
276 } |
274 %} |
277 %} |
275 . |
278 . |
276 " |
279 " |
525 KnownProcesses do:[:p | |
528 KnownProcesses do:[:p | |
526 p notNil ifTrue:[ |
529 p notNil ifTrue:[ |
527 "how, exactly should this be done ?" |
530 "how, exactly should this be done ?" |
528 |
531 |
529 p isRestartable == true ifTrue:[ |
532 p isRestartable == true ifTrue:[ |
|
533 p nextLink:nil. |
530 processesToRestart add:p |
534 processesToRestart add:p |
531 ]. |
535 ] ifFalse:[ |
532 p setId:nil state:#dead |
536 p setId:nil state:#dead |
|
537 ] |
533 ]. |
538 ]. |
534 scheduler setId:nil state:#dead |
539 scheduler setId:nil state:#dead |
535 ]. |
540 ]. |
|
541 scheduler setId:nil state:#dead. |
536 |
542 |
537 " |
543 " |
538 now, start from scratch |
544 now, start from scratch |
539 " |
545 " |
540 KnownProcesses := nil. |
546 KnownProcesses := nil. |
605 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
611 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
606 ! ! |
612 ! ! |
607 |
613 |
608 !ProcessorScheduler methodsFor:'process creation'! |
614 !ProcessorScheduler methodsFor:'process creation'! |
609 |
615 |
|
616 newProcessFor:aProcess withId:idWant |
|
617 "private entry for Process restart - do not use in your program" |
|
618 |
|
619 |id| |
|
620 |
|
621 (self class threadCreate:aProcess withId:idWant) ~~ idWant ifTrue:[ |
|
622 ^ false |
|
623 ]. |
|
624 |
|
625 aProcess state:#light. "meaning: has no stack yet" |
|
626 self remember:aProcess. |
|
627 ^ true |
|
628 ! |
|
629 |
610 newProcessFor:aProcess |
630 newProcessFor:aProcess |
611 "create a physical (VM-) process for aProcess. |
631 "create a physical (VM-) process for aProcess. |
612 Return true if ok, false if something went wrong. |
632 Return true if ok, false if something went wrong. |
613 The process is not scheduled; to start it running, it needs a Process>>resume." |
633 The process is not scheduled; to start it running, |
|
634 it needs a Process>>resume. Once resumed, the process will later |
|
635 get control in its #start method." |
614 |
636 |
615 |id| |
637 |id| |
616 |
638 |
617 id := self class threadCreate:aProcess. |
639 id := self class threadCreate:aProcess withId:nil. |
618 id isNil ifTrue:[^ false]. |
640 id isNil ifTrue:[^ false]. |
619 |
641 |
620 aProcess setId:id state:#light. "meaning: has no stack yet" |
642 aProcess setId:id state:#light. "meaning: has no stack yet" |
621 self remember:aProcess. |
643 self remember:aProcess. |
622 ^ true |
644 ^ true |
691 MiniDebugger enterWithMessage:'bad suspend: already dead'. |
713 MiniDebugger enterWithMessage:'bad suspend: already dead'. |
692 self threadSwitch:scheduler. |
714 self threadSwitch:scheduler. |
693 ^ self |
715 ^ self |
694 ]. |
716 ]. |
695 aProcess == scheduler ifTrue:[ |
717 aProcess == scheduler ifTrue:[ |
696 'scheduler should never be suspended' printNL. |
718 'scheduler should never be suspended' errorPrintNL. |
697 MiniDebugger enterWithMessage:'scheduler should never be suspended'. |
719 MiniDebugger enterWithMessage:'scheduler should never be suspended'. |
698 ^ self |
720 ^ self |
699 ]. |
721 ]. |
700 |
722 |
701 wasBlocked := OperatingSystem blockInterrupts. |
723 wasBlocked := OperatingSystem blockInterrupts. |
707 debugging consisteny checks - will be removed later |
729 debugging consisteny checks - will be removed later |
708 " |
730 " |
709 l isNil ifTrue:[ |
731 l isNil ifTrue:[ |
710 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
732 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
711 |
733 |
712 'bad suspend: empty run list' printNL. |
734 'bad suspend: empty run list' errorPrintNL. |
713 "/ MiniDebugger enterWithMessage:'bad suspend: empty run list'. |
735 "/ MiniDebugger enterWithMessage:'bad suspend: empty run list'. |
714 self threadSwitch:scheduler. |
736 self threadSwitch:scheduler. |
715 ^ self |
737 ^ self |
716 ]. |
738 ]. |
717 |
739 |
718 "notice: this is slightly faster than putting the if-code into |
740 "notice: this is slightly faster than putting the if-code into |
719 the ifAbsent block, because [] is a shared cheap block |
741 the ifAbsent block, because [] is a shared cheap block |
720 " |
742 " |
721 (l remove:aProcess ifAbsent:[]) isNil ifTrue:[ |
743 (l remove:aProcess ifAbsent:[]) isNil ifTrue:[ |
722 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
744 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
723 'bad suspend: not on run list' printNL. |
745 'bad suspend: not on run list' errorPrintNL. |
724 "/ MiniDebugger enterWithMessage:'bad suspend: not on run list'. |
746 "/ MiniDebugger enterWithMessage:'bad suspend: not on run list'. |
725 self threadSwitch:scheduler. |
747 self threadSwitch:scheduler. |
726 ^ self |
748 ^ self |
727 ]. |
749 ]. |
728 |
750 |
981 !ProcessorScheduler methodsFor:'queries'! |
1003 !ProcessorScheduler methodsFor:'queries'! |
982 |
1004 |
983 highestPriorityRunnableProcess |
1005 highestPriorityRunnableProcess |
984 "return the highest prio runnable process" |
1006 "return the highest prio runnable process" |
985 |
1007 |
986 |listArray l p maxPri "{ Class: SmallInteger }" | |
1008 |listArray l p prio "{ Class: SmallInteger }" | |
987 |
1009 |
988 maxPri := HighestPriority. |
1010 prio := HighestPriority. |
989 listArray := quiescentProcessLists. |
1011 listArray := quiescentProcessLists. |
990 maxPri to:1 by:-1 do:[:prio | |
1012 [prio >= 1] whileTrue:[ |
991 l := listArray at:prio. |
1013 l := listArray at:prio. |
992 l notNil ifTrue:[ |
1014 l notNil ifTrue:[ |
993 l isEmpty ifTrue:[ |
1015 l isEmpty ifTrue:[ |
994 " |
1016 " |
995 on the fly clear out empty lists |
1017 on the fly clear out empty lists |
996 " |
1018 " |
997 listArray at:prio put:nil |
1019 listArray at:prio put:nil |
998 ] ifFalse:[ |
1020 ] ifFalse:[ |
999 p := l first. |
1021 p := l first. |
1000 " |
1022 " |
1001 if it got corrupted somehow |
1023 if it got corrupted somehow ... |
1002 " |
1024 " |
1003 p id isNil ifTrue:[ |
1025 p id isNil ifTrue:[ |
1004 'process with nil id removed' printNL. |
1026 'process with nil id removed' errorPrintNL. |
1005 l removeFirst. |
1027 l removeFirst. |
1006 ^ nil. |
1028 ^ nil. |
1007 ]. |
1029 ]. |
1008 ^ p |
1030 ^ p |
1009 ]. |
1031 ]. |
1010 ] |
1032 ]. |
|
1033 prio := prio - 1 |
1011 ]. |
1034 ]. |
1012 ^ nil |
1035 ^ nil |
1013 ! |
1036 ! |
1014 |
1037 |
1015 isSystemProcess:aProcess |
1038 isSystemProcess:aProcess |