OS PyramidTechnion 234123 · Operating Systemsbasics → exam
Stage 5: CPU Scheduling
2018A_Winter_BQuestion 2core25 pts

תזכורת: פונקצית הגרעין ()context_switch מבצעת החלפת הקשר בין שני תהליכים בלינוקס. הפונקציה משתמשת במאקרו switch_to אשר מוגדר באופן הבא עבור הארכיטקטורה 32-IA, כפי שלמדנו בתרגולים: ```c #define switch_to(prev, next, last) 1. movl prev, %eax 2. movl next, %edx 3. pushl %esi 4. pushl %edi 5. pushl %ebp 6. ??? 7. ??? 8. movl $1f, prev->thread.eip 9. pushl next->thread.eip 10. jmp _switch_to 11. 1: 12. popl %ebp 13. popl %edi 14. popl %esi ``` כאשר prev מצביע למתאר התהליך הנוכחי, ואילו next מצביע למתאר התהליך הבא שיקבל את המעבד. בני, סטודנט ללא ניסיון במערכות הפעלה, החליט להחליף את פקודת jmp בשורה 10 בפקודת call: ```c #define switch_to(prev, next, last) ... // lines 1--7 remained unchanged 8. movl $1f, prev->thread.eip 9. pushl next->thread.eip 10. call _switch_to ??? // a fix is needed here 11. 1: 12. popl %ebp 13. popl %edi 14. popl %esi ``` שימו לב: שורות 1--7 נותרו ללא שינוי (הן לא מוצגות שוב מטעמי חיסכון). כמו כן, שאר קוד הגרעין נותר ללא שינוי. משה, חבר של בני, לא רצה לשים את פקודת pushl לפני ה-call, ולכן הציע את הקוד הבא: ```c #define switch_to(prev, next, last) ... // lines 1--7 remained unchanged 8. movl $1f, prev->thread.eip 9. pushl next->thread.eip 10. call _switch_to ??? // a fix is needed here 11. 1: 12. popl %ebp 13. popl %edi 14. popl %esi ``` שימו לב: שורה 9 נמחקה. שורות 1--7 נותרו ללא שינוי (הן לא מוצגות שוב מטעמי חיסכון). כמו כן, שאר קוד הגרעין נותר ללא שינוי. אבי, חבר של בני ומשה, לא רצה שהמערכת תרוץ בצורה יעילה ומהירה. לכן אבי שינה את הקריאה לפונקציה switch_to מקונבנציית FASTCALL לקונבנציית GCC הרגילה: ```c void FASTCALL(__switch_to( struct task_struct *prev, struct task_struct *next)); ``` כדי לתמוך בשינוי הנ"ל, אבי העביר את הארגומנטים של הפונקציה switch_to_ על המחסנית במקום ברגיסטרים eaxedx: ```c #define switch_to(prev, next, last) // lines 1--7 remained unchanged 8. movl $1f, prev->thread.eip 9. pushl next->thread.eip pushl %edx pushl %eax 10. call _switch_to ??? // a fix is needed here 11. 1: 12. popl %ebp 13. popl %edi 14. popl %esi ``` שימו לב: שורה 9 עדיין מחוקה. שורות 1--7 נותרו ללא שינוי (הן לא מוצגות שוב מטעמי חיסכון). כמו כן, שאר קוד הגרעין נותר ללא שינוי.

Full original question text (raw OCR)

חלק 2 - החלפת הקשר (25 נק') בחלק זה כל השאלות הן מסוג רב-ברירה (שאלות אמריקאיות) כאשר לכל שאלה יש בדיוק תשובה אחת נכונה. בשאלות אלו יש להקיף את התשובה הנכונה ביותר לדעתכם ולנמק. 6. (5 נק') מה הצירוף של פקודות מכונה השקול לפקודה "call 0x12345"? a. after_call: pushl after_call jmp $0x12345 b. jmp $0x12345 pushl after_call c. pushl after_call after_call: jmp $0x12345 d. jmp $0x12345 pushl after_call after_call: e. pushl after_call jmp $0x12345 after_call: f. pushl after_call after_call: jmp $0x12345 נימוק: תזכורת: פונקצית הגרעין ()context_switch מבצעת החלפת הקשר בין שני תהליכים בלינוקס. הפונקציה משתמשת במאקרו switch_to אשר מוגדר באופן הבא עבור הארכיטקטורה 32-IA, כפי שלמדנו בתרגולים: #define switch_to(prev, next, last) 1. movl prev, %eax 2. movl next, %edx 3. pushl %esi 4. pushl %edi 5. pushl %ebp 6. ??? 7. ??? 8. movl $1f, prev->thread.eip 9. pushl next->thread.eip 10. jmp _switch_to 11. 1: 12. popl %ebp 13. popl %edi 14. popl %esi כאשר prev מצביע למתאר התהליך הנוכחי, ואילו next מצביע למתאר התהליך הבא שיקבל את המעבד. 7. (5 נק') מה הקוד החסר בשורות 6--7? תזכורת: פקודת movl a,b מעתיקה את התוכן של a ל-b. a. movl next->thread.esp, %esp movl %esp, prev->thread.esp b. movl %esp, prev->thread.esp movl next->thread.esp, %esp c. movl %esp, next->thread.esp movl prev->thread.esp, %esp d. movl prev->thread.esp, %esp movl %esp, next->thread.esp e. movl %esp, prev->thread.esp movl %esp, next->thread.esp f. movl prev->thread.esp, %esp movl next->thread.esp, %esp נימוק: בני, סטודנט ללא ניסיון במערכות הפעלה, החליט להחליף את פקודת jmp בשורה 10 בפקודת call: #define switch_to(prev, next, last) ... // lines 1--7 remained unchanged 8. movl $1f, prev->thread.eip 9. pushl next->thread.eip 10. call _switch_to ??? // a fix is needed here 11. 1: 12. popl %ebp 13. popl %edi 14. popl %esi שימו לב: שורות 1--7 נותרו ללא שינוי (הן לא מוצגות שוב מטעמי חיסכון). כמו כן, שאר קוד הגרעין נותר ללא שינוי. 8. (5 נק') למרבה הצער, הקוד החדש של בני לא עובד (הגרעין קורס מיד בשלב האיתחול). מה הקוד שיש להוסיף בין שורות 10,11 כדי לתקן את הגרעין? a. ret b. iret c. jmp $1f d. jmp next->thread.eip e. call $1f f. call next->thread.eip נימוק: משה, חבר של בני, לא רצה לשים את פקודת pushl לפני ה-call, ולכן הציע את הקוד הבא: #define switch_to(prev, next, last) // lines 1--7 remained unchanged 8. movl $1f, prev->thread.eip 9. pushl next->thread.eip 10. call _switch_to ??? // a fix is needed here 11. 1: 12. popl %ebp 13. popl %edi 14. popl %esi שימו לב: שורה 9 נמחקה. שורות 1--7 נותרו ללא שינוי (הן לא מוצגות שוב מטעמי חיסכון). כמו כן, שאר קוד הגרעין נותר ללא שינוי. 9. (5 נק') למרבה הצער, גם הקוד של משה לא עובד (הגרעין קורס מיד בשלב האיתחול). מה הקוד שיש להוסיף בין שורות 10,11 כדי לתקן את הגרעין? a. ret b. iret c. jmp $1f d. jmp next->thread.eip e. call $1f f. call next->thread.eip נימוק: אבי, חבר של בני ומשה, לא רצה שהמערכת תרוץ בצורה יעילה ומהירה. לכן אבי שינה את הקריאה לפונקציה switch_to מקונבנציית FASTCALL לקונבנציית GCC הרגילה: void FASTCALL(__switch_to( struct task_struct *prev, struct task_struct *next)); כדי לתמוך בשינוי הנ"ל, אבי העביר את הארגומנטים של הפונקציה switch_to_ על המחסנית במקום ברגיסטרים eaxedx: #define switch_to(prev, next, last) // lines 1--7 remained unchanged 8. movl $1f, prev->thread.eip 9. pushl next->thread.eip pushl %edx pushl %eax 10. call _switch_to ??? // a fix is needed here 11. 1: 12. popl %ebp 13. popl %edi 14. popl %esi שימו לב: שורה 9 עדיין מחוקה. שורות 1--7 נותרו ללא שינוי (הן לא מוצגות שוב מטעמי חיסכון). כמו כן, שאר קוד הגרעין נותר ללא שינוי. 10. (5 נק') כצפוי, גם הקוד של אבי לא עובד (הגרעין קורס מיד בשלב האתחול). מה הקוד שיש להוסיף בין שורות 10,11 כדי לתקן את הגרעין? a. jmp next->thread.eip popl %eax popl %edx b. popl %eax popl %edx jmp next->thread.eip c. ret popl %eax popl %edx d. popl %eax popl %edx ret e. ret popl %eax popl %edx popl %eax f. pop1 %edx popl %eax ret נימוק:

  1. 6· mcq· 5 ptsCPU Scheduling

    (5 נק') מה הצירוף של פקודות מכונה השקול לפקודה "call 0x12345"? a. after_call: pushl after_call jmp $0x12345 b. jmp $0x12345 pushl after_call c. pushl after_call after_call: jmp $0x12345 d. jmp $0x12345 pushl after_call after_call: e. pushl after_call jmp $0x12345 after_call: f. pushl after_call after_call: jmp $0x12345

    Voluntary vs preemptive context switchlibc syscall wrapper caching pitfallsPipe IPC semantics
  2. נימוק· short_answerCPU Scheduling

    Voluntary vs preemptive context switchlibc syscall wrapper caching pitfallsPipe IPC semantics
  3. 7· mcq· 5 ptsCPU Scheduling

    (5 נק') מה הקוד החסר בשורות 6--7? תזכורת: פקודת movl a,b מעתיקה את התוכן של a ל-b. a. movl next->thread.esp, %esp movl %esp, prev->thread.esp b. movl %esp, prev->thread.esp movl next->thread.esp, %esp c. movl %esp, next->thread.esp movl prev->thread.esp, %esp d. movl prev->thread.esp, %esp movl %esp, next->thread.esp e. movl %esp, prev->thread.esp movl %esp, next->thread.esp f. movl prev->thread.esp, %esp movl next->thread.esp, %esp

    Pipe IPC semantics
  4. נימוק· short_answerCPU Scheduling

    Voluntary vs preemptive context switchlibc syscall wrapper caching pitfallsPipe IPC semantics
  5. 8· mcq· 5 ptsCPU Scheduling

    (5 נק') למרבה הצער, הקוד החדש של בני לא עובד (הגרעין קורס מיד בשלב האיתחול). מה הקוד שיש להוסיף בין שורות 10,11 כדי לתקן את הגרעין? a. ret b. iret c. jmp $1f d. jmp next->thread.eip e. call $1f f. call next->thread.eip

    Pipe IPC semantics
  6. נימוק· short_answerCPU Scheduling

    Voluntary vs preemptive context switchlibc syscall wrapper caching pitfallsPipe IPC semantics
  7. 9· mcq· 5 ptsCPU Scheduling

    (5 נק') למרבה הצער, גם הקוד של משה לא עובד (הגרעין קורס מיד בשלב האיתחול). מה הקוד שיש להוסיף בין שורות 10,11 כדי לתקן את הגרעין? a. ret b. iret c. jmp $1f d. jmp next->thread.eip e. call $1f f. call next->thread.eip

    Pipe IPC semantics
  8. נימוק· short_answerCPU Scheduling

    Voluntary vs preemptive context switchlibc syscall wrapper caching pitfallsPipe IPC semantics
  9. 10· mcq· 5 ptsCPU Scheduling

    (5 נק') כצפוי, גם הקוד של אבי לא עובד (הגרעין קורס מיד בשלב האתחול). מה הקוד שיש להוסיף בין שורות 10,11 כדי לתקן את הגרעין? a. jmp next->thread.eip popl %eax popl %edx b. popl %eax popl %edx jmp next->thread.eip c. ret popl %eax popl %edx d. popl %eax popl %edx ret e. ret popl %eax popl %edx popl %eax f. pop1 %edx popl %eax ret

    Pipe IPC semantics
  10. נימוק· short_answerCPU Scheduling

    Voluntary vs preemptive context switchlibc syscall wrapper caching pitfallsPipe IPC semantics

The exam question — original PDF

pages 9, 10, 11, 12, 13

Exactly as it appears on the exam paper.

loading page 9
loading page 10
loading page 11
loading page 12
loading page 13

Built from these components

Ordered basic → advanced. Master the earlier ones first.

L2Voluntary vs preemptive context switchL2Latency vs throughput process classificationL3libc syscall wrapper caching pitfallsL3Pipe IPC semanticsL3SCHED_FIFO / SCHED_RR real-time policiesL3Non-preemptible kernel implications

Review the material

Read these before you answer — each verified slide teaches a component this question tests, and nothing from an unrelated topic is included. Tutorial slides show the actual slide image.

Tutorial 2slide 18קריאת המערכת exit()שאלה: למה בכלל לקרוא ל-exit(status) , אם אפשר פשוט לרשום return status בסוף פונקציית ה-main?תשובה:...

קריאת המערכת exit()שאלה: למה בכלל לקרוא ל-exit(status) , אם אפשר פשוט לרשום return status בסוף פונקציית ה-main?תשובה: main היא לא באמת הפונקציה הראשית של התכנית...main() נקראת ע"י __libc_start_main() שאוספת את ערך החזרה של main() וקוראת ל-exit().int __libc_start_main(…) { …… exit(main(…));}מסקנה: הפונקציה exit תמיד נקראת לסיום סטנדרטי של התוכנית.מערכות הפעלה - תרגול 218

Tutorial 2slide 22קריאות המערכת getpid(), getppid()pid_t getpid();קריאת מערכת המחזירה לתהליך הקורא את ה-pid של עצמו

קריאות המערכת getpid(), getppid()pid_t getpid();קריאת מערכת המחזירה לתהליך הקורא את ה-pid של עצמו.pid_t getppid();קריאת מערכת המחזירה את ה-PID של תהליך האב של התהליך הקורא.שאלה: מה המשמעות של getppid() == 1 עבור תהליך משתמש טיפוסי?תשובה: תהליך האב הוא init. קורה למשל אם תהליך הבן יתום.מערכות הפעלה - תרגול 222

Tutorial 2slide 24דוגמת קודמסכמתprintf("pid = %d\n", getpid());pid_t pid = fork();if (pid == 0) { printf("child pid = %d\n", getpid());...

דוגמת קודמסכמתprintf("pid = %d\n", getpid());pid_t pid = fork();if (pid == 0) { printf("child pid = %d\n", getpid()); char* args[] = {"/bin/date", NULL}; execv(args[0], args); printf("This should not be printed\n");} else { wait(NULL); printf("parent pid = %d\n", getpid());}פלט לדוגמה:pid = 8919child pid = 8920Sun Oct 29 00:31:32 IDT 2017parent pid = 8919מערכות הפעלה - תרגול 224

Tutorial 3slide 20FD (file descriptors)כל פעולות קלט/פלט של תהליך בלינוקס מבוצעות דרך "קבצים":קבצים "רגילים" לאחסון מידע (/usr/file

FD (file descriptors)כל פעולות קלט/פלט של תהליך בלינוקס מבוצעות דרך "קבצים":קבצים "רגילים" לאחסון מידע (/usr/file.txt) נמצאים בדיסק.התקני חומרה גם כן מיוצגים כקבצים, אבל נמצאים בזיכרון.למשל, העכברים המחוברים למחשב מיוצגים כ- /dev/input/mouseN .גם ערוצי תקשורת כמו pipes מיוצגים ע"י קבצים שנמצאים בזיכרון.הקשר בין תהליך לבין קובץ שהוא ניגש אליו נשמר, ברמת המשתמש, ע"י מספר שלם שנקרא file descriptor (FD).לדוגמה: קריאת המערכת open() מחזירה FD.המשתמש מעביר את ה-FD לקריאות מערכת כמו read(), write() כדי לקרוא ולכתוב לקובץ.מערכות הפעלה - תרגול 320

Tutorial 3slide 42שחרור file objectשאלה: מי מבצע את שחרור הזיכרון של file object? מתי ניתן לשחררו? ייתכנו מצבים בהם תהליכים שונים מצביע...

שחרור file objectשאלה: מי מבצע את שחרור הזיכרון של file object? מתי ניתן לשחררו? ייתכנו מצבים בהם תהליכים שונים מצביעים לאותו file object, לכן שחרור ה-file object יכול להתבצע רק לאחר ביצוע close() מכל התהליכים החולקים את אותו ה-file object. זכרו של-file object יש מונה (f_count) הסופר את כמות התהליכים המצביעים עליו בכל רגע נתון. המונה קטן באחד עם כל פעולת close() על האובייקט. כאשר המונה מתאפס, ה-file object ישוחרר.מערכות הפעלה - תרגול 342

Tutorial 5slide 2TL;DRזַמָּן התהליכים ((scheduler הוא הרכיב במערכת ההפעלה שאחראי על בחירת התהליך הבא שירוץ על המעבד

TL;DRזַמָּן התהליכים ((scheduler הוא הרכיב במערכת ההפעלה שאחראי על בחירת התהליך הבא שירוץ על המעבד.אנחנו נלמד, בתור דוגמה, את אלגוריתם הזימון של לינוקס.אבל לפני שנלמד דוגמה "אמיתית" ומורכבת, נרצה להבין את הגישות הבסיסיות בזימון תהליכים כדי לפתח אינטואיציה.מערכות הפעלה - תרגול 52זימון תהליכים בלינוקסCFS = completely fair schedulerאלגוריתם זימון של תהליכים רגיליםSCHED_FIFO, SCHED_RRאלגוריתם זימון של תהליכי זמן אמת

Tutorial 5slide 9דוגמת FCFSaverageResponseTime = (10 + 20 + 30) / 3 = 20כעת נסיר את הנחה 1 ("כל התהליכים רצים למשך אותו זמן")

דוגמת FCFSaverageResponseTime = (10 + 20 + 30) / 3 = 20כעת נסיר את הנחה 1 ("כל התהליכים רצים למשך אותו זמן"). לכל תהליך זמן ריצה משלו.תוכלו לחשוב על דוגמה שבה FCFS אינו יעיל?מערכות הפעלה - תרגול 59כל התהליכים רצים למשך אותו זמן.כל התהליכים מגיעים באותו זמן (t=0).אם תהליך התחיל לרוץ, אז הוא ירוץ עד לסיומו ללא הפסקות.התהליכים משתמשים רק במעבד ולא מבצעים I/O.זמן הריצה של כל התהליכים ידוע מראש.

Tutorial 5slide 15אלגוריתם SRTFSRTF = shortest remaining time firstנקרא גם: STCF = shortest time to completion firstאופן פעולה: כמו SJF...

אלגוריתם SRTFSRTF = shortest remaining time firstנקרא גם: STCF = shortest time to completion firstאופן פעולה: כמו SJF, אבל עם הפקעות.בכל פעם שתהליך חדש מגיע למערכת, SRTF מחשב למי מבין התהליכים (כולל התהליך החדש) נותר הכי פחות זמן לרוץ, ובוחר את התהליך הזה לריצה.תחת ההנחות החדשות, ניתן להוכיח כי SRTF אופטימלי במדד זמן התגובה הממוצע.בתוספת הנחה כי זמן החלפת הקשר הוא אפסי.מערכות הפעלה - תרגול 515כל התהליכים רצים למשך אותו זמן.כל התהליכים מגיעים באותו זמן (t=0).אם תהליך התחיל לרוץ, אז הוא ירוץ עד לסיומו ללא הפסקות.התהליכים משתמשים רק במעבד ולא מבצעים I/O.זמן הריצה של כל התהליכים ידוע מראש.

Tutorial 5slide 23נהוג לסווג תהליכים לשני סוגיםתהליך אינטראקטיבי I/O Boundמעוניין בזמן המתנה נמוך

נהוג לסווג תהליכים לשני סוגיםתהליך אינטראקטיבי I/O Boundמעוניין בזמן המתנה נמוך.latency sensitive.דוגמה: נגן סרטים שמחליף 60 פריימים בשנייה.בדרך-כלל מוותר על המעבד מרצונו אחרי פרק זמן קצר בגלל המתנה לפעולות I/O.תהליך חישוביCPU Boundמעוניין בזמן תגובה נמוך.throughput sensitive.דוגמה: סקריפט python שמנתח נתונים ע"י חישובים אלגבריים.בדרך-כלל לא מוותר על המעבד מרצונו אלא מופקע.מערכות הפעלה - תרגול 523

Tutorial 5slide 35מדיניות זימון של תהליךלכל תהליך זמן-אמת יש מדיניות זימון (scheduling policy):SCHED_FIFO או SCHED_RR

מדיניות זימון של תהליךלכל תהליך זמן-אמת יש מדיניות זימון (scheduling policy):SCHED_FIFO או SCHED_RR .נקבעת ע"י המשתמש באמצעות קריאות מערכת sched_setscheduler() .מדיניות הזימון – תשפיע על כמה זמן ריצה כל תהליך יקבל ואופן עבודת התור.מערכות הפעלה - תרגול 535

Tutorial 6slide 10מהי החלפת הקשר?מערכות הפעלה - תרגול 610

מהי החלפת הקשר?מערכות הפעלה - תרגול 610

Tutorial 6slide 11מהי החלפת הקשר?לכל תהליך יש "הקשר ביצוע" (execution context) המכיל את כל המידע הדרוש לביצוע התהליך

מהי החלפת הקשר?לכל תהליך יש "הקשר ביצוע" (execution context) המכיל את כל המידע הדרוש לביצוע התהליך.מחסניות, רגיסטרים, תכולת זיכרון, קבצים פתוחים, ..."החלפת הקשר" = עצירת הביצוע של התהליך הנוכחי ושמירת ההקשר שלו.טעינת ההקשר של התהליך הבא לביצוע.הקשר התהליך הנוכחי מתחלף – מכאן שם הפעולה "החלפת הקשר".מערכות הפעלה - תרגול 611

Tutorial 6slide 13שני סוגים של החלפת הקשרהחלפת הקשר כפויה(== הפקעה)הגרעין מפקיע (כלומר, לוקח בכוח) את המעבד מהתהליך, למשל בעקבות:פסיקת ...

שני סוגים של החלפת הקשרהחלפת הקשר כפויה(== הפקעה)הגרעין מפקיע (כלומר, לוקח בכוח) את המעבד מהתהליך, למשל בעקבות:פסיקת שעון (מטופלת בשגרה scheduler_tick) אשר מגלה כי הזמן שהוקצב לתהליך הנוכחי אזל.אירוע אסינכרוני אשר מעיר תהליך בעל עדיפות טובה יותר מהתהליך הרץ כרגע.לדוגמה: פסיקת דיסק או שחרור מנעול שתהליך המתין לו.החלפת הקשר יזומההתהליך מוותר מרצונו על המעבד, למשל באמצעות:קריאת מערכת חוסמת (כמו wait(), read(), …) אשר מוציאה את התהליך להמתנה.קריאת מערכת exit() אשר מסיימת את התהליך.קריאת מערכת sched_yield() – קריאת מערכת ייעודית לוויתור על המעבד.מערכות הפעלה - תרגול 613

Tutorial 6slide 35הפונקציה __switch_to_asm (3) popq %r15 popq %r14 popq %r13 popq %r12 popq %rbx popq %rbp jmp __switch_to מערכות הפעלה...

הפונקציה __switch_to_asm (3) popq %r15 popq %r14 popq %r13 popq %r12 popq %rbx popq %rbp jmp __switch_to מערכות הפעלה - תרגול 635שחזור הרגיסטרים ממחסנית הגרעין של next.אלו הרגיסטרים ש-next שמר כאשר הוא קרא להחלפת הקשר בעבר.קפיצה (jmp) במקום קריאה (call) לפונקציה. למה?כתובת החזרה מהפונקציה __switch_to() כבר שמורה על המחסנית של next.

Ask Gemini
2018A_Winter_B · Q2 — question + its material already loaded
Pick a shortcut above or ask anything about this question.
The exam text, the skills it tests, and the exact slides are already in context.