416 wasBlocked| |
418 wasBlocked| |
417 |
419 |
418 wasBlocked := OperatingSystem blockInterrupts. |
420 wasBlocked := OperatingSystem blockInterrupts. |
419 idx := readFdArray identityIndexOf:aFileDescriptor startingAt:1. |
421 idx := readFdArray identityIndexOf:aFileDescriptor startingAt:1. |
420 idx ~~ 0 ifTrue:[ |
422 idx ~~ 0 ifTrue:[ |
421 readFdArray at:idx put:nil. |
423 useIOInterrupts ifTrue:[ |
422 readCheckArray at:idx put:nil. |
424 OperatingSystem disableIOInterruptsOn:aFileDescriptor |
423 readSemaphoreArray at:idx put:nil |
425 ]. |
|
426 readFdArray at:idx put:nil. |
|
427 readCheckArray at:idx put:nil. |
|
428 readSemaphoreArray at:idx put:nil |
424 ]. |
429 ]. |
425 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
430 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
|
431 |
|
432 "Modified: 4.8.1997 / 15:16:00 / cg" |
426 ! |
433 ! |
427 |
434 |
428 enableIOAction:aBlock onInput:aFileDescriptor |
435 enableIOAction:aBlock onInput:aFileDescriptor |
429 "half-obsolete event support: arrange for aBlock to be |
436 "half-obsolete event support: arrange for aBlock to be |
430 evaluated when input on aFileDescriptor arrives. |
437 evaluated when input on aFileDescriptor arrives. |
433 |idx "{Class: SmallInteger }" |
440 |idx "{Class: SmallInteger }" |
434 wasBlocked| |
441 wasBlocked| |
435 |
442 |
436 wasBlocked := OperatingSystem blockInterrupts. |
443 wasBlocked := OperatingSystem blockInterrupts. |
437 (readFdArray identityIndexOf:aFileDescriptor startingAt:1) == 0 ifTrue:[ |
444 (readFdArray identityIndexOf:aFileDescriptor startingAt:1) == 0 ifTrue:[ |
438 idx := readFdArray identityIndexOf:nil startingAt:1. |
445 idx := readFdArray identityIndexOf:nil startingAt:1. |
439 idx ~~ 0 ifTrue:[ |
446 idx ~~ 0 ifTrue:[ |
440 readFdArray at:idx put:aFileDescriptor. |
447 readFdArray at:idx put:aFileDescriptor. |
441 readCheckArray at:idx put:aBlock. |
448 readCheckArray at:idx put:aBlock. |
442 readSemaphoreArray at:idx put:nil |
449 readSemaphoreArray at:idx put:nil |
443 ] ifFalse:[ |
450 ] ifFalse:[ |
444 readFdArray := readFdArray copyWith:aFileDescriptor. |
451 readFdArray := readFdArray copyWith:aFileDescriptor. |
445 readCheckArray := readCheckArray copyWith:aBlock. |
452 readCheckArray := readCheckArray copyWith:aBlock. |
446 readSemaphoreArray := readSemaphoreArray copyWith:nil. |
453 readSemaphoreArray := readSemaphoreArray copyWith:nil. |
447 ] |
454 ]. |
|
455 useIOInterrupts ifTrue:[ |
|
456 OperatingSystem enableIOInterruptsOn:aFileDescriptor |
|
457 ]. |
|
458 |
448 ]. |
459 ]. |
449 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
460 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
|
461 |
|
462 "Modified: 4.8.1997 / 15:17:28 / cg" |
450 ! ! |
463 ! ! |
451 |
464 |
452 !ProcessorScheduler methodsFor:'accessing'! |
465 !ProcessorScheduler methodsFor:'accessing'! |
453 |
466 |
454 activePriority |
467 activePriority |
535 |
548 |
536 " |
549 " |
537 handle all timeout actions |
550 handle all timeout actions |
538 " |
551 " |
539 anyTimeouts ifTrue:[ |
552 anyTimeouts ifTrue:[ |
540 self evaluateTimeouts |
553 self evaluateTimeouts |
541 ]. |
554 ]. |
542 |
555 |
543 "first do a quick check for semaphores using checkActions - this is needed for |
556 "first do a quick check for semaphores using checkActions - this is needed for |
544 devices like the X-connection, where some events might be in the event |
557 devices like the X-connection, where some events might be in the event |
545 queue but the sockets input queue is empty. |
558 queue but the sockets input queue is empty. |
546 Without these checks, a select might block even though there is work to do |
559 Without these checks, a select might block even though there is work to do |
547 " |
560 " |
548 any := false. |
561 any := false. |
549 nActions := readCheckArray size. |
562 nActions := readCheckArray size. |
550 1 to:nActions do:[:index | |
563 1 to:nActions do:[:index | |
551 checkBlock := readCheckArray at:index. |
564 checkBlock := readCheckArray at:index. |
552 (checkBlock notNil and:[checkBlock value]) ifTrue:[ |
565 (checkBlock notNil and:[checkBlock value]) ifTrue:[ |
553 sema := readSemaphoreArray at:index. |
566 sema := readSemaphoreArray at:index. |
554 sema notNil ifTrue:[ |
567 sema notNil ifTrue:[ |
555 sema signalOnce. |
568 sema signalOnce. |
556 ]. |
569 ]. |
557 any := true. |
570 any := true. |
558 ] |
571 ] |
559 ]. |
572 ]. |
560 |
573 |
561 "now, someone might be runnable ..." |
574 "now, someone might be runnable ..." |
562 |
575 |
563 p := self highestPriorityRunnableProcess. |
576 p := self highestPriorityRunnableProcess. |
564 p isNil ifTrue:[ |
577 p isNil ifTrue:[ |
565 "/ no one runnable, hard wait for event or timeout |
578 "/ no one runnable, hard wait for event or timeout |
566 |
579 |
567 self waitForEventOrTimeout. |
580 self waitForEventOrTimeout. |
568 |
581 |
569 "/ check for OS process termination |
582 "/ check for OS process termination |
570 gotChildSignalInterrupt ifTrue:[ |
583 gotChildSignalInterrupt ifTrue:[ |
571 gotChildSignalInterrupt := false. |
584 gotChildSignalInterrupt := false. |
572 self handleChildSignalInterrupt |
585 self handleChildSignalInterrupt |
573 ]. |
586 ]. |
574 ^ self |
587 ^ self |
575 ]. |
588 ]. |
576 |
589 |
577 pri := p priority. |
590 pri := p priority. |
578 |
591 |
579 " |
592 " |
616 or by installing a poll-interrupt after 50ms (if the OS does not). |
629 or by installing a poll-interrupt after 50ms (if the OS does not). |
617 " |
630 " |
618 pri < UserInterruptPriority ifTrue:[ |
631 pri < UserInterruptPriority ifTrue:[ |
619 |
632 |
620 "comment out this if above is uncommented" |
633 "comment out this if above is uncommented" |
621 anyTimeouts ifTrue:[ |
634 anyTimeouts ifTrue:[ |
622 millis := self timeToNextTimeout. |
635 millis := self timeToNextTimeout. |
623 millis == 0 ifTrue:[^ self]. |
636 millis == 0 ifTrue:[^ self]. |
624 ]. |
637 ]. |
625 "---" |
638 "---" |
626 |
639 |
627 useIOInterrupts ifTrue:[ |
640 useIOInterrupts ifTrue:[ |
628 readFdArray do:[:fd | |
641 "/ readFdArray do:[:fd | |
629 (fd notNil and:[fd >= 0]) ifTrue:[ |
642 "/ (fd notNil and:[fd >= 0]) ifTrue:[ |
630 OperatingSystem enableIOInterruptsOn:fd |
643 "/ OperatingSystem enableIOInterruptsOn:fd |
631 ]. |
644 "/ ]. |
632 ]. |
645 "/ ]. |
633 ] ifFalse:[ |
646 ] ifFalse:[ |
634 millis notNil ifTrue:[ |
647 millis notNil ifTrue:[ |
635 millis := millis min:EventPollingInterval |
648 millis := millis min:EventPollingInterval |
636 ] ifFalse:[ |
649 ] ifFalse:[ |
637 millis := EventPollingInterval |
650 millis := EventPollingInterval |
638 ] |
651 ] |
639 ] |
652 ] |
640 ]. |
653 ]. |
641 |
654 |
642 millis notNil ifTrue:[ |
655 millis notNil ifTrue:[ |
643 "schedule a clock interrupt after millis milliseconds" |
656 "schedule a clock interrupt after millis milliseconds" |
644 OperatingSystem enableTimer:millis rounded. |
657 OperatingSystem enableTimer:millis rounded. |
645 ]. |
658 ]. |
646 |
659 |
647 " |
660 " |
648 now let the process run - will come back here by reschedule |
661 now let the process run - will come back here by reschedule |
649 from ioInterrupt or timerInterrupt ... (running at max+1) |
662 from ioInterrupt or timerInterrupt ... (running at max+1) |
650 " |
663 " |
651 self threadSwitch:p. |
664 self threadSwitch:p. |
652 |
665 |
653 "... when we arrive here, we are back on stage. |
666 "... when we arrive here, we are back on stage. |
654 Either by an ALARM or IO signal, or by a suspend of another process |
667 Either by an ALARM or IO signal, or by a suspend of another process |
655 " |
668 " |
656 |
669 |
657 millis notNil ifTrue:[ |
670 millis notNil ifTrue:[ |
658 OperatingSystem disableTimer. |
671 OperatingSystem disableTimer. |
659 ]. |
672 ]. |
660 |
673 |
661 "/ check for OS process termination |
674 "/ check for OS process termination |
662 gotChildSignalInterrupt ifTrue:[ |
675 gotChildSignalInterrupt ifTrue:[ |
663 gotChildSignalInterrupt := false. |
676 gotChildSignalInterrupt := false. |
664 self handleChildSignalInterrupt |
677 self handleChildSignalInterrupt |
665 ]. |
678 ]. |
666 |
679 |
667 "/ check for new input |
680 "/ check for new input |
668 |
681 |
669 (gotIOInterrupt or:[useIOInterrupts not]) ifTrue:[ |
682 (gotIOInterrupt or:[useIOInterrupts not]) ifTrue:[ |
670 gotIOInterrupt := false. |
683 gotIOInterrupt := false. |
671 self checkForInputWithTimeout:0. |
684 self checkForInputWithTimeout:0. |
672 ] |
685 ] |
673 |
686 |
674 "Modified: 12.4.1996 / 10:14:18 / stefan" |
687 "Modified: 12.4.1996 / 10:14:18 / stefan" |
675 "Modified: 9.1.1997 / 16:12:44 / cg" |
688 "Modified: 4.8.1997 / 15:34:09 / cg" |
676 ! |
689 ! |
677 |
690 |
678 dispatchLoop |
691 dispatchLoop |
679 "central dispatch loop; the scheduler process is always staying in |
692 "central dispatch loop; the scheduler process is always staying in |
680 this method, looping forever." |
693 this method, looping forever." |
1757 "start preemptive scheduling (timeSlicing)" |
1770 "start preemptive scheduling (timeSlicing)" |
1758 |
1771 |
1759 timeSliceProcess notNil ifTrue: [^ self]. |
1772 timeSliceProcess notNil ifTrue: [^ self]. |
1760 |
1773 |
1761 timeSliceProcess := [ |
1774 timeSliceProcess := [ |
1762 [ |
1775 [ |
1763 |myDelay t| |
1776 |myDelay t| |
1764 |
1777 |
1765 myDelay := Delay forMilliseconds:(t := TimeSliceInterval). |
1778 myDelay := Delay forMilliseconds:(t := TimeSliceInterval). |
1766 |
1779 |
1767 [true] whileTrue: [ |
1780 [true] whileTrue: [ |
1768 t ~~ TimeSliceInterval ifTrue:[ |
1781 t ~~ TimeSliceInterval ifTrue:[ |
1769 "/ interval changed -> need a new delay |
1782 "/ interval changed -> need a new delay |
1770 myDelay delay:(t := TimeSliceInterval). |
1783 myDelay delay:(t := TimeSliceInterval). |
1771 ]. |
1784 ]. |
1772 myDelay wait. |
1785 myDelay wait. |
1773 self slice |
1786 self slice |
1774 ] |
1787 ] |
1775 ] valueOnUnwindDo:[ |
1788 ] valueOnUnwindDo:[ |
1776 timeSliceProcess := nil |
1789 timeSliceProcess := nil |
1777 ] |
1790 ] |
1778 ] newProcess. |
1791 ] newProcess. |
1779 timeSliceProcess priority:HighestPriority. |
1792 timeSliceProcess priority:HighestPriority. |
1780 timeSliceProcess name:'time slicer'. |
1793 timeSliceProcess name:'time slicer'. |
|
1794 timeSliceProcess restartable:true. |
1781 timeSliceProcess beSystemProcess. |
1795 timeSliceProcess beSystemProcess. |
1782 timeSliceProcess resume. |
1796 timeSliceProcess resume. |
1783 |
1797 |
1784 " |
1798 " |
1785 Processor stopTimeSlicing. |
1799 Processor stopTimeSlicing. |
1786 Processor startTimeSlicing. |
1800 Processor startTimeSlicing. |
1787 " |
1801 " |
1788 |
1802 |
1789 "Created: 17.1.1997 / 16:42:02 / cg" |
1803 "Created: 17.1.1997 / 16:42:02 / cg" |
1790 "Modified: 24.1.1997 / 21:34:24 / cg" |
1804 "Modified: 4.8.1997 / 15:10:44 / cg" |
1791 ! |
1805 ! |
1792 |
1806 |
1793 stopTimeSlicing |
1807 stopTimeSlicing |
1794 "stop preemptive scheduling (timeSlicing)" |
1808 "stop preemptive scheduling (timeSlicing)" |
1795 |
1809 |
1796 timeSliceProcess notNil ifTrue: [ |
1810 timeSliceProcess notNil ifTrue: [ |
1797 timeSliceProcess terminate. |
1811 timeSliceProcess terminate. |
|
1812 timeSliceProcess := nil. |
1798 ] |
1813 ] |
1799 |
1814 |
1800 " |
1815 " |
1801 Processor stopTimeSlicing |
1816 Processor stopTimeSlicing |
1802 " |
1817 " |
1803 |
1818 |
1804 "Created: 17.1.1997 / 16:43:03 / cg" |
1819 "Created: 17.1.1997 / 16:43:03 / cg" |
1805 "Modified: 17.1.1997 / 16:43:42 / cg" |
1820 "Modified: 4.8.1997 / 14:27:45 / cg" |
1806 ! ! |
1821 ! ! |
1807 |
1822 |
1808 !ProcessorScheduler methodsFor:'semaphore signalling'! |
1823 !ProcessorScheduler methodsFor:'semaphore signalling'! |
1809 |
1824 |
1810 disableSemaphore:aSemaphore |
1825 disableSemaphore:aSemaphore |
1811 "disable triggering of a semaphore" |
1826 "disable triggering of a semaphore" |
1812 |
1827 |
1813 |idx "{ Class: SmallInteger }" |
1828 |idx "{ Class: SmallInteger }" |
1814 wasBlocked| |
1829 wasBlocked fd| |
1815 |
1830 |
1816 wasBlocked := OperatingSystem blockInterrupts. |
1831 wasBlocked := OperatingSystem blockInterrupts. |
1817 idx := readSemaphoreArray identityIndexOf:aSemaphore startingAt:1. |
1832 idx := readSemaphoreArray identityIndexOf:aSemaphore startingAt:1. |
1818 [idx ~~ 0] whileTrue:[ |
1833 [idx ~~ 0] whileTrue:[ |
1819 readFdArray at:idx put:nil. |
1834 useIOInterrupts ifTrue:[ |
1820 readSemaphoreArray at:idx put:nil. |
1835 fd := readFdArray at:idx. |
1821 readCheckArray at:idx put:nil. |
1836 fd notNil ifTrue:[ |
1822 idx := readSemaphoreArray identityIndexOf:aSemaphore startingAt:idx. |
1837 OperatingSystem disableIOInterruptsOn:fd |
|
1838 ]. |
|
1839 ]. |
|
1840 readFdArray at:idx put:nil. |
|
1841 readSemaphoreArray at:idx put:nil. |
|
1842 readCheckArray at:idx put:nil. |
|
1843 idx := readSemaphoreArray identityIndexOf:aSemaphore startingAt:idx. |
1823 ]. |
1844 ]. |
1824 idx := writeSemaphoreArray identityIndexOf:aSemaphore startingAt:1. |
1845 idx := writeSemaphoreArray identityIndexOf:aSemaphore startingAt:1. |
1825 [idx ~~ 0] whileTrue:[ |
1846 [idx ~~ 0] whileTrue:[ |
1826 writeFdArray at:idx put:nil. |
1847 useIOInterrupts ifTrue:[ |
1827 writeSemaphoreArray at:idx put:nil. |
1848 fd := writeFdArray at:idx. |
1828 idx := writeSemaphoreArray identityIndexOf:aSemaphore startingAt:idx. |
1849 fd notNil ifTrue:[ |
|
1850 OperatingSystem disableIOInterruptsOn:fd |
|
1851 ]. |
|
1852 ]. |
|
1853 writeFdArray at:idx put:nil. |
|
1854 writeSemaphoreArray at:idx put:nil. |
|
1855 idx := writeSemaphoreArray identityIndexOf:aSemaphore startingAt:idx. |
1829 ]. |
1856 ]. |
1830 idx := timeoutSemaphoreArray identityIndexOf:aSemaphore startingAt:1. |
1857 idx := timeoutSemaphoreArray identityIndexOf:aSemaphore startingAt:1. |
1831 [idx ~~ 0] whileTrue:[ |
1858 [idx ~~ 0] whileTrue:[ |
1832 timeoutArray at:idx put:nil. |
1859 timeoutArray at:idx put:nil. |
1833 timeoutSemaphoreArray at:idx put:nil. |
1860 timeoutSemaphoreArray at:idx put:nil. |
1834 timeoutActionArray at:idx put:nil. |
1861 timeoutActionArray at:idx put:nil. |
1835 timeoutProcessArray at:idx put:nil. |
1862 timeoutProcessArray at:idx put:nil. |
1836 idx := timeoutSemaphoreArray identityIndexOf:aSemaphore startingAt:idx. |
1863 idx := timeoutSemaphoreArray identityIndexOf:aSemaphore startingAt:idx. |
1837 ]. |
1864 ]. |
1838 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1865 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
|
1866 |
|
1867 "Modified: 4.8.1997 / 15:19:33 / cg" |
1839 ! |
1868 ! |
1840 |
1869 |
1841 signal:aSemaphore |
1870 signal:aSemaphore |
1842 "arrange for a semaphore to be triggered as soon as possible. |
1871 "arrange for a semaphore to be triggered as soon as possible. |
1843 The actual signalling is performed slightly delayed, when the dispatcher |
1872 The actual signalling is performed slightly delayed, when the dispatcher |
1926 |
1955 |
1927 |idx "{ Class: SmallInteger }" |
1956 |idx "{ Class: SmallInteger }" |
1928 wasBlocked| |
1957 wasBlocked| |
1929 |
1958 |
1930 aFileDescriptor isNil ifTrue:[ |
1959 aFileDescriptor isNil ifTrue:[ |
1931 'ProcessorScheduler [info]: no fd to select on - polling with checkBlock' infoPrintCR |
1960 'ProcessorScheduler [info]: no fd to select on - polling with checkBlock' infoPrintCR |
1932 ]. |
1961 ]. |
1933 |
1962 |
1934 wasBlocked := OperatingSystem blockInterrupts. |
1963 wasBlocked := OperatingSystem blockInterrupts. |
1935 (readFdArray identityIndexOf:aFileDescriptor startingAt:1) == 0 ifTrue:[ |
1964 (readFdArray identityIndexOf:aFileDescriptor startingAt:1) == 0 ifTrue:[ |
1936 idx := readFdArray identityIndexOf:nil startingAt:1. |
1965 idx := readFdArray identityIndexOf:nil startingAt:1. |
1937 idx ~~ 0 ifTrue:[ |
1966 idx ~~ 0 ifTrue:[ |
1938 readFdArray at:idx put:aFileDescriptor. |
1967 readFdArray at:idx put:aFileDescriptor. |
1939 readSemaphoreArray at:idx put:aSemaphore. |
1968 readSemaphoreArray at:idx put:aSemaphore. |
1940 readCheckArray at:idx put:aBlock |
1969 readCheckArray at:idx put:aBlock |
1941 ] ifFalse:[ |
1970 ] ifFalse:[ |
1942 readFdArray := readFdArray copyWith:aFileDescriptor. |
1971 readFdArray := readFdArray copyWith:aFileDescriptor. |
1943 readSemaphoreArray := readSemaphoreArray copyWith:aSemaphore. |
1972 readSemaphoreArray := readSemaphoreArray copyWith:aSemaphore. |
1944 readCheckArray := readCheckArray copyWith:aBlock. |
1973 readCheckArray := readCheckArray copyWith:aBlock. |
1945 ] |
1974 ]. |
|
1975 useIOInterrupts ifTrue:[ |
|
1976 OperatingSystem enableIOInterruptsOn:aFileDescriptor |
|
1977 ]. |
|
1978 |
1946 ]. |
1979 ]. |
1947 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1980 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1948 |
1981 |
1949 "Modified: 10.1.1997 / 15:09:41 / cg" |
1982 "Modified: 4.8.1997 / 15:20:45 / cg" |
1950 ! |
1983 ! |
1951 |
1984 |
1952 signal:aSemaphore onOutput:aFileDescriptor |
1985 signal:aSemaphore onOutput:aFileDescriptor |
1953 "arrange for a semaphore to be triggered when output on aFileDescriptor |
1986 "arrange for a semaphore to be triggered when output on aFileDescriptor |
1954 is possible. (i.e. can be written without blocking). |
1987 is possible. (i.e. can be written without blocking). |
1957 |idx "{ Class: SmallInteger }" |
1990 |idx "{ Class: SmallInteger }" |
1958 wasBlocked| |
1991 wasBlocked| |
1959 |
1992 |
1960 wasBlocked := OperatingSystem blockInterrupts. |
1993 wasBlocked := OperatingSystem blockInterrupts. |
1961 (writeFdArray identityIndexOf:aFileDescriptor startingAt:1) == 0 ifTrue:[ |
1994 (writeFdArray identityIndexOf:aFileDescriptor startingAt:1) == 0 ifTrue:[ |
1962 idx := writeFdArray identityIndexOf:nil startingAt:1. |
1995 idx := writeFdArray identityIndexOf:nil startingAt:1. |
1963 idx ~~ 0 ifTrue:[ |
1996 idx ~~ 0 ifTrue:[ |
1964 writeFdArray at:idx put:aFileDescriptor. |
1997 writeFdArray at:idx put:aFileDescriptor. |
1965 writeSemaphoreArray at:idx put:aSemaphore. |
1998 writeSemaphoreArray at:idx put:aSemaphore. |
1966 ] ifFalse:[ |
1999 ] ifFalse:[ |
1967 writeFdArray := writeFdArray copyWith:aFileDescriptor. |
2000 writeFdArray := writeFdArray copyWith:aFileDescriptor. |
1968 writeSemaphoreArray := writeSemaphoreArray copyWith:aSemaphore. |
2001 writeSemaphoreArray := writeSemaphoreArray copyWith:aSemaphore. |
1969 ] |
2002 ]. |
|
2003 useIOInterrupts ifTrue:[ |
|
2004 OperatingSystem enableIOInterruptsOn:aFileDescriptor |
|
2005 ]. |
|
2006 |
1970 ]. |
2007 ]. |
1971 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2008 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
|
2009 |
|
2010 "Modified: 4.8.1997 / 15:21:49 / cg" |
1972 ! ! |
2011 ! ! |
1973 |
2012 |
1974 !ProcessorScheduler methodsFor:'timeout handling'! |
2013 !ProcessorScheduler methodsFor:'timeout handling'! |
1975 |
2014 |
1976 addTimedBlock:aBlock afterMilliseconds:delta |
2015 addTimedBlock:aBlock afterMilliseconds:delta |