98 A later version will allow specification of automatic restart, but |
98 A later version will allow specification of automatic restart, but |
99 thats not yet implemented. However, even when implemented, restartable processes |
99 thats not yet implemented. However, even when implemented, restartable processes |
100 will be recreated to restart from the beginning. It will not be possible to |
100 will be recreated to restart from the beginning. It will not be possible to |
101 automatically continue a processes execution where it left off. |
101 automatically continue a processes execution where it left off. |
102 This is a consequence of the portable implementation of ST/X, since in order to |
102 This is a consequence of the portable implementation of ST/X, since in order to |
103 implement this feature, the machines stack had to be preserved and recreated. |
103 implement process cintinuation, the machines stack had to be preserved and |
|
104 recreated. |
104 Although this is possible theoretically, this has not been implemented, since |
105 Although this is possible theoretically, this has not been implemented, since |
105 the machines stack layout is highly machine/compiler dependent, |
106 the machines stack layout is highly machine/compiler dependent, thus leading |
|
107 to much bigger porting effort of ST/X. |
106 |
108 |
107 |
109 |
108 Process synchronization: |
110 Process synchronization: |
109 any other process can wait for a process to suspend or terminate. This |
111 any other process can wait for a process to suspend or terminate. This |
110 is implemented by using suspendSemaphore and exitSemaphore, which are |
112 is implemented by using suspendSemaphore and exitSemaphore, which are |
305 "set my priority" |
307 "set my priority" |
306 |
308 |
307 Processor changePriority:aNumber for:self. |
309 Processor changePriority:aNumber for:self. |
308 ! |
310 ! |
309 |
311 |
|
312 isRestartable |
|
313 "return true, iff the receiver is restartable" |
|
314 |
|
315 ^ restartable |
|
316 ! |
|
317 |
|
318 restartable:aBoolean |
|
319 "set/clear, the restartable flag. |
|
320 Restartable processes will automatically be restarted by the |
|
321 ProcessorScheduler upon image restart. Others have to be restarted |
|
322 manually." |
|
323 |
|
324 restartable := aBoolean |
|
325 ! |
|
326 |
310 changePriority:aNumber |
327 changePriority:aNumber |
311 "same as priority:, but returns the old priority. |
328 "same as priority:, but returns the old priority. |
312 (cannot do this in priority: for ST-80 compatibility)" |
329 (cannot do this in priority: for ST-80 compatibility)" |
313 |
330 |
314 |oldPrio| |
331 |oldPrio| |
494 !Process methodsFor:'startup '! |
511 !Process methodsFor:'startup '! |
495 |
512 |
496 start |
513 start |
497 "start the process - this is sent by the VM to the process to get |
514 "start the process - this is sent by the VM to the process to get |
498 the process up and running. |
515 the process up and running. |
499 Sending start to the process allows more flexible handling |
516 Sending #start to the process (instead of directly executing the startBlock) |
500 of processes, since anything that responds to #start can be handled |
517 allows more flexible handling of processes, since anything that responds |
501 by the VM then ..." |
518 to #start can be handled transparently by the VM then ..." |
502 |
519 |
503 |block| |
520 |block| |
504 |
521 |
505 (block := startBlock) notNil ifTrue:[ |
522 (block := startBlock) notNil ifTrue:[ |
506 " |
523 " |
507 just for your convenience ... |
524 just for your convenience ... |
508 " |
525 " |
509 name isNil ifTrue:[ |
526 name isNil ifTrue:[ |
510 name := '(' , startBlock displayString , ')' |
527 name := '(' , startBlock displayString , ')' |
511 ]. |
528 ]. |
512 startBlock := nil. |
529 restartable ~~ true ifTrue:[startBlock := nil]. |
513 CoughtSignals handle:[:ex | |
530 CoughtSignals handle:[:ex | |
514 ex return |
531 ex return |
515 ] do:block. |
532 ] do:block. |
516 |
533 |
517 (block := exitAction) notNil ifTrue:[ |
534 (block := exitAction) notNil ifTrue:[ |
518 exitAction := nil. |
535 exitAction := nil. |
519 block value. |
536 block value. |
520 ]. |
537 ]. |
521 suspendSemaphore notNil ifTrue:[suspendSemaphore signal]. |
538 suspendSemaphore notNil ifTrue:[suspendSemaphore signalForAll]. |
522 exitSemaphore notNil ifTrue:[exitSemaphore signal]. |
539 exitSemaphore notNil ifTrue:[exitSemaphore signalForAll]. |
523 Processor terminateActiveNoSignal |
540 Processor terminateActiveNoSignal |
524 ] ifFalse:[ |
541 ] ifFalse:[ |
525 "is this artificial restriction useful ?" |
542 "is this artificial restriction useful ?" |
526 self error:'a process cannot be started twice' |
543 self error:'a process cannot be started twice' |
527 ] |
544 ] |
531 |
548 |
532 stop |
549 stop |
533 "suspend the receiver process - will continue to run when a resume is sent. |
550 "suspend the receiver process - will continue to run when a resume is sent. |
534 A stopped process will not be resumed for interrupt processing." |
551 A stopped process will not be resumed for interrupt processing." |
535 |
552 |
536 suspendSemaphore notNil ifTrue:[suspendSemaphore signal]. |
553 suspendSemaphore notNil ifTrue:[suspendSemaphore signalForAll]. |
537 state := #stopped. |
554 state := #stopped. |
538 Processor suspend:self |
555 Processor suspend:self |
539 ! |
556 ! |
540 |
557 |
541 suspend |
558 suspend |
542 "suspend the receiver process - will continue to run when a resume is sent. |
559 "suspend the receiver process - will continue to run when a resume is sent. |
543 An interrupt will resume the receiver." |
560 An interrupt will resume the receiver." |
544 |
561 |
545 suspendSemaphore notNil ifTrue:[suspendSemaphore signal]. |
562 suspendSemaphore notNil ifTrue:[suspendSemaphore signalForAll]. |
546 Processor suspend:self |
563 Processor suspend:self |
547 ! |
564 ! |
548 |
565 |
549 resume |
566 resume |
550 "resume the receiver process" |
567 "resume the receiver process" |
566 Signal noHandlerSignal handle:[:ex | |
583 Signal noHandlerSignal handle:[:ex | |
567 ex return. |
584 ex return. |
568 ] do:[ |
585 ] do:[ |
569 TerminateSignal raise. |
586 TerminateSignal raise. |
570 ]. |
587 ]. |
571 suspendSemaphore notNil ifTrue:[suspendSemaphore signal]. |
588 suspendSemaphore notNil ifTrue:[suspendSemaphore signalForAll]. |
572 exitSemaphore notNil ifTrue:[exitSemaphore signal]. |
589 exitSemaphore notNil ifTrue:[exitSemaphore signalForAll]. |
573 Processor terminateNoSignal:self |
590 Processor terminateNoSignal:self |
574 ] ifFalse:[ |
591 ] ifFalse:[ |
575 self interruptWith:[self terminate] |
592 self interruptWith:[self terminate] |
576 ] |
593 ] |
577 ! |
594 ! |
578 |
595 |
579 terminateNoSignal |
596 terminateNoSignal |
580 "terminate the receiver process without performing any unwind- or exit-actions" |
597 "terminate the receiver process without performing any unwind- or exit-actions" |
581 |
598 |
582 suspendSemaphore notNil ifTrue:[suspendSemaphore signal]. |
599 suspendSemaphore notNil ifTrue:[suspendSemaphore signalForAll]. |
583 exitSemaphore notNil ifTrue:[exitSemaphore signal]. |
600 exitSemaphore notNil ifTrue:[exitSemaphore signalForAll]. |
584 Processor terminateNoSignal:self |
601 Processor terminateNoSignal:self |
585 ! ! |
602 ! ! |
586 |
603 |
587 !Process methodsFor:'interrupts'! |
604 !Process methodsFor:'interrupts'! |
588 |
605 |
666 0 "stc hint" |
683 0 "stc hint" |
667 ] |
684 ] |
668 ! |
685 ! |
669 |
686 |
670 waitUntilTerminated |
687 waitUntilTerminated |
671 "set the softSuspend flag of the receiver and wait until it |
688 "wait until the receiver is terminated" |
672 suspends. The receviers process must execute checkForSoftSuspend |
689 |
673 periodically for this rendevous to work." |
690 |wasBlocked| |
674 |
691 |
675 exitSemaphore := Semaphore new. |
692 wasBlocked := OperatingSystem blockInterrupts. |
676 exitSemaphore wait |
693 exitSemaphore isNil ifTrue:[exitSemaphore := Semaphore new]. |
|
694 exitSemaphore wait. |
|
695 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
677 ! |
696 ! |
678 |
697 |
679 waitUntilSuspended |
698 waitUntilSuspended |
680 "set the softSuspend flag of the receiver and wait until it |
699 "wait until the receiver is suspended" |
681 suspends. The receviers process must execute checkForSoftSuspend |
700 |
682 periodically for this rendevous to work." |
701 |wasBlocked| |
683 |
702 |
684 suspendSemaphore := Semaphore new. |
703 wasBlocked := OperatingSystem blockInterrupts. |
|
704 suspendSemaphore isNil ifTrue:[suspendSemaphore := Semaphore new]. |
685 suspendSemaphore wait |
705 suspendSemaphore wait |
|
706 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
686 ! ! |
707 ! ! |
687 |
708 |
688 !Process methodsFor:'printing & storing'! |
709 !Process methodsFor:'printing & storing'! |
689 |
710 |
690 printOn:aStream |
711 printOn:aStream |
|
712 "a little more info in my printed representation" |
|
713 |
691 aStream nextPutAll:state article; |
714 aStream nextPutAll:state article; |
692 space; |
715 space; |
693 nextPutAll:state; |
716 nextPutAll:state; |
694 nextPutAll:' Process ('; |
717 nextPutAll:' Process ('; |
695 nextPutAll:self nameOrId; |
718 nextPutAll:self nameOrId; |