החלפת תהליכים

החלפת תהליכים במערכת ההפעלה מבוצעת על ידי קריאה לפונקצית resched. הקריאה יכולה להיות יזומה על ידי התהליך – קריאה ל-wait(), signal() וכו', או יזומה על ידי מערכת  ההפעלה.

בכל רגע נתון רץ רק תהליך אחד – התהליך הנוכחי. התהליכים האחרים ממתינים לביצוע או ממתינים למשאב כלשהו.

לפי הכניסה ל-resched, תהליך יכול לשנות את מצבו (למשל על ידי wait). אם אין תהליך במצב CURRENT ואם אסורה החלפת תהליכים, תתבצע קריאה ל-PANIC.

אם זאת, החלפת תהליכים במצב אסור איננה אפשרית, בהנחה שאין באגים במערכת ההפעלה.

אם קיים תהליך במצב CURRENT (כלומר מערכת ההפעלה יוזמת את ההחלפה), ואם אסורה החלפת תהליכים, resched תסתיים בלי לנסות להחליף תהליכים.

כל החלפות התהליכים ב-XINU נעשים רק באמצעות resched. הפונקציה resched קוראת לפונקצית עזר – ctxsw, המבצעת את ההחלפה בפועל. הנקודה בה ממש מתחלף ההקשר היא השורה ב-ctxsw בה אנו מחליפים את תוכן הרגיסטר SP.

כאשר תהליך 1 קורא ל-resched, החלפת התהליכים מתרחשת לפני סיום resched, אולם resched ממשיכה להתבצע, ובסופה היא מחזירה את הביצוע לתהליך 2.

resched, בדומה לקריאות מערכת אחרות, בודקת את תקינות הפרמטרים המגיעים אליה.

נשים לב כי resched לא נקראת במישרין על ידי המשתמש. היא חלק פנימי של המערכת.

בכל רגע, התהליכים הממתינים למעבד נשמרים בתור ממוין לפי עדיפות. תור זה נקרא ready queue. XINU ניגשת לתור זה על ידי המשתנים rdyhead, rdytail.

בתור ה-ready, האיבר בסוף התור הוא בעל העדיפות הגבוהה ביותר. התהליך הבא שירוץ יהיה התהליך הנוכחי, או איבר זה שבסוף תור ה-ready. התהליך הנוכחי איננו נמצא בתור ה-ready.

לפני שאנו מחליפים את התהליך הנוכחי, אנו צריכים לשמור את נתוני ההקשר שלו, על מנת שנוכל מאוחר יותר לגרום לתהליך להמשיך בפעולתו.

השדה היחידי בטבלת התהליכים המשמש בהחלפת תהליך הוא pregs (השומר את ערך SP, מצביע המחסנית). כל שאר נתוני ההקשר נשמרים על המחסנית.

כיצד נשמר כל נתון הקשר?

  • AX, BX, CX, DX נשמרים על ידי הקור ל-resched אם ערכיהם חשובים לו.
  • SI, DI, BP, Flags נשמרים על ידי ctxsw על גבי המחסנית.
  •  CS, DS, ES, SSאינם משתנים ולכן אינם נשמרים. (בפסיקה: נשמרים ברמת הפסיקה).
  • IP נשמר על ידי פקודת call ל-resched. הערך המעודכן ברגע ההחלפה אינו צריך להישמר.
  • SP ערכו לאחר הכנסת ההקשר למחסנית נשמר בטבלת התהליכים. משתחזר אוטומטית לערכו הקודם בהוצאה מהמחסנית.

משתני התהליך הנוכחי, שדות טבלת התהליכים ותור ה-ready מתעדכנים על ידי resched.

נביט בקוד של ctxsw:

_ctxsw proc   near

       push   bp

       mov    bp,sp         ; frame pointer

       pushf                ; flags save interrupt condition

       cli                  ; disable interrupts just to be sure

       push   si

       push   di            ; preserve registers

       mov    bx,[bp+4]     ; old stack save address

       mov    [bx],sp

       mov    bx,[bp+6]     ; new stack save address

       mov    sp,[bx]

       pop    di

       pop    si

       popf                 ; restore interrupt state

       pop    bp

       ret

_ctxsw endp

דגשים:

  • הפקודה cli היא למעשה מיותרת, כי אנו קוראים לפונקציה ctxsw תמיד מתוך resched, שכבר דאגה לבטל את הפסיקות.
  • push si, push di דוחפות את הרגיסטרים של התהליך הראשון. pop di, pop si שולפות את הרגיסטרים של התהליך השני.

תגיות המסמך:

מאת: באסל

תודה

הסברתם את זה, כמו שאר הנושאים, באופן הכי ברור שיש.
שיתוף:
| עוד