1 / 29

Practical Session 7

Practical Session 7. Co-Routines. co-routines are assembly implementation of threads each co-routine decides to which co-routine to pass a control - unlike “usual” threads. Co-routine state. co-routine is denoted by Coi , where i is ID of the co-routine scheduler is also a co-routine

nowles
Download Presentation

Practical Session 7

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  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 STKSZ equ 16*1024 CODEP equ 0 FLAGSP equ 4 SPP equ 8 section .rodata align 16 global numco numco: dd 3 CORS: dd CO1 dd CO2 dd CO3 section .data align 16 CO1: dd Function1 ; Structure for first co-routine Flags1: dd 0 SP1: dd STK1+STKSZ CO2: dd Function1 ; Structure for second co-routine Flags2: dd 0 SP2: dd STK2+STKSZ CO3: dd Function2 ; Structure for third co-routine Flags3: dd 0 SP3: dd STK3+STKSZ section .bss align 16 CURR: resd 1 SPT: resd 1 SPMAIN: resd 1 STK1: resb STKSZ STK2: resb STKSZ STK3: resb STKSZ

  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 extern printf global init_co_from_c global start_co_from_c global end_co init_co_from_c: push EBP mov EBP, ESP push EBX mov EBX, [EBP+8] ; EBX contains a number of the co-routine to be initialized mov EBX, [EBX*4+CORS] ; EBX contains a pointer to co-routine structure to be initialized call co_init pop EBX pop EBP ret co_init: pusha bts dword [EBX+FLAGSP],0 ; test if already initialized jc init_done mov EAX,[EBX+CODEP] ; get initial PC mov [SPT], ESP ; save original SP mov ESP,[EBX+SPP] ; get initial SP mov EBP, ESP ; also use as EBP push EAX ; push initial "return" address (initial PC) pushf ; push flags pusha ; push all other registers mov [EBX+SPP],ESP ; save new SP in structure mov ESP, [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. Co-routine resume 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 mov EDX, [CURR] mov [EDX+SPP],ESP ; save current SP do_resume: mov ESP, [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: push dword 1 push dword [CORS+8] push dword [CURR] push dword FMT1 call printf add ESP, 20 mov EBX, [CORS+8] ; resume a scheduler call dword resume push 2 push dword [CORS+8] push dword [CURR] push dword FMT1 call printf add ESP, 20 mov EBX, [CORS+8] ; resume a scheduler call dword 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: push dword 1 push dword [CORS] push dword [CURR] push dword FMT2 call printf add ESP, 16 mov EBX, [CORS] ; resume CO1 call dword resume push dword 2 push dword [CORS+4] push dword [CURR] push dword FMT2 call printf add ESP, 20 mov EBX, [CORS+4] ; resume CO2 call dword resume push dword 3 push dword [CORS] push dword [CURR] push dword FMT2 call printf add ESP, 16 mov EBX, [CORS] ; resume CO1 call dword resume push dword 4 push dword [CORS+4] push dword [CURR] push dword FMT2 call printf add ESP, 16 mov EBX, [CORS+4] ; resume CO2 call dword 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: push EBP mov EBP, ESP pusha mov [SPMAIN], ESP ; save SP of main code mov EBX, [EBP+8] ; get number of co-routine mov EBX, [EBX*4+CORS] ; and pointer to co-routine structure jmp do_resume End co-routine mechanism, back to c main end_co: mov ESP, [SPMAIN] ; restore state of main code popa pop EBP ret

  19. Main.c #include <stdio.h> 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 .bss .data

  21. Afterco-routine initialization .bss .data

  22. Resuming - right before .bss .data resume: pushf pusha mov EDX, [CURR] mov [EDX+SPP],ESP do_resume: mov ESP, [EBX+SPP] mov [CURR], EBX popa popf ret

  23. Resuming – resume is called .bss .data resume: pushf pusha mov EDX, [CURR] mov [EDX+SPP],ESP do_resume: mov ESP, [EBX+SPP] mov [CURR], EBX popa popf ret

  24. Resuming – backup registers .bss .data resume: pushf pusha mov EDX, [CURR] mov [EDX+SPP],ESP do_resume: mov ESP, [EBX+SPP] mov [CURR], EBX popa popf ret

  25. Resuming – backup stack pointer .bss .data resume: pushf pusha mov EDX, [CURR] mov [EDX+SPP],ESP do_resume: mov ESP, [EBX+SPP] mov [CURR], EBX popa popf ret

  26. Resuming - load stack pointer of resume co-routine .bss .data resume: pushf pusha mov EDX, [CURR] mov [EDX+SPP],ESP do_resume: mov ESP, [EBX+SPP] mov [CURR], EBX popa popf ret

  27. Resuming – set current co-routine variable .bss .data resume: pushf pusha mov EDX, [CURR] mov [EDX+SPP],ESP do_resume: mov ESP, [EBX+SPP] mov [CURR], EBX popa popf ret

  28. Resuming – restore a state of loaded co-routine .bss .data resume: pushf pusha mov EDX, [CURR] mov [EDX+SPP],ESP do_resume: mov ESP, [EBX+SPP] mov [CURR], EBX popa popf ret

  29. Resuming – go to execute the loaded co-routine .bss .data resume: pushf pusha mov EDX, [CURR] mov [EDX+SPP],ESP do_resume: mov ESP, [EBX+SPP] mov [CURR], EBX popa popf ret

More Related