Download presentation
Presentation is loading. Please wait.
Published byStuart Gray Modified over 9 years ago
1
Practical Session 7
2
Co-Routines co-routines are assembly implementation of threads each co-routine decides to which co- routine to pass a control - unlike “usual” threads
3
Co-routine state co-routine is denoted by Coi, where i is ID of the co- routine scheduler is also a co-routine co-routine suspends itself after some “time slice” co-routine resumes a scheduler co-routine should save its current state before it suspends itself, in order to continue its execution later a state of co-routine includes: stack state registers flags stack pointer (ESP) instructions pointer (EIP)
4
Co-routine structure STKSIZE equ 16*1024 ;(16 Kb) STK1:resb STKSIZE CO1:dd Function1 ; pointer to co-routine code Flags:dd 0 ; 0 if co-routine is not initialized, 1 otherwise SP1:dd STK1 + STKSIZE; pointer to co-routine stack
5
Co-routine structure
6
Variable Declaration STKSZequ16*1024 CODEPequ0 FLAGSPequ4 SPPequ8 section.rodata align 16 globalnumco numco:dd3 CORS:ddCO1 ddCO2 ddCO3 section.data align 16 CO1:ddFunction1 ; Structure for first co-routine Flags1:dd0 SP1:ddSTK1+STKSZ CO2:ddFunction1 ; Structure for second co-routine Flags2:dd0 SP2:ddSTK2+STKSZ CO3:ddFunction2 ; Structure for third co-routine Flags3:dd0 SP3:ddSTK3+STKSZ section.bss align 16 CURR:resd1 SPT:resd1 SPMAIN:resd1 STK1:resbSTKSZ STK2:resbSTKSZ STK3:resbSTKSZ
7
Co-routine initialization
8
Co-routine initialization: save initial co-routine state ‘bts’ instruction tests one bit of its first operand, whose index is given by the second operand, and stores the value of that bit in the carry flag (CF). In addition, ‘bts’ sets the bit to be 1.
9
Co-routine initialization init_co_from_c : initialize a co-routine, which number is given as an argument from C section.text align 16 externprintf globalinit_co_from_c globalstart_co_from_c globalend_co init_co_from_c: pushEBP movEBP, ESP pushEBX movEBX, [EBP+8] ; EBX contains a number of the co-routine to be initialized movEBX, [EBX*4+CORS]; EBX contains a pointer to co-routine structure to be initialized callco_init popEBX popEBP ret co_init: pusha btsdword [EBX+FLAGSP],0 ; test if already initialized jcinit_done movEAX,[EBX+CODEP]; get initial PC mov[SPT], ESP; save original SP movESP,[EBX+SPP] ; get initial SP movEBP, ESP ; also use as EBP pushEAX ; push initial "return" address (initial PC) pushf ; push flags pusha ; push all other registers mov[EBX+SPP],ESP ; save new SP in structure movESP, [SPT] ; restore original SP init_done: popa ret
10
Co-routine code (function)
11
Scheduler co-routine function Scheduler function is started by main. scheduler_Function: pick up some thread ID i mov EBX, [CORS + i*4] ; resumes Coi call resume pick up some other thread ID j mov EBX, [CORS + j*4] ; resumes Coj call resume … jmp end_co; resume main
12
Co-routine resume What should resume do? save a state of the current co-routine resume a state of the next co-routine (EBX should contain a pointer to it) Let’s look closer at the resume function: after ‘call resume’, returned address (i.e. EIP) is pushed automatically into (co-routine) stack we just have to save EFLAGS, ESP, and registers resume: pushf pusha mov EDX, [CURR] mov [EDX+SPP], ESP
13
Co-routine resume
14
EBX is pointer to co-init structure of co-routine to be resumed CURR holds a pointer to co-init structure of the current co-routine resume: pushf; save state of caller pusha movEDX, [CURR] mov[EDX+SPP],ESP; save current SP do_resume: movESP, [EBX+SPP] ; load SP for resumed co-routine mov[CURR], EBX popa; restore resumed co-routine state popf ret; "return" to resumed co-routine!
15
Function1 This function used as code for co-routines 0 and 1 FMT1: db "Function1, co %lx, called by %lx, pass %ld", 10, 0 Function1: pushdword1 pushdword [CORS+8] pushdword [CURR] pushdword FMT1 callprintf addESP, 20 movEBX, [CORS+8]; resume a scheduler calldword resume push2 pushdword [CORS+8] pushdword [CURR] pushdword FMT1 callprintf add ESP, 20 movEBX, [CORS+8] ; resume a scheduler calldword resume
16
Function2 This function used as code for co-routine 2 FMT2: db "Function2, co %lx, called by %lx, pass %ld", 10, 0 Function2: pushdword1 pushdword [CORS] pushdword [CURR] pushdword FMT2 callprintf addESP, 16 movEBX, [CORS] ; resume CO1 calldword resume pushdword2 pushdword [CORS+4] pushdword [CURR] pushdword FMT2 callprintf addESP, 20 movEBX, [CORS+4] ; resume CO2 calldword resume pushdword3 pushdword [CORS] pushdword [CURR] pushdword FMT2 callprintf addESP, 16 movEBX, [CORS] ; resume CO1 calldword resume pushdword4 pushdword [CORS+4] pushdword [CURR] pushdword FMT2 callprintf addESP, 16 movEBX, [CORS+4] ; resume CO2 calldword resume jmp end_co ; resume main
17
Start co-routine scheduler We start scheduling by suspending main function and starting (resuming) a first co-routine (scheduler) In our implementation, we call (from c) to start_co_from_c(2) start_co_from_c: pusha mov [SPMAIN], ESP; save stack pointer of the main code mov EBX, [EBP+8]; gets ID number of a scheduler structure mov EBX, [EBX*4 + CORS]; gets a pointer to a scheduler structure jmp do_resume; resume a scheduler co-routine
18
co-routine start and end C-callable start of the first co-routine start_co_from_c: pushEBP movEBP, ESP pusha mov[SPMAIN], ESP ; save SP of main code movEBX, [EBP+8] ; get number of co-routine movEBX, [EBX*4+CORS] ; and pointer to co-routine structure jmpdo_resume End co-routine mechanism, back to c main end_co: movESP, [SPMAIN] ; restore state of main code popa popEBP ret
19
Main.c #include extern long numco; extern void end_co(); extern void start_co_from_c(int num); extern void init_co_from_c(int num); extern void resume_from_c(int num); main() { long i; for(i = 0; i < numco; i++) init_co_from_c(i);// initialize co-routines printf("After init\n"); start_co_from_c(2);// start a scheduler co-routine printf("All co-routines done\n"); }
20
Run example – data declaration CURR SPT SPMAIN STK1 STK2 STK3 3numco CO1CORS CO2 CO3 Function1CO1 0Flags1 SP1 Function1CO2 0Flags2 SP2 Function2CO3 0Flags3 SP3 0COUNTER 3MAX_ITER.bss.data
21
Afterco-routine initialization After co-routine initialization CURR SPT SPMAIN STK1 Registers Flags Function1 STK2 Registers Flags Function1 STK3 Registers Flags Function2 3numco CO1CORS CO2 CO3 Function1CO1 1Flags1 SP1 Function1CO2 1Flags2 SP2 Function2CO3 1Flags3 SP3 0COUNTER 3MAX_ITER.bss.data
22
Resuming - right before CO2CURR SPT SPMAIN STK1 Registers Flags Addr1 STK2 ESP ………. STK3 Registers Flags Addr3 3numco CO1CORS CO2 CO3 Function1CO1 1Flags1 SP1 Function1CO2 1Flags2 SP2 Function2CO3 1Flags3 SP3 0COUNTER 3MAX_ITER resume: pushf pusha movEDX, [CURR] mov[EDX+SPP],ESP do_resume: movESP, [EBX+SPP] mov[CURR], EBX popa popf ret.bss.data
23
Resuming – resume is called CO2CURR SPT SPMAIN STK1 Registers Flags Addr1 STK2 ESP Addr2 ………. STK3 Registers Flags Addr3 3numco CO1CORS CO2 CO3 Function1CO1 1Flags1 SP1 Function1CO2 1Flags2 SP2 Function2CO3 1Flags3 SP3 0COUNTER 3MAX_ITER.bss.data resume: pushf pusha movEDX, [CURR] mov[EDX+SPP],ESP do_resume: movESP, [EBX+SPP] mov[CURR], EBX popa popf ret
24
Resuming – backup registers CO2CURR SPT SPMAIN STK1 Registers Flags Addr1 ESP RegistersSTK2 Flags Addr2 ………. STK3 Registers Flags Addr3 3numco CO1CORS CO2 CO3 Function1CO1 1Flags1 SP1 Function1CO2 1Flags2 SP2 Function2CO3 1Flags3 SP3 0COUNTER 3MAX_ITER.bss.data resume: pushf pusha movEDX, [CURR] mov[EDX+SPP],ESP do_resume: movESP, [EBX+SPP] mov[CURR], EBX popa popf ret
25
Resuming – backup stack pointer CO2CURR SPT SPMAIN STK1 Registers Flags Addr1 ESP RegistersSTK2 Flags Addr2 ………. STK3 Registers Flags Addr3 3numco CO1CORS CO2 CO3 Function1CO1 1Flags1 SP1 Function1CO2 1Flags2 SP2 Function2CO3 1Flags3 SP3 0COUNTER 3MAX_ITER.bss.data resume: pushf pusha movEDX, [CURR] mov[EDX+SPP],ESP do_resume: movESP, [EBX+SPP] mov[CURR], EBX popa popf ret
26
Resuming - load stack pointer of resume co-routine CO2CURR SPT SPMAIN STK1 Registers Flags Addr1 RegistersSTK2 Flags Addr2 ………. STK3 ESP Registers Flags Addr3 3numco CO1CORS CO2 CO3 Function1CO1 1Flags1 SP1 Function1CO2 1Flags2 SP2 Function2CO3 1Flags3 SP3 0COUNTER 3MAX_ITER.bss.data resume: pushf pusha movEDX, [CURR] mov[EDX+SPP],ESP do_resume: movESP, [EBX+SPP] mov[CURR], EBX popa popf ret
27
Resuming – set current co-routine variable CO3CURR SPT SPMAIN STK1 Registers Flags Addr1 RegistersSTK2 Flags Addr2 ………. STK3 ESP Registers Flags Addr3 3numco CO1CORS CO2 CO3 Function1CO1 1Flags1 SP1 Function1CO2 1Flags2 SP2 Function2CO3 1Flags3 SP3 0COUNTER 3MAX_ITER.bss.data resume: pushf pusha movEDX, [CURR] mov[EDX+SPP],ESP do_resume: movESP, [EBX+SPP] mov[CURR], EBX popa popf ret
28
Resuming – restore a state of loaded co-routine CO3CURR SPT SPMAIN STK1 Registers Flags Addr1 RegistersSTK2 Flags Addr2 ………. STK3 ESP Addr3 3numco CO1CORS CO2 CO3 Function1CO1 1Flags1 SP1 Function1CO2 1Flags2 SP2 Function2CO3 1Flags3 SP3 0COUNTER 3MAX_ITER.bss.data resume: pushf pusha movEDX, [CURR] mov[EDX+SPP],ESP do_resume: movESP, [EBX+SPP] mov[CURR], EBX popa popf ret
29
Resuming – go to execute the loaded co-routine CO3CURR SPT SPMAIN STK1 Registers Flags Addr1 RegistersSTK2 Flags Addr2 ………. STK3 3numco CO1CORS CO2 CO3 Function1CO1 1Flags1 SP1 Function1CO2 1Flags2 SP2 Function2CO3 1Flags3 SP3 0COUNTER 3MAX_ITER.bss.data resume: pushf pusha movEDX, [CURR] mov[EDX+SPP],ESP do_resume: movESP, [EBX+SPP] mov[CURR], EBX popa popf ret
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.