Assembly Language Co-Routines
Process A process is a program in execution. Multiprogramming/Multitasking Operating systems switches from one process to another. Each process has its own Instruction pointer Stack pointer Register values Pointers to Code Segment Data Segment Stack Segment Three Processes A, B, and C A. B. C. Create
Threads A process has Resources: address space, open files, accounting information, etc. A thread of control: instruction pointer, register contents, stack. Multithreading scheme permits multiple threads of control to execute within one process. Threads in the same process share a lot of data, such as code and data segments. Switching between threads with the same process is much less expensive than switching between thread in separate processes as they cause threads in the same process share so much state, between separate processes.
Control of the CPU Multitasking operating systems swap control of the CPU between several code section back and forth while executing. In two approaches: I. Preemptive: Several processes or threads take turns executing with the task switch occurring independently of the executing code. The Operating System takes responsibility for interrupting one task and transferring control to other task. II. Cooperative Blocks of code explicitly pass control between one another. The program manages the control flow usually using co-routines
Routines Routine B Routine A Routine B Routine A Resume B call B Entry Entry Entry Entry Resume B call B Resume A Routine B Routine A Routine B Routine A Resume B Resume A return Return Return Return Return
Co-Routines Initial resume (call) of X: create activation for X resume execution at entry point resume Y : suspend current activation Resume which activation of Y? resume ? return anonymous resume “terminated” activation Call create & resume
A Use Case Coroutines are quite useful for games where the “players” take turns, following different strategies. The first player executes some code to make its first move, then resumes the second player and allows it to make a move. After the second player makes its move, it resumes the first process and gives the first player its second move, picking up immediately after its resume. This transfer of control bounces back and forth until one player wins. Coroutines are also useful to implement state machine
Implementation A resume is effectively a call and a return instruction all rolled into one operation. From the point of view of the routine executing the resume, the resume operation is equivalent to a procedure call From the point of view of the processing being called (callee), the resume operation is equivalent to a return operation. When the second routine resumes the first, control resumes not at the be ginning of the first process, but immediately after the last resume operation from that coroutine.
Implementation Coroutines originated as an assembly-language technique, but are supported in some high-level languages. Most popular programming languages do not have direct support for coroutines within the language or their standard libraries. This due to The limitations of stack-based subroutine implementation. The standard call mechanism Coroutines needs an initialization process, which is different from the typical resume. When a program begins execution The main coroutine takes control and uses the stack associated with the entire program. Each process have its own stack, which size depends on its coroutine
Implementation For each coroutines we define a structure that stores Pointer to a code Pointer to a stack Content of used flags and registers We define a global array that stores that information of all the co-routines in the application. Initialize all the co-rountines
Co-routine initialization
Co-routine initialization
Passing Parameters Passing parameters to a coroutine is difficult Typically the stack is used to pass parameters and coroutines all use different stacks. The parameters one coroutine passes to another won’t be on the correct stack when the second coroutine continues execution. Typical coroutine has several entry points It is often necessary to communicate information between coroutines and one could do that by Global variables Registers Pass the address of a block of parameters vi a register
Resume Resume Save the state of the current co-routine Resume the state of the next co-routine (its reference in EBX)
Resume