656 Also, this is needed for poor MSDOS, where WaitForObject does not work with |
677 Also, this is needed for poor MSDOS, where WaitForObject does not work with |
657 sockets and pipes (sigh) |
678 sockets and pipes (sigh) |
658 " |
679 " |
659 nActions := readCheckArray size. |
680 nActions := readCheckArray size. |
660 1 to:nActions do:[:index | |
681 1 to:nActions do:[:index | |
661 checkBlock := readCheckArray at:index. |
682 checkBlock := readCheckArray at:index. |
662 (checkBlock notNil and:[checkBlock value]) ifTrue:[ |
683 (checkBlock notNil and:[checkBlock value]) ifTrue:[ |
663 sema := readSemaphoreArray at:index. |
684 sema := readSemaphoreArray at:index. |
664 sema notNil ifTrue:[ |
685 sema notNil ifTrue:[ |
665 sema signalOnce. |
686 sema signalOnce. |
666 ]. |
687 ]. |
667 ] |
688 ] |
668 ]. |
689 ]. |
669 nActions := writeCheckArray size. |
690 nActions := writeCheckArray size. |
670 1 to:nActions do:[:index | |
691 1 to:nActions do:[:index | |
671 checkBlock := writeCheckArray at:index. |
692 checkBlock := writeCheckArray at:index. |
672 (checkBlock notNil and:[checkBlock value]) ifTrue:[ |
693 (checkBlock notNil and:[checkBlock value]) ifTrue:[ |
673 sema := writeSemaphoreArray at:index. |
694 sema := writeSemaphoreArray at:index. |
674 sema notNil ifTrue:[ |
695 sema notNil ifTrue:[ |
675 sema signalOnce. |
696 sema signalOnce. |
676 ]. |
697 ]. |
677 ] |
698 ] |
678 ]. |
699 ]. |
679 |
700 |
680 "now, someone might be runnable ..." |
701 "now, someone might be runnable ..." |
681 |
702 |
682 p := self highestPriorityRunnableProcess. |
703 p := self highestPriorityRunnableProcess. |
683 p isNil ifTrue:[ |
704 p isNil ifTrue:[ |
684 "/ no one runnable, hard wait for event or timeout |
705 "/ no one runnable, hard wait for event or timeout |
685 "/ Trace ifTrue:['w' printCR.]. |
706 "/ Trace ifTrue:['w' printCR.]. |
686 self waitForEventOrTimeout. |
707 self waitForEventOrTimeout. |
687 |
708 |
688 "/ check for OS process termination |
709 "/ check for OS process termination |
689 gotChildSignalInterrupt ifTrue:[ |
710 gotChildSignalInterrupt ifTrue:[ |
690 gotChildSignalInterrupt := false. |
711 gotChildSignalInterrupt := false. |
691 self handleChildSignalInterrupt |
712 self handleChildSignalInterrupt |
692 ]. |
713 ]. |
693 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
714 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
694 ^ self |
715 ^ self |
695 ]. |
716 ]. |
696 |
717 |
697 pri := p priority. |
718 pri := p priority. |
698 |
719 |
699 " |
720 " |
739 or by installing a poll-interrupt after 50ms (if the OS does not). |
760 or by installing a poll-interrupt after 50ms (if the OS does not). |
740 " |
761 " |
741 pri < UserInterruptPriority ifTrue:[ |
762 pri < UserInterruptPriority ifTrue:[ |
742 |
763 |
743 "comment out this if above is uncommented" |
764 "comment out this if above is uncommented" |
744 anyTimeouts ifTrue:[ |
765 anyTimeouts ifTrue:[ |
745 millis := self timeToNextTimeout. |
766 millis := self timeToNextTimeout. |
746 millis == 0 ifTrue:[ |
767 millis == 0 ifTrue:[ |
747 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
768 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
748 ^ self |
769 ^ self |
749 ]. |
770 ]. |
750 ]. |
771 ]. |
751 "---" |
772 "---" |
752 |
773 |
753 useIOInterrupts ifTrue:[ |
774 useIOInterrupts ifTrue:[ |
754 "/ readFdArray do:[:fd | |
775 "/ readFdArray do:[:fd | |
755 "/ (fd notNil and:[fd >= 0]) ifTrue:[ |
776 "/ (fd notNil and:[fd >= 0]) ifTrue:[ |
756 "/ OperatingSystem enableIOInterruptsOn:fd |
777 "/ OperatingSystem enableIOInterruptsOn:fd |
757 "/ ]. |
778 "/ ]. |
758 "/ ]. |
779 "/ ]. |
759 ] ifFalse:[ |
780 ] ifFalse:[ |
760 millis notNil ifTrue:[ |
781 millis notNil ifTrue:[ |
761 millis := millis min:EventPollingInterval |
782 millis := millis min:EventPollingInterval |
762 ] ifFalse:[ |
783 ] ifFalse:[ |
763 millis := EventPollingInterval |
784 millis := EventPollingInterval |
764 ] |
785 ] |
765 ] |
786 ] |
766 ]. |
787 ]. |
767 |
788 |
768 millis notNil ifTrue:[ |
789 millis notNil ifTrue:[ |
769 "/ Trace ifTrue:['C' print. millis printCR.]. |
790 "/ Trace ifTrue:['C' print. millis printCR.]. |
770 "schedule a clock interrupt after millis milliseconds" |
791 "schedule a clock interrupt after millis milliseconds" |
771 OperatingSystem enableTimer:millis rounded. |
792 OperatingSystem enableTimer:millis rounded. |
772 ]. |
793 ]. |
773 |
794 |
774 scheduledProcesses notNil ifTrue:[ |
795 scheduledProcesses notNil ifTrue:[ |
775 scheduledProcesses add:p |
796 scheduledProcesses add:p |
776 ]. |
797 ]. |
777 |
798 |
778 " |
799 " |
779 now let the process run - will come back here by reschedule |
800 now let the process run - will come back here by reschedule |
780 from ioInterrupt, scheduler or timerInterrupt ... (running at max+1) |
801 from ioInterrupt, scheduler or timerInterrupt ... (running at max+1) |
1016 <context: #return> |
1038 <context: #return> |
1017 |
1039 |
1018 |index pri aProcess l| |
1040 |index pri aProcess l| |
1019 |
1041 |
1020 OperatingSystem interruptsBlocked ifFalse:[ |
1042 OperatingSystem interruptsBlocked ifFalse:[ |
1021 MiniDebugger |
1043 MiniDebugger |
1022 enterWithMessage:'vmResumeInterrupt with no interruptsBlocked' |
1044 enterWithMessage:'vmResumeInterrupt with no interruptsBlocked' |
1023 mayProceed:true. |
1045 mayProceed:true. |
1024 ]. |
1046 ]. |
1025 |
1047 |
1026 index := KnownProcessIds identityIndexOf:id. |
1048 index := KnownProcessIds identityIndexOf:id. |
1027 index ~~ 0 ifTrue:[ |
1049 index ~~ 0 ifTrue:[ |
1028 aProcess := KnownProcesses at:index. |
1050 aProcess := KnownProcesses at:index. |
1029 pri := aProcess priority. |
1051 pri := aProcess priority. |
1030 l := quiescentProcessLists at:pri. |
1052 l := quiescentProcessLists at:pri. |
1031 l notNil ifTrue:[ |
1053 l notNil ifTrue:[ |
1032 (l includesIdentical:aProcess) ifTrue:[ |
1054 (l includesIdentical:aProcess) ifTrue:[ |
1033 "/ aProcess is on a run queue. |
1055 "/ aProcess is on a run queue. |
1034 "/ CG: this situation may happen, if the wrapCall |
1056 "/ CG: this situation may happen, if the wrapCall |
1035 "/ finishes before the process was layed to sleep |
1057 "/ finishes before the process was layed to sleep |
1036 "/ (i.e. schedulerIRQ arrives before the threadSwitch was finished). |
1058 "/ (i.e. schedulerIRQ arrives before the threadSwitch was finished). |
1037 "/ In that case, simply resume it and everything is OK. |
1059 "/ In that case, simply resume it and everything is OK. |
1038 "/ If the process is state running, ignore. |
1060 "/ If the process is state running, ignore. |
1039 |
1061 |
1040 |state| |
1062 |state| |
1041 |
1063 |
1042 state := aProcess state. |
1064 state := aProcess state. |
1043 (state == #wrapWait or:[(state == #osWait) or:[state == #stopped]]) ifTrue:[ |
1065 (state == #wrapWait or:[(state == #osWait) or:[state == #stopped]]) ifTrue:[ |
1044 aProcess state:#run. |
1066 aProcess state:#run. |
1045 ]. |
1067 ]. |
1046 'ProcSched [info]: resumeIRQ ignored for process: ' infoPrint. |
1068 'ProcSched [info]: resumeIRQ ignored for process: ' infoPrint. |
1047 aProcess id infoPrint. ' in state: ' infoPrint. state infoPrintCR. |
1069 aProcess id infoPrint. ' in state: ' infoPrint. state infoPrintCR. |
1048 ^ self |
1070 ^ self |
1049 ] |
1071 ] |
1050 ] ifFalse:[ |
1072 ] ifFalse:[ |
1051 l := LinkedList new. |
1073 l := LinkedList new. |
1052 quiescentProcessLists at:pri put:l. |
1074 quiescentProcessLists at:pri put:l. |
1053 ]. |
1075 ]. |
1054 l addLast:aProcess. |
1076 l addLast:aProcess. |
1055 aProcess state:#run. |
1077 aProcess state:#run. |
1056 ] ifFalse:[ |
1078 ] ifFalse:[ |
1057 'ProcSched [info]: resumeIRQ for unknown process: ' infoPrint. |
1079 'ProcSched [info]: resumeIRQ for unknown process: ' infoPrint. |
1058 id infoPrintCR. |
1080 id infoPrintCR. |
1059 ] |
1081 ] |
1060 |
1082 |
1061 "Modified: / 28.9.1998 / 11:36:53 / cg" |
1083 "Modified: / 28.9.1998 / 11:36:53 / cg" |
1062 ! |
1084 ! |
1063 |
1085 |
1540 wasBlocked := OperatingSystem blockInterrupts. |
1563 wasBlocked := OperatingSystem blockInterrupts. |
1541 |
1564 |
1542 listArray := quiescentProcessLists. |
1565 listArray := quiescentProcessLists. |
1543 |
1566 |
1544 [prio >= 1] whileTrue:[ |
1567 [prio >= 1] whileTrue:[ |
1545 l := listArray at:prio. |
1568 l := listArray at:prio. |
1546 l notNil ifTrue:[ |
1569 l notNil ifTrue:[ |
1547 l linksDo:[:aProcess | |
1570 l linksDo:[:aProcess | |
1548 aProcess isUserProcess ifTrue:[ |
1571 aProcess isUserProcess ifTrue:[ |
1549 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1572 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1550 ^ true. |
1573 ^ true. |
1551 ] |
1574 ] |
1552 ] |
1575 ] |
1553 ]. |
1576 ]. |
1554 prio := prio - 1 |
1577 prio := prio - 1 |
1555 ]. |
1578 ]. |
1556 |
1579 |
1557 "/ any user process waiting on a sema? |
1580 "/ any user process waiting on a sema? |
1558 (readSemaphoreArray contains:[:sema | |
1581 (readSemaphoreArray contains:[:sema | |
1559 sema notNil and:[sema waitingProcesses contains:[:p | p notNil and:[p isUserProcess] ]]] |
1582 sema notNil and:[sema waitingProcesses contains:[:p | p notNil and:[p isUserProcess] ]]] |
1560 ) ifTrue:[ |
1583 ) ifTrue:[ |
1561 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1584 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1562 ^ true. |
1585 ^ true. |
1563 ]. |
1586 ]. |
1564 (writeSemaphoreArray contains:[:sema | |
1587 (writeSemaphoreArray contains:[:sema | |
1565 sema notNil and:[sema waitingProcesses contains:[:p | p notNil and:[p isUserProcess] ]]] |
1588 sema notNil and:[sema waitingProcesses contains:[:p | p notNil and:[p isUserProcess] ]]] |
1566 ) ifTrue:[ |
1589 ) ifTrue:[ |
1567 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1590 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1568 ^ true. |
1591 ^ true. |
1569 ]. |
1592 ]. |
1570 (timeoutSemaphoreArray contains:[:sema | |
1593 (timeoutSemaphoreArray contains:[:sema | |
1571 sema notNil and:[sema waitingProcesses contains:[:p | p notNil and:[p isUserProcess] ]]] |
1594 sema notNil and:[sema waitingProcesses contains:[:p | p notNil and:[p isUserProcess] ]]] |
1572 ) ifTrue:[ |
1595 ) ifTrue:[ |
1573 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1596 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1574 ^ true. |
1597 ^ true. |
1575 ]. |
1598 ]. |
1576 (timeoutProcessArray contains:[:p | p notNil and:[p isUserProcess] ] |
1599 (timeoutProcessArray contains:[:p | p notNil and:[p isUserProcess] ] |
1577 ) ifTrue:[ |
1600 ) ifTrue:[ |
1578 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1601 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1579 ^ true. |
1602 ^ true. |
1580 ]. |
1603 ]. |
1581 |
1604 |
1582 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1605 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1583 ^ false |
1606 ^ false |
1584 |
1607 |
2321 |idx "{ Class: SmallInteger }" |
2344 |idx "{ Class: SmallInteger }" |
2322 wasBlocked sema| |
2345 wasBlocked sema| |
2323 |
2346 |
2324 wasBlocked := OperatingSystem blockInterrupts. |
2347 wasBlocked := OperatingSystem blockInterrupts. |
2325 useIOInterrupts ifTrue:[ |
2348 useIOInterrupts ifTrue:[ |
2326 OperatingSystem disableIOInterruptsOn:aFileDescriptor. |
2349 OperatingSystem disableIOInterruptsOn:aFileDescriptor. |
2327 ]. |
2350 ]. |
2328 |
2351 |
2329 idx := readFdArray identityIndexOf:aFileDescriptor startingAt:1. |
2352 idx := readFdArray identityIndexOf:aFileDescriptor startingAt:1. |
2330 [idx ~~ 0] whileTrue:[ |
2353 [idx ~~ 0] whileTrue:[ |
2331 readFdArray at:idx put:nil. |
2354 readFdArray at:idx put:nil. |
2332 readCheckArray at:idx put:nil. |
2355 readCheckArray at:idx put:nil. |
2333 (sema := readSemaphoreArray at:idx) notNil ifTrue:[ |
2356 (sema := readSemaphoreArray at:idx) notNil ifTrue:[ |
2334 readSemaphoreArray at:idx put:nil. |
2357 readSemaphoreArray at:idx put:nil. |
2335 doSignal ifTrue:[ |
2358 doSignal ifTrue:[ |
2336 sema signalForAll. |
2359 sema signalForAll. |
2337 ]. |
2360 ]. |
2338 ]. |
2361 ]. |
2339 idx := readFdArray identityIndexOf:aFileDescriptor startingAt:idx+1. |
2362 idx := readFdArray identityIndexOf:aFileDescriptor startingAt:idx+1. |
2340 ]. |
2363 ]. |
2341 idx := writeFdArray identityIndexOf:aFileDescriptor startingAt:1. |
2364 idx := writeFdArray identityIndexOf:aFileDescriptor startingAt:1. |
2342 [idx ~~ 0] whileTrue:[ |
2365 [idx ~~ 0] whileTrue:[ |
2343 writeFdArray at:idx put:nil. |
2366 writeFdArray at:idx put:nil. |
2344 writeCheckArray at:idx put:nil. |
2367 writeCheckArray at:idx put:nil. |
2345 (sema := writeSemaphoreArray at:idx) notNil ifTrue:[ |
2368 (sema := writeSemaphoreArray at:idx) notNil ifTrue:[ |
2346 writeSemaphoreArray at:idx put:nil. |
2369 writeSemaphoreArray at:idx put:nil. |
2347 doSignal ifTrue:[ |
2370 doSignal ifTrue:[ |
2348 sema signalForAll. |
2371 sema signalForAll. |
2349 ]. |
2372 ]. |
2350 ]. |
2373 ]. |
2351 idx := writeFdArray identityIndexOf:aFileDescriptor startingAt:idx+1. |
2374 idx := writeFdArray identityIndexOf:aFileDescriptor startingAt:idx+1. |
2352 ]. |
2375 ]. |
2353 idx := exceptFdArray identityIndexOf:aFileDescriptor startingAt:1. |
2376 idx := exceptFdArray identityIndexOf:aFileDescriptor startingAt:1. |
2354 [idx ~~ 0] whileTrue:[ |
2377 [idx ~~ 0] whileTrue:[ |
2355 exceptFdArray at:idx put:nil. |
2378 exceptFdArray at:idx put:nil. |
2356 (sema := exceptSemaphoreArray at:idx) notNil ifTrue:[ |
2379 (sema := exceptSemaphoreArray at:idx) notNil ifTrue:[ |
2357 exceptSemaphoreArray at:idx put:nil. |
2380 exceptSemaphoreArray at:idx put:nil. |
2358 doSignal ifTrue:[ |
2381 doSignal ifTrue:[ |
2359 sema signalForAll. |
2382 sema signalForAll. |
2360 ]. |
2383 ]. |
2361 ]. |
2384 ]. |
2362 idx := exceptFdArray identityIndexOf:aFileDescriptor startingAt:idx+1. |
2385 idx := exceptFdArray identityIndexOf:aFileDescriptor startingAt:idx+1. |
2363 ]. |
2386 ]. |
2364 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2387 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2365 ! |
2388 ! |
2366 |
2389 |
2367 disableSemaphore:aSemaphore |
2390 disableSemaphore:aSemaphore |
2371 wasBlocked fd| |
2394 wasBlocked fd| |
2372 |
2395 |
2373 wasBlocked := OperatingSystem blockInterrupts. |
2396 wasBlocked := OperatingSystem blockInterrupts. |
2374 idx := readSemaphoreArray identityIndexOf:aSemaphore startingAt:1. |
2397 idx := readSemaphoreArray identityIndexOf:aSemaphore startingAt:1. |
2375 [idx ~~ 0] whileTrue:[ |
2398 [idx ~~ 0] whileTrue:[ |
2376 useIOInterrupts ifTrue:[ |
2399 useIOInterrupts ifTrue:[ |
2377 fd := readFdArray at:idx. |
2400 fd := readFdArray at:idx. |
2378 fd notNil ifTrue:[ |
2401 fd notNil ifTrue:[ |
2379 OperatingSystem disableIOInterruptsOn:fd |
2402 OperatingSystem disableIOInterruptsOn:fd |
2380 ]. |
2403 ]. |
2381 ]. |
2404 ]. |
2382 readFdArray at:idx put:nil. |
2405 readFdArray at:idx put:nil. |
2383 readSemaphoreArray at:idx put:nil. |
2406 readSemaphoreArray at:idx put:nil. |
2384 readCheckArray at:idx put:nil. |
2407 readCheckArray at:idx put:nil. |
2385 idx := readSemaphoreArray identityIndexOf:aSemaphore startingAt:idx+1. |
2408 idx := readSemaphoreArray identityIndexOf:aSemaphore startingAt:idx+1. |
2386 ]. |
2409 ]. |
2387 idx := writeSemaphoreArray identityIndexOf:aSemaphore startingAt:1. |
2410 idx := writeSemaphoreArray identityIndexOf:aSemaphore startingAt:1. |
2388 [idx ~~ 0] whileTrue:[ |
2411 [idx ~~ 0] whileTrue:[ |
2389 useIOInterrupts ifTrue:[ |
2412 useIOInterrupts ifTrue:[ |
2390 fd := writeFdArray at:idx. |
2413 fd := writeFdArray at:idx. |
2391 fd notNil ifTrue:[ |
2414 fd notNil ifTrue:[ |
2392 OperatingSystem disableIOInterruptsOn:fd |
2415 OperatingSystem disableIOInterruptsOn:fd |
2393 ]. |
2416 ]. |
2394 ]. |
2417 ]. |
2395 writeFdArray at:idx put:nil. |
2418 writeFdArray at:idx put:nil. |
2396 writeSemaphoreArray at:idx put:nil. |
2419 writeSemaphoreArray at:idx put:nil. |
2397 writeCheckArray at:idx put:nil. |
2420 writeCheckArray at:idx put:nil. |
2398 idx := writeSemaphoreArray identityIndexOf:aSemaphore startingAt:idx+1. |
2421 idx := writeSemaphoreArray identityIndexOf:aSemaphore startingAt:idx+1. |
2399 ]. |
2422 ]. |
2400 idx := timeoutSemaphoreArray identityIndexOf:aSemaphore startingAt:1. |
2423 idx := timeoutSemaphoreArray identityIndexOf:aSemaphore startingAt:1. |
2401 [idx ~~ 0] whileTrue:[ |
2424 [idx ~~ 0] whileTrue:[ |
2402 timeoutArray at:idx put:nil. |
2425 timeoutArray at:idx put:nil. |
2403 timeoutSemaphoreArray at:idx put:nil. |
2426 timeoutSemaphoreArray at:idx put:nil. |
2404 timeoutActionArray at:idx put:nil. |
2427 timeoutActionArray at:idx put:nil. |
2405 timeoutProcessArray at:idx put:nil. |
2428 timeoutProcessArray at:idx put:nil. |
2406 idx := timeoutSemaphoreArray identityIndexOf:aSemaphore startingAt:idx+1. |
2429 idx := timeoutSemaphoreArray identityIndexOf:aSemaphore startingAt:idx+1. |
2407 ]. |
2430 ]. |
2408 idx := exceptSemaphoreArray identityIndexOf:aSemaphore startingAt:1. |
2431 idx := exceptSemaphoreArray identityIndexOf:aSemaphore startingAt:1. |
2409 [idx ~~ 0] whileTrue:[ |
2432 [idx ~~ 0] whileTrue:[ |
2410 exceptFdArray at:idx put:nil. |
2433 exceptFdArray at:idx put:nil. |
2411 exceptSemaphoreArray at:idx put:nil. |
2434 exceptSemaphoreArray at:idx put:nil. |
2412 idx := exceptSemaphoreArray identityIndexOf:aSemaphore startingAt:idx+1. |
2435 idx := exceptSemaphoreArray identityIndexOf:aSemaphore startingAt:idx+1. |
2413 ]. |
2436 ]. |
2414 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2437 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2415 |
2438 |
2416 "Modified: 4.8.1997 / 15:19:33 / cg" |
2439 "Modified: 4.8.1997 / 15:19:33 / cg" |
2417 ! |
2440 ! |
2504 |
2527 |
2505 "Here we assume, that for every triple (aSemaphore, aFileDescriptor, aBlock) |
2528 "Here we assume, that for every triple (aSemaphore, aFileDescriptor, aBlock) |
2506 aSemphore is never nil, but one of aFileDescriptor, aBlock may be nil" |
2529 aSemphore is never nil, but one of aFileDescriptor, aBlock may be nil" |
2507 |
2530 |
2508 aFileDescriptor isNil ifTrue:[ |
2531 aFileDescriptor isNil ifTrue:[ |
2509 idx := exceptSemaphoreArray identityIndexOf:aSemaphore or:nil. |
2532 idx := exceptSemaphoreArray identityIndexOf:aSemaphore or:nil. |
2510 idx == 0 ifTrue:[ |
2533 idx == 0 ifTrue:[ |
2511 "aSemaphore is not registered yet, have to create a new slot" |
2534 "aSemaphore is not registered yet, have to create a new slot" |
2512 exceptFdArray := exceptFdArray copyWith:nil. |
2535 exceptFdArray := exceptFdArray copyWith:nil. |
2513 exceptSemaphoreArray := exceptSemaphoreArray copyWith:aSemaphore. |
2536 exceptSemaphoreArray := exceptSemaphoreArray copyWith:aSemaphore. |
2514 ] ifFalse:[ |
2537 ] ifFalse:[ |
2515 slot := exceptSemaphoreArray at:idx. |
2538 slot := exceptSemaphoreArray at:idx. |
2516 slot isNil ifTrue:[ |
2539 slot isNil ifTrue:[ |
2517 exceptSemaphoreArray at:idx put:aSemaphore. |
2540 exceptSemaphoreArray at:idx put:aSemaphore. |
2518 ] |
2541 ] |
2519 ] |
2542 ] |
2520 ] ifFalse:[ |
2543 ] ifFalse:[ |
2521 idx := exceptFdArray identityIndexOf:aFileDescriptor or:nil. |
2544 idx := exceptFdArray identityIndexOf:aFileDescriptor or:nil. |
2522 idx == 0 ifTrue:[ |
2545 idx == 0 ifTrue:[ |
2523 "aFileDescriptor is not registered yet, have to create a new slot" |
2546 "aFileDescriptor is not registered yet, have to create a new slot" |
2524 exceptFdArray := exceptFdArray copyWith:aFileDescriptor. |
2547 exceptFdArray := exceptFdArray copyWith:aFileDescriptor. |
2525 exceptSemaphoreArray := exceptSemaphoreArray copyWith:aSemaphore. |
2548 exceptSemaphoreArray := exceptSemaphoreArray copyWith:aSemaphore. |
2526 ] ifFalse:[ |
2549 ] ifFalse:[ |
2527 slot := exceptFdArray at:idx. |
2550 slot := exceptFdArray at:idx. |
2528 slot isNil ifTrue:[ |
2551 slot isNil ifTrue:[ |
2529 exceptFdArray at:idx put:aFileDescriptor. |
2552 exceptFdArray at:idx put:aFileDescriptor. |
2530 exceptSemaphoreArray at:idx put:aSemaphore. |
2553 exceptSemaphoreArray at:idx put:aSemaphore. |
2531 ]. |
2554 ]. |
2532 ]. |
2555 ]. |
2533 "/ (useIOInterrupts and:[slot isNil]) ifTrue:[ |
2556 "/ (useIOInterrupts and:[slot isNil]) ifTrue:[ |
2534 "/ OperatingSystem enableIOInterruptsOn:aFileDescriptor |
2557 "/ OperatingSystem enableIOInterruptsOn:aFileDescriptor |
2535 "/ ]. |
2558 "/ ]. |
2536 ]. |
2559 ]. |
2537 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2560 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
3011 "/ looks ugly, but as this is called very often, reduces idle allocation by a lot. |
3033 "/ looks ugly, but as this is called very often, reduces idle allocation by a lot. |
3012 |
3034 |
3013 now := OperatingSystem getMillisecondTime. |
3035 now := OperatingSystem getMillisecondTime. |
3014 n := timeoutArray size. |
3036 n := timeoutArray size. |
3015 1 to:n do:[:index | |
3037 1 to:n do:[:index | |
3016 aTime := timeoutArray at:index. |
3038 aTime := timeoutArray at:index. |
3017 aTime notNil ifTrue:[ |
3039 aTime notNil ifTrue:[ |
3018 (OperatingSystem millisecondTime:now isAfter:aTime) ifTrue:[ |
3040 (OperatingSystem millisecondTime:now isAfter:aTime) ifTrue:[ |
3019 "this one should be triggered" |
3041 "this one should be triggered" |
3020 |
3042 |
3021 sema := timeoutSemaphoreArray at:index. |
3043 sema := timeoutSemaphoreArray at:index. |
3022 sema notNil ifTrue:[ |
3044 sema notNil ifTrue:[ |
3023 timeoutSemaphoreArray at:index put:nil. |
3045 timeoutSemaphoreArray at:index put:nil. |
3024 sema signalOnce. |
3046 timedActionCounter := (timedActionCounter + 1 bitAnd:16r3FFFFFFF). |
3025 ] ifFalse:[ |
3047 sema signalOnce. |
3026 "to support pure-events" |
3048 ] ifFalse:[ |
3027 block := timeoutActionArray at:index. |
3049 "to support pure-events" |
3028 block notNil ifTrue:[ |
3050 block := timeoutActionArray at:index. |
3029 firstBlockToEvaluate isNil ifTrue:[ |
3051 block notNil ifTrue:[ |
3030 firstBlockToEvaluate := block. |
3052 "/ usually (>99%), there is only one single timeout action to call; |
3031 firstProcess := timeoutProcessArray at:index. |
3053 "/ avoid creation of an OrderedCollection |
3032 ] ifFalse:[ |
3054 firstBlockToEvaluate isNil ifTrue:[ |
3033 blocksAndProcessesToEvaluate isNil ifTrue:[ |
3055 firstBlockToEvaluate := block. |
3034 blocksAndProcessesToEvaluate := OrderedCollection |
3056 firstProcess := timeoutProcessArray at:index. |
3035 with:firstBlockToEvaluate |
3057 ] ifFalse:[ |
3036 with:firstProcess. |
3058 blocksAndProcessesToEvaluate isNil ifTrue:[ |
3037 ]. |
3059 blocksAndProcessesToEvaluate := OrderedCollection |
3038 blocksAndProcessesToEvaluate add:block. |
3060 with:firstBlockToEvaluate |
3039 blocksAndProcessesToEvaluate add:(timeoutProcessArray at:index). |
3061 with:firstProcess. |
3040 ]. |
3062 ]. |
3041 timeoutActionArray at:index put:nil. |
3063 blocksAndProcessesToEvaluate add:block. |
3042 timeoutProcessArray at:index put:nil. |
3064 blocksAndProcessesToEvaluate add:(timeoutProcessArray at:index). |
3043 ] |
3065 ]. |
3044 ]. |
3066 timeoutActionArray at:index put:nil. |
3045 timeoutArray at:index put:nil. |
3067 timeoutProcessArray at:index put:nil. |
3046 ] ifFalse:[ |
3068 ] |
3047 "there are still pending timeouts" |
3069 ]. |
3048 anyTimeouts := true. |
3070 timeoutArray at:index put:nil. |
3049 indexOfLastTimeout := index. |
3071 ] ifFalse:[ |
3050 ] |
3072 "there are still pending timeouts" |
3051 ] |
3073 anyTimeouts := true. |
|
3074 indexOfLastTimeout := index. |
|
3075 ] |
|
3076 ] |
3052 ]. |
3077 ]. |
3053 |
3078 |
3054 "shrink the arrays, if they are 50% free" |
3079 "shrink the arrays, if they are 50% free" |
3055 n > 20 ifTrue:[ |
3080 n > 20 ifTrue:[ |
3056 halfSize := n // 2. |
3081 halfSize := n // 2. |
3057 indexOfLastTimeout < halfSize ifTrue:[ |
3082 indexOfLastTimeout < halfSize ifTrue:[ |
3058 wasBlocked := OperatingSystem blockInterrupts. |
3083 wasBlocked := OperatingSystem blockInterrupts. |
3059 (timeoutArray at:indexOfLastTimeout+1) isNil ifTrue:[ "/ no new timeouts arrived |
3084 (timeoutArray at:indexOfLastTimeout+1) isNil ifTrue:[ "/ no new timeouts arrived |
3060 timeoutArray := timeoutArray copyTo:halfSize. |
3085 timeoutArray := timeoutArray copyTo:halfSize. |
3061 timeoutSemaphoreArray := timeoutSemaphoreArray copyTo:halfSize. |
3086 timeoutSemaphoreArray := timeoutSemaphoreArray copyTo:halfSize. |
3062 timeoutActionArray := timeoutActionArray copyTo:halfSize. |
3087 timeoutActionArray := timeoutActionArray copyTo:halfSize. |
3063 timeoutProcessArray := timeoutProcessArray copyTo:halfSize. |
3088 timeoutProcessArray := timeoutProcessArray copyTo:halfSize. |
3064 ]. |
3089 ]. |
3065 wasBlocked ifFalse:[ OperatingSystem unblockInterrupts ]. |
3090 wasBlocked ifFalse:[ OperatingSystem unblockInterrupts ]. |
3066 ]. |
3091 ]. |
3067 ]. |
3092 ]. |
3068 |
3093 |
|
3094 "/ usually (>99%), there is only one single timeout action to call; |
|
3095 "/ above code avoided the creation of an OrderedCollection |
3069 blocksAndProcessesToEvaluate isNil ifTrue:[ |
3096 blocksAndProcessesToEvaluate isNil ifTrue:[ |
3070 firstBlockToEvaluate notNil ifTrue:[ |
3097 firstBlockToEvaluate notNil ifTrue:[ |
3071 (firstProcess isNil or:[firstProcess == scheduler or:[PureEventDriven]]) ifTrue:[ |
3098 timedActionCounter := (timedActionCounter + 1 bitAnd:16r3FFFFFFF). |
3072 firstBlockToEvaluate value |
3099 (firstProcess isNil or:[firstProcess == scheduler or:[PureEventDriven]]) ifTrue:[ |
3073 ] ifFalse:[ |
3100 firstBlockToEvaluate value |
3074 firstProcess isDead ifTrue:[ |
3101 ] ifFalse:[ |
3075 "/ a timedBlock for a process which has already terminated |
3102 firstProcess isDead ifTrue:[ |
3076 "/ issue a warning and do not execute it. |
3103 "/ a timedBlock for a process which has already terminated |
3077 "/ (exeuting here may be dangerous, since it would run at scheduler priority here, |
3104 "/ issue a warning and do not execute it. |
3078 "/ and thereby could block the whole smalltalk system. |
3105 "/ (exeuting here may be dangerous, since it would run at scheduler priority here, |
3079 "/ For this reason is it IGNORED here.) |
3106 "/ and thereby could block the whole smalltalk system. |
|
3107 "/ For this reason is it IGNORED here.) |
3080 "/ Could handle it in timeoutProcess, but we don't, |
3108 "/ Could handle it in timeoutProcess, but we don't, |
3081 "/ because otherwise timeouts might be reissued forever... |
3109 "/ because otherwise timeouts might be reissued forever... |
3082 "/ (timeoutHandlerProcess notNil and:[timeoutHandlerProcess isDead not]) ifTrue:[ |
3110 "/ (timeoutHandlerProcess notNil and:[timeoutHandlerProcess isDead not]) ifTrue:[ |
3083 "/ timeoutHandlerProcess interruptWith:block. |
3111 "/ timeoutHandlerProcess interruptWith:block. |
3084 "/ ] ifFalse:[ |
3112 "/ ] ifFalse:[ |
3085 ('ProcessorScheduler [warning]: cannot evaluate timedBlock for dead process: ''' , firstProcess name , '''') infoPrintCR. |
3113 ('ProcessorScheduler [warning]: cannot evaluate timedBlock for dead process: ''' , firstProcess name , '''') infoPrintCR. |
3086 ('ProcessorScheduler [warning]: the timedBlock is: ' , firstBlockToEvaluate displayString) infoPrintCR. |
3114 ('ProcessorScheduler [warning]: the timedBlock is: ' , firstBlockToEvaluate displayString) infoPrintCR. |
3087 "/ ]. |
3115 "/ ]. |
3088 ] ifFalse:[ |
3116 ] ifFalse:[ |
3089 firstProcess interruptWith:firstBlockToEvaluate |
3117 firstProcess interruptWith:firstBlockToEvaluate |
3090 ] |
3118 ] |
3091 ] |
3119 ] |
3092 ]. |
3120 ]. |
3093 ] ifFalse:[ |
3121 ] ifFalse:[ |
3094 n := blocksAndProcessesToEvaluate size. |
3122 n := blocksAndProcessesToEvaluate size. |
3095 1 to:n by:2 do:[:index | |
3123 1 to:n by:2 do:[:index | |
3096 block := blocksAndProcessesToEvaluate at:index. |
3124 timedActionCounter := (timedActionCounter + 1 bitAnd:16r3FFFFFFF). |
3097 p := blocksAndProcessesToEvaluate at:index+1. |
3125 block := blocksAndProcessesToEvaluate at:index. |
3098 (p isNil or:[p == scheduler or:[PureEventDriven]]) ifTrue:[ |
3126 p := blocksAndProcessesToEvaluate at:index+1. |
3099 block value |
3127 (p isNil or:[p == scheduler or:[PureEventDriven]]) ifTrue:[ |
3100 ] ifFalse:[ |
3128 "/ 'irq*: ' infoPrint. block infoPrintCR. |
3101 p isDead ifTrue:[ |
3129 block value |
3102 "/ a timedBlock for a process which has already terminated |
3130 ] ifFalse:[ |
3103 "/ issue a warning and do not execute it. |
3131 p isDead ifTrue:[ |
3104 "/ (exeuting here may be dangerous, since it would run at scheduler priority here, |
3132 "/ see comment above |
3105 "/ and thereby could block the whole smalltalk system. |
3133 ('ProcessorScheduler [warning]: cannot evaluate timedBlock for dead process: ''' , p name , '''') infoPrintCR. |
3106 "/ For this reason is it IGNORED here.) |
3134 ('ProcessorScheduler [warning]: the timedBlock is: ' , block displayString) infoPrintCR. |
3107 "/ Could handle it in timeoutProcess, but we don't, |
3135 ] ifFalse:[ |
3108 "/ because otherwise timeouts might be reissued forever... |
3136 p interruptWith:block. |
3109 "/ (timeoutHandlerProcess notNil and:[timeoutHandlerProcess isDead not]) ifTrue:[ |
3137 "/ 'irq: ' infoPrint. block infoPrintCR. |
3110 "/ timeoutHandlerProcess interruptWith:block. |
3138 ] |
3111 "/ ] ifFalse:[ |
3139 ] |
3112 ('ProcessorScheduler [warning]: cannot evaluate timedBlock for dead process: ''' , p name , '''') infoPrintCR. |
3140 ] |
3113 ('ProcessorScheduler [warning]: the timedBlock is: ' , block displayString) infoPrintCR. |
|
3114 "/ ]. |
|
3115 ] ifFalse:[ |
|
3116 p interruptWith:block |
|
3117 ] |
|
3118 ] |
|
3119 ] |
|
3120 ]. |
3141 ]. |
3121 |
3142 |
3122 "Modified: / 30-07-2013 / 19:33:24 / cg" |
3143 "Modified: / 30-07-2013 / 19:33:24 / cg" |
3123 ! |
3144 ! |
3124 |
3145 |
3277 |
3300 |
3278 wasBlocked := OperatingSystem unblockInterrupts. |
3301 wasBlocked := OperatingSystem unblockInterrupts. |
3279 |
3302 |
3280 newProcessMaybeReady := false. |
3303 newProcessMaybeReady := false. |
3281 readableResultFdArray size < readFdArray size ifTrue:[ |
3304 readableResultFdArray size < readFdArray size ifTrue:[ |
3282 readableResultFdArray := Array new:(40 max:readFdArray size). |
3305 readableResultFdArray := Array new:(40 max:readFdArray size). |
3283 ]. |
3306 ]. |
3284 writableResultFdArray size < writeFdArray size ifTrue:[ |
3307 writableResultFdArray size < writeFdArray size ifTrue:[ |
3285 writableResultFdArray := Array new:(40 max:writeFdArray size). |
3308 writableResultFdArray := Array new:(40 max:writeFdArray size). |
3286 ]. |
3309 ]. |
3287 |
3310 |
3288 exceptArray := exceptFdArray. |
3311 exceptArray := exceptFdArray. |
3289 |
3312 |
3290 OperatingSystem isMSWINDOWSlike ifTrue:[ |
3313 OperatingSystem isMSWINDOWSlike ifTrue:[ |
3291 "/ |
3314 "/ |
3292 "/ win32 does a WaitForMultipleObjects in select... |
3315 "/ win32 does a WaitForMultipleObjects in select... |
3293 "/ unix waits for SIGCHLD |
3316 "/ unix waits for SIGCHLD |
3294 "/ |
3317 "/ |
3295 |hasPids| |
3318 |hasPids| |
3296 |
3319 |
3297 hasPids := false. |
3320 hasPids := false. |
3298 osChildExitActions keysDo:[:eachPid| |
3321 osChildExitActions keysDo:[:eachPid| |
3299 eachPid address = 0 ifTrue:[ |
3322 eachPid address = 0 ifTrue:[ |
3300 'Processor: remove 0-handle pid: ' infoPrint. eachPid infoPrintCR. |
3323 'Processor: remove 0-handle pid: ' infoPrint. eachPid infoPrintCR. |
3301 osChildExitActions safeRemoveKey:eachPid. |
3324 osChildExitActions safeRemoveKey:eachPid. |
3302 ] ifFalse:[ |
3325 ] ifFalse:[ |
3303 hasPids := true. |
3326 hasPids := true. |
3304 ]. |
3327 ]. |
3305 ]. |
3328 ]. |
3306 hasPids ifTrue:[ |
3329 hasPids ifTrue:[ |
3307 exceptArray := (exceptArray upTo:nil), osChildExitActions keys asArray. |
3330 exceptArray := (exceptArray upTo:nil), osChildExitActions keys asArray. |
3308 "/'exceptArray: ' print. exceptArray printCR. |
3331 "/'exceptArray: ' print. exceptArray printCR. |
3309 ]. |
3332 ]. |
3310 ]. |
3333 ]. |
3311 |
3334 |
3312 exceptResultFdArray size < exceptArray size ifTrue:[ |
3335 exceptResultFdArray size < exceptArray size ifTrue:[ |
3313 exceptResultFdArray := Array new:(40 max:exceptArray size). |
3336 exceptResultFdArray := Array new:(40 max:exceptArray size). |
3314 ]. |
3337 ]. |
3315 |
3338 |
3316 nReady := OperatingSystem |
3339 nReady := OperatingSystem |
3317 selectOnAnyReadable:readFdArray |
3340 selectOnAnyReadable:readFdArray |
3318 writable:writeFdArray |
3341 writable:writeFdArray |
3319 exception:exceptArray |
3342 exception:exceptArray |
3320 readableInto:readableResultFdArray |
3343 readableInto:readableResultFdArray |
3321 writableInto:writableResultFdArray |
3344 writableInto:writableResultFdArray |
3322 exceptionInto:exceptResultFdArray |
3345 exceptionInto:exceptResultFdArray |
3323 withTimeOut:millis. |
3346 withTimeOut:millis. |
3324 |
3347 |
3325 wasBlocked ifTrue:[ |
3348 wasBlocked ifTrue:[ |
3326 OperatingSystem blockInterrupts. |
3349 OperatingSystem blockInterrupts. |
3327 ]. |
3350 ]. |
3328 |
3351 |
3329 nReady <= 0 ifTrue:[ |
3352 nReady <= 0 ifTrue:[ |
3330 "/ either still nothing to do, |
3353 "/ either still nothing to do, |
3331 "/ or error (which should not happen) |
3354 "/ or error (which should not happen) |
3332 |
3355 |
3333 (nReady < 0 and:[(err := OperatingSystem lastErrorSymbol) notNil]) ifTrue:[ |
3356 (nReady < 0 and:[(err := OperatingSystem lastErrorSymbol) notNil]) ifTrue:[ |
3334 err == #EBADF ifTrue:[ |
3357 err == #EBADF ifTrue:[ |
3335 "/ mhmh - one of the fd's given to me is corrupt. |
3358 "/ mhmh - one of the fd's given to me is corrupt. |
3336 "/ find out which one .... and remove it |
3359 "/ find out which one .... and remove it |
3337 self removeCorruptedFds |
3360 self removeCorruptedFds |
3338 ] ifFalse:[ |
3361 ] ifFalse:[ |
3339 err == #ENOENT ifTrue:[ |
3362 err == #ENOENT ifTrue:[ |
3340 'Processor [warning]: ENOENT in select; rd=' infoPrint. |
3363 'Processor [warning]: ENOENT in select; rd=' infoPrint. |
3341 readFdArray infoPrint. ' wr=' infoPrint. writeFdArray infoPrintCR. |
3364 readFdArray infoPrint. ' wr=' infoPrint. writeFdArray infoPrintCR. |
3342 ] ifFalse:[ |
3365 ] ifFalse:[ |
3343 'Processor [warning]: error in select: ' infoPrint. err infoPrintCR. |
3366 'Processor [warning]: error in select: ' infoPrint. err infoPrintCR. |
3344 ] |
3367 ] |
3345 ]. |
3368 ]. |
3346 ] |
3369 ] |
3347 ] ifFalse:[ |
3370 ] ifFalse:[ |
3348 readyIndex := 1. |
3371 readyIndex := 1. |
3349 [nReady > 0 |
3372 [nReady > 0 |
3350 and:[ readyIndex <= readableResultFdArray size |
3373 and:[ readyIndex <= readableResultFdArray size |
3351 and:[ (fd := readableResultFdArray at:readyIndex) notNil ]] |
3374 and:[ (fd := readableResultFdArray at:readyIndex) notNil ]] |
3352 ] whileTrue:[ |
3375 ] whileTrue:[ |
3353 index := readFdArray identityIndexOf:fd. |
3376 index := readFdArray identityIndexOf:fd. |
3354 index ~~ 0 ifTrue:[ |
3377 index ~~ 0 ifTrue:[ |
3355 action := readCheckArray at:index. |
3378 action := readCheckArray at:index. |
3356 sema := readSemaphoreArray at:index. |
3379 sema := readSemaphoreArray at:index. |
3357 sema notNil ifTrue:[ |
3380 sema notNil ifTrue:[ |
3358 sema signalOnce. |
3381 sema signalOnce. |
3359 newProcessMaybeReady := true. |
3382 newProcessMaybeReady := true. |
3360 action isNil ifTrue:[ |
3383 action isNil ifTrue:[ |
3361 "before May 2014 we disabled the sema in the caller after wakeup. |
3384 "before May 2014 we disabled the sema in the caller after wakeup. |
3362 This caused ST/X to consume 100% cpu, when the caller didn't read |
3385 This caused ST/X to consume 100% cpu, when the caller didn't read |
3363 the data (e.g. because his process was stopped)." |
3386 the data (e.g. because his process was stopped)." |
3364 "disable possible write side and timeouts as well" |
3387 "disable possible write side and timeouts as well" |
3365 self disableSemaphore:sema. |
3388 self disableSemaphore:sema. |
3366 ]. |
3389 ]. |
3367 ]. |
3390 ]. |
3368 (action notNil and:[action value]) ifTrue:[ |
3391 (action notNil and:[action value]) ifTrue:[ |
3369 newProcessMaybeReady := true. |
3392 newProcessMaybeReady := true. |
3370 ]. |
3393 ]. |
3371 ]. |
3394 ]. |
3372 nReady := nReady - 1. |
3395 nReady := nReady - 1. |
3373 readyIndex := readyIndex + 1. |
3396 readyIndex := readyIndex + 1. |
3374 ]. |
3397 ]. |
3375 |
3398 |
3376 readyIndex := 1. |
3399 readyIndex := 1. |
3377 [nReady > 0 |
3400 [nReady > 0 |
3378 and:[ readyIndex <= writableResultFdArray size |
3401 and:[ readyIndex <= writableResultFdArray size |
3379 and:[ (fd := writableResultFdArray at:readyIndex) notNil ]] |
3402 and:[ (fd := writableResultFdArray at:readyIndex) notNil ]] |
3380 ] whileTrue:[ |
3403 ] whileTrue:[ |
3381 index := writeFdArray identityIndexOf:fd. |
3404 index := writeFdArray identityIndexOf:fd. |
3382 index ~~ 0 ifTrue:[ |
3405 index ~~ 0 ifTrue:[ |
3383 action := writeCheckArray at:index. |
3406 action := writeCheckArray at:index. |
3384 sema := writeSemaphoreArray at:index. |
3407 sema := writeSemaphoreArray at:index. |
3385 sema notNil ifTrue:[ |
3408 sema notNil ifTrue:[ |
3386 sema signalOnce. |
3409 sema signalOnce. |
3387 newProcessMaybeReady := true. |
3410 newProcessMaybeReady := true. |
3388 action isNil ifTrue:[ |
3411 action isNil ifTrue:[ |
3389 "now this is a one shot operation - see the input above" |
3412 "now this is a one shot operation - see the input above" |
3390 "disable possible read side and timeouts as well" |
3413 "disable possible read side and timeouts as well" |
3391 self disableSemaphore:sema. |
3414 self disableSemaphore:sema. |
3392 ]. |
3415 ]. |
3393 ]. |
3416 ]. |
3394 (action notNil and:[action value]) ifTrue:[ |
3417 (action notNil and:[action value]) ifTrue:[ |
3395 newProcessMaybeReady := true. |
3418 newProcessMaybeReady := true. |
3396 ]. |
3419 ]. |
3397 ]. |
3420 ]. |
3398 nReady := nReady - 1. |
3421 nReady := nReady - 1. |
3399 readyIndex := readyIndex + 1. |
3422 readyIndex := readyIndex + 1. |
3400 ]. |
3423 ]. |
3401 |
3424 |
3402 "/'except result got: ' print. exceptArray printCR. exceptResultFdArray printCR. |
3425 "/'except result got: ' print. exceptArray printCR. exceptResultFdArray printCR. |
3403 readyIndex := 1. |
3426 readyIndex := 1. |
3404 [nReady > 0 |
3427 [nReady > 0 |
3405 and:[ readyIndex <= exceptResultFdArray size |
3428 and:[ readyIndex <= exceptResultFdArray size |
3406 and:[ (fdOrPid := exceptResultFdArray at:readyIndex) notNil ]] |
3429 and:[ (fdOrPid := exceptResultFdArray at:readyIndex) notNil ]] |
3407 ] whileTrue:[ |
3430 ] whileTrue:[ |
3408 "/'except got: ' print. fdOrPid printCR. |
3431 "/'except got: ' print. fdOrPid printCR. |
3409 index := exceptFdArray identityIndexOf:fdOrPid. |
3432 index := exceptFdArray identityIndexOf:fdOrPid. |
3410 index ~~ 0 ifTrue:[ |
3433 index ~~ 0 ifTrue:[ |
3411 sema := exceptSemaphoreArray at:index. |
3434 sema := exceptSemaphoreArray at:index. |
3412 sema notNil ifTrue:[ |
3435 sema notNil ifTrue:[ |
3413 sema signalOnce. |
3436 sema signalOnce. |
3414 newProcessMaybeReady := true. |
3437 newProcessMaybeReady := true. |
3415 "disable possible read/write side and timeouts as well" |
3438 "disable possible read/write side and timeouts as well" |
3416 self disableSemaphore:sema. |
3439 self disableSemaphore:sema. |
3417 ]. |
3440 ]. |
3418 ] ifFalse:[ "may be a PID?" |
3441 ] ifFalse:[ "may be a PID?" |
3419 |osProcessStatus actionBlock| |
3442 |osProcessStatus actionBlock| |
3420 |
3443 |
3421 actionBlock := osChildExitActions removeKey:fdOrPid ifAbsent:nil. |
3444 actionBlock := osChildExitActions removeKey:fdOrPid ifAbsent:nil. |
3422 "/'pid signaled: ' print. fdOrPid printCR. |
3445 "/'pid signaled: ' print. fdOrPid printCR. |
3423 actionBlock notNil ifTrue:[ |
3446 actionBlock notNil ifTrue:[ |
3424 osProcessStatus := OperatingSystem childProcessWait:false pid:fdOrPid. |
3447 osProcessStatus := OperatingSystem childProcessWait:false pid:fdOrPid. |
3425 (osProcessStatus notNil and:[osProcessStatus pid = fdOrPid]) ifTrue:[ |
3448 (osProcessStatus notNil and:[osProcessStatus pid = fdOrPid]) ifTrue:[ |
3426 actionBlock value:osProcessStatus. |
3449 actionBlock value:osProcessStatus. |
3427 newProcessMaybeReady := true. |
3450 newProcessMaybeReady := true. |
3428 ]. |
3451 ]. |
3429 ]. |
3452 ]. |
3430 ]. |
3453 ]. |
3431 nReady := nReady - 1. |
3454 nReady := nReady - 1. |
3432 readyIndex := readyIndex + 1. |
3455 readyIndex := readyIndex + 1. |
3433 ]. |
3456 ]. |
3434 ]. |
3457 ]. |
3435 ^ newProcessMaybeReady |
3458 ^ newProcessMaybeReady |
3436 |
3459 |
3437 "Modified: / 12-04-1996 / 09:31:22 / stefan" |
3460 "Modified: / 12-04-1996 / 09:31:22 / stefan" |
3438 "Modified: / 07-12-2006 / 19:48:17 / cg" |
3461 "Modified: / 07-12-2006 / 19:48:17 / cg" |
3498 an #EBADF error, leading to high-frequency polling and a locked up system. |
3522 an #EBADF error, leading to high-frequency polling and a locked up system. |
3499 (you could still fix things by interrupting on the console and fixing the |
3523 (you could still fix things by interrupting on the console and fixing the |
3500 readFdArray/writeFdArray in the debugger)" |
3524 readFdArray/writeFdArray in the debugger)" |
3501 |
3525 |
3502 readFdArray keysAndValuesDo:[:idx :fd | |
3526 readFdArray keysAndValuesDo:[:idx :fd | |
3503 |result sema| |
3527 |result sema| |
3504 |
3528 |
3505 fd notNil ifTrue:[ |
3529 fd notNil ifTrue:[ |
3506 result := OperatingSystem |
3530 result := OperatingSystem |
3507 selectOnAnyReadable:(Array with:fd) writable:nil exception:nil |
3531 selectOnAnyReadable:(Array with:fd) writable:nil exception:nil |
3508 readableInto:nil writableInto:nil exceptionInto:nil |
3532 readableInto:nil writableInto:nil exceptionInto:nil |
3509 withTimeOut:0. |
3533 withTimeOut:0. |
3510 |
3534 |
3511 result < 0 ifTrue:[ |
3535 result < 0 ifTrue:[ |
3512 'Processor [info]: removing invalid read-select fileDescriptor: ' infoPrint. fd infoPrint. ' idx: 'infoPrint. idx infoPrintCR. |
3536 'Processor [info]: removing invalid read-select fileDescriptor: ' infoPrint. fd infoPrint. ' idx: 'infoPrint. idx infoPrintCR. |
3513 readFdArray at:idx put:nil. |
3537 readFdArray at:idx put:nil. |
3514 readCheckArray at:idx put:nil. |
3538 readCheckArray at:idx put:nil. |
3515 (sema := readSemaphoreArray at:idx) notNil ifTrue:[ |
3539 (sema := readSemaphoreArray at:idx) notNil ifTrue:[ |
3516 readSemaphoreArray at:idx put:nil. |
3540 readSemaphoreArray at:idx put:nil. |
3517 sema signalForAll. |
3541 sema signalForAll. |
3518 ]. |
3542 ]. |
3519 ] |
3543 ] |
3520 ]. |
3544 ]. |
3521 ]. |
3545 ]. |
3522 |
3546 |
3523 writeFdArray keysAndValuesDo:[:idx :fd | |
3547 writeFdArray keysAndValuesDo:[:idx :fd | |
3524 |result sema| |
3548 |result sema| |
3525 |
3549 |
3526 fd notNil ifTrue:[ |
3550 fd notNil ifTrue:[ |
3527 result := OperatingSystem |
3551 result := OperatingSystem |
3528 selectOnAnyReadable:nil writable:(Array with:fd) exception:nil |
3552 selectOnAnyReadable:nil writable:(Array with:fd) exception:nil |
3529 readableInto:nil writableInto:nil exceptionInto:nil |
3553 readableInto:nil writableInto:nil exceptionInto:nil |
3530 withTimeOut:0. |
3554 withTimeOut:0. |
3531 |
3555 |
3532 result < 0 ifTrue:[ |
3556 result < 0 ifTrue:[ |
3533 'Processor [info]: removing invalid write-select fileDescriptor: ' infoPrint. fd infoPrint. ' idx: 'infoPrint. idx infoPrintCR. |
3557 'Processor [info]: removing invalid write-select fileDescriptor: ' infoPrint. fd infoPrint. ' idx: 'infoPrint. idx infoPrintCR. |
3534 writeFdArray at:idx put:nil. |
3558 writeFdArray at:idx put:nil. |
3535 writeCheckArray at:idx put:nil. |
3559 writeCheckArray at:idx put:nil. |
3536 (sema := writeSemaphoreArray at:idx) notNil ifTrue:[ |
3560 (sema := writeSemaphoreArray at:idx) notNil ifTrue:[ |
3537 writeSemaphoreArray at:idx put:nil. |
3561 writeSemaphoreArray at:idx put:nil. |
3538 sema signalForAll. |
3562 sema signalForAll. |
3539 ]. |
3563 ]. |
3540 ] |
3564 ] |
3541 ] |
3565 ] |
3542 ]. |
3566 ]. |
3543 |
3567 |
3544 exceptFdArray keysAndValuesDo:[:idx :fd | |
3568 exceptFdArray keysAndValuesDo:[:idx :fd | |
3545 |result sema| |
3569 |result sema| |
3546 |
3570 |
3547 fd notNil ifTrue:[ |
3571 fd notNil ifTrue:[ |
3548 result := OperatingSystem |
3572 result := OperatingSystem |
3549 selectOnAnyReadable:nil writable:nil exception:(Array with:fd) |
3573 selectOnAnyReadable:nil writable:nil exception:(Array with:fd) |
3550 readableInto:nil writableInto:nil exceptionInto:nil |
3574 readableInto:nil writableInto:nil exceptionInto:nil |
3551 withTimeOut:0. |
3575 withTimeOut:0. |
3552 |
3576 |
3553 result < 0 ifTrue:[ |
3577 result < 0 ifTrue:[ |
3554 'Processor [info]: removing invalid exception-select fileDescriptor: ' infoPrint. fd infoPrint. ' idx: 'infoPrint. idx infoPrintCR. |
3578 'Processor [info]: removing invalid exception-select fileDescriptor: ' infoPrint. fd infoPrint. ' idx: 'infoPrint. idx infoPrintCR. |
3555 exceptFdArray at:idx put:nil. |
3579 exceptFdArray at:idx put:nil. |
3556 (sema := exceptSemaphoreArray at:idx) notNil ifTrue:[ |
3580 (sema := exceptSemaphoreArray at:idx) notNil ifTrue:[ |
3557 exceptSemaphoreArray at:idx put:nil. |
3581 exceptSemaphoreArray at:idx put:nil. |
3558 sema signalForAll. |
3582 sema signalForAll. |
3559 ]. |
3583 ]. |
3560 ] |
3584 ] |
3561 ] |
3585 ] |
3562 ]. |
3586 ]. |
3563 |
3587 |
3564 |
3588 |
3565 OperatingSystem isMSWINDOWSlike ifTrue:[ |
3589 OperatingSystem isMSWINDOWSlike ifTrue:[ |
3566 "/ |
3590 "/ |
3567 "/ win32 does a WaitForMultipleObjects in select... |
3591 "/ win32 does a WaitForMultipleObjects in select... |
3568 "/ unix waits for SIGCHLD |
3592 "/ unix waits for SIGCHLD |
3569 "/ |
3593 "/ |
3570 osChildExitActions keysDo:[:eachPid | |
3594 osChildExitActions keysDo:[:eachPid | |
3571 |result sema| |
3595 |result sema| |
3572 |
3596 |
3573 eachPid notNil ifTrue:[ |
3597 eachPid notNil ifTrue:[ |
3574 result := OperatingSystem |
3598 result := OperatingSystem |
3575 selectOnAnyReadable:nil writable:nil exception:(Array with:eachPid) |
3599 selectOnAnyReadable:nil writable:nil exception:(Array with:eachPid) |
3576 readableInto:nil writableInto:nil exceptionInto:nil |
3600 readableInto:nil writableInto:nil exceptionInto:nil |
3577 withTimeOut:0. |
3601 withTimeOut:0. |
3578 |
3602 |
3579 result < 0 ifTrue:[ |
3603 result < 0 ifTrue:[ |
3580 'Processor [info]: removing invalid exception-select pid: ' infoPrint. eachPid infoPrintCR. |
3604 'Processor [info]: removing invalid exception-select pid: ' infoPrint. eachPid infoPrintCR. |
3581 osChildExitActions safeRemoveKey:eachPid. |
3605 osChildExitActions safeRemoveKey:eachPid. |
3582 ] |
3606 ] |
3583 ] |
3607 ] |
3584 ]. |
3608 ]. |
3585 ]. |
3609 ]. |
3586 |
3610 |
3587 "Modified: 12.4.1996 / 09:32:58 / stefan" |
3611 "Modified: 12.4.1996 / 09:32:58 / stefan" |
3588 "Modified: 27.1.1997 / 20:09:27 / cg" |
3612 "Modified: 27.1.1997 / 20:09:27 / cg" |
3589 ! |
3613 ! |
3660 |
3686 |
3661 |millis doingGC dT| |
3687 |millis doingGC dT| |
3662 |
3688 |
3663 doingGC := true. |
3689 doingGC := true. |
3664 [doingGC] whileTrue:[ |
3690 [doingGC] whileTrue:[ |
3665 anyTimeouts ifTrue:[ |
3691 anyTimeouts ifTrue:[ |
3666 millis := self timeToNextTimeout. |
3692 millis := self timeToNextTimeout. |
3667 (millis notNil and:[millis <= 0]) ifTrue:[ |
3693 (millis notNil and:[millis <= 0]) ifTrue:[ |
3668 ^ self "oops - hurry up checking" |
3694 ^ self "oops - hurry up checking" |
3669 ]. |
3695 ]. |
3670 ]. |
3696 ]. |
3671 |
3697 |
3672 " |
3698 " |
3673 if its worth doing, collect a bit of garbage; |
3699 if its worth doing, collect a bit of garbage; |
3674 but not, if a backgroundCollector is active |
3700 but not, if a backgroundCollector is active |
3675 " |
3701 " |
3676 ObjectMemory backgroundCollectorRunning ifTrue:[ |
3702 ObjectMemory backgroundCollectorRunning ifTrue:[ |
3677 doingGC := false |
3703 doingGC := false |
3678 ] ifFalse:[ |
3704 ] ifFalse:[ |
3679 doingGC := ObjectMemory gcStepIfUseful. |
3705 doingGC := ObjectMemory gcStepIfUseful. |
3680 ]. |
3706 ]. |
3681 |
3707 |
3682 "then do idle actions" |
3708 "then do idle actions" |
3683 (idleActions notNil and:[idleActions size ~~ 0]) ifTrue:[ |
3709 (idleActions notNil and:[idleActions size ~~ 0]) ifTrue:[ |
3684 idleActions do:[:aBlock | |
3710 idleActions do:[:aBlock | |
3685 aBlock value. |
3711 aBlock value. |
3686 ]. |
3712 ]. |
3687 ^ self "go back checking" |
3713 ^ self "go back checking" |
3688 ]. |
3714 ]. |
3689 |
3715 |
3690 doingGC ifTrue:[ |
3716 doingGC ifTrue:[ |
3691 (self checkForIOWithTimeout:0) ifTrue:[ |
3717 (self checkForIOWithTimeout:0) ifTrue:[ |
3692 ^ self "go back checking" |
3718 ^ self "go back checking" |
3693 ] |
3719 ] |
3694 ] |
3720 ] |
3695 ]. |
3721 ]. |
3696 |
3722 |
3697 exitWhenNoMoreUserProcesses ifTrue:[ |
3723 exitWhenNoMoreUserProcesses ifTrue:[ |
3698 "/ check if there are any processes at all |
3724 "/ check if there are any processes at all |
3699 "/ stop dispatching if there is none |
3725 "/ stop dispatching if there is none |
3700 "/ (and anyTimeouts is false, which means that no timeout blocks are present) |
3726 "/ (and anyTimeouts is false, which means that no timeout blocks are present) |
3701 "/ and no readSemaphores are present (which means that noone is waiting for input) |
3727 "/ and no readSemaphores are present (which means that noone is waiting for input) |
3702 "/ and no writeSemaphores are present |
3728 "/ and no writeSemaphores are present |
3703 |
3729 |
3704 self noMoreUserProcesses ifTrue:[ |
3730 self noMoreUserProcesses ifTrue:[ |
3705 dispatching := false. |
3731 dispatching := false. |
3706 ^ self |
3732 ^ self |
3707 ]. |
3733 ]. |
3708 ]. |
3734 ]. |
3709 |
3735 |
3710 preWaitActions notNil ifTrue:[ |
3736 preWaitActions notNil ifTrue:[ |
3711 preWaitActions do:[:action | action value]. |
3737 preWaitActions do:[:action | action value]. |
3712 ]. |
3738 ]. |
3713 |
3739 |
3714 "/ |
3740 "/ |
3715 "/ absolutely nothing to do - simply wait |
3741 "/ absolutely nothing to do - simply wait |
3716 "/ |
3742 "/ |
3717 OperatingSystem supportsSelect ifFalse:[ |
3743 OperatingSystem supportsSelect ifFalse:[ |
3718 "SCO instant ShitStation has a bug here, |
3744 "SCO instant ShitStation has a bug here, |
3719 waiting always 1 sec in the select - therefore we delay a bit and |
3745 waiting always 1 sec in the select - therefore we delay a bit and |
3720 return - effectively polling in 50ms cycles |
3746 return - effectively polling in 50ms cycles |
3721 " |
3747 " |
3722 (self checkForIOWithTimeout:0) ifTrue:[ |
3748 (self checkForIOWithTimeout:0) ifTrue:[ |
3723 ^ self "go back checking" |
3749 ^ self "go back checking" |
3724 ]. |
3750 ]. |
3725 OperatingSystem millisecondDelay:EventPollingInterval. |
3751 OperatingSystem millisecondDelay:EventPollingInterval. |
3726 ^ self |
3752 ^ self |
3727 ]. |
3753 ]. |
3728 |
3754 |
3729 useIOInterrupts ifTrue:[ |
3755 useIOInterrupts ifTrue:[ |
3730 dT := 999999 |
3756 dT := 999999 |
3731 ] ifFalse:[ |
3757 ] ifFalse:[ |
3732 dT := EventPollingInterval |
3758 dT := EventPollingInterval |
3733 ]. |
3759 ]. |
3734 |
3760 |
3735 millis isNil ifTrue:[ |
3761 millis isNil ifTrue:[ |
3736 millis := dT. |
3762 millis := dT. |
3737 ] ifFalse:[ |
3763 ] ifFalse:[ |
3738 millis := millis rounded min:dT. |
3764 millis := millis rounded min:dT. |
3739 ]. |
3765 ]. |
3740 |
3766 |
3741 self checkForIOWithTimeout:millis |
3767 self checkForIOWithTimeout:millis |
3742 |
3768 |
3743 "Modified: 14.12.1995 / 13:37:46 / stefan" |
3769 "Modified: 14.12.1995 / 13:37:46 / stefan" |