Process_SwitchLocks
السلام عليكم السلام عليكم يا شباب. السلام عليكم ورحمة الله.محاضرة النهارده خلاص الصوت لو سمحتوا الصوت
النهاردة إن شاء الله موضوع يخص الـ process. اتكلمنا الأسبوع اللي فات على الـ four main concepts بتاعت الـ OS. طبعا بالإضافة للintro يعني، النهارده بنتكلم على mainly two concepts منهم اللي هما الـ process والـ switching اللي ما بين.
الـ dual mode إن شاء الله. سريعًا نفتكر من آخر مرة، اتكلمنا على دور الـ OS وقلنا إن هو دوره متمثل في تلات حاجات. illusionist عشان يسهل الاستخدام، يوهمك إن، يوهم كل user program إن معاه infinite resources.
هو governor عشان يـ manage الـ resources بشكل efficient. وهو history teacher بيتعلم من الماضي عشان يـ predict الـ future. وشوفنا الـ evolution بتاعه بداية من إن كان uni-programming بيشغل single program at a time وبعدين.
اتطور بقى بيبدل ما بين البرامج بس استيل على single processor ده اللي سميناه multiprogramming. بعدين ظهر بقى الـ multiprocessor فبقى تقدر تشغل two or more processes at the same time parallel في نفس الوقت. بالإضافة طبعا إن هم بيبدلوا على مستوى كل برنامج.
أو كل CPU و اكلمنا أن عندنا أربعة main concepts مبني عليهم ال modern operating system الthreads اللى هى ممثلة في execution context بعبر عنه بقيم الregisters مع stack عشان أkeep track ال calling stack بتاعي
أما بفتح أكتر من thread معناها إن أنا كأن virtually كل واحد معاه processor خاص بيه. الـ stack بتاعها ممثل في الـ stack، يعني الـ thread بتاعها في الـ memory هو الـ stack.
بالإضافة للـ thread control block اللي هو شايل قيم الـ registers. هو ده بيتقال عليه عليه يتقال عليه كده مع بعضه thread. فأقدر أفتح منه أكتر من نسخة أو أكتر من thread يعني في نفس الوقت. اتكلمنا على الـ address space وقلنا إن بنوهم إن كل برنامج معاه الـ complete memory.
الـ complete address space خاص بيه هو، ما بيتواصلش خالص مع الـ physical رامات. فهو بيبقى برضه illusion موهوم إن معاه memory كاملة. اتكلمنا عن الـ process اللي هي دمج الحاجات دي مع بعض سواء الـ multiple threads مع الـ memory الـ address space كله والـ files والـ stack الـ heap.
والcode والdata shared، كل ده بيتقال عليه process. وهدف الـ process هي حماية مطلقة على مستوى الحاجات اللي جوه الـ process. فالحاجة اللي جوه الـ process بيبقى صعب جدًا إن هي تأكسس حاجة في process تانية إلا بإذنها بالاتفاق ما بينهم. بعد كده اتكلمنا إن من الحاجات اللي بتخدم الـ protection.
هو الـ dual mode إن بيبقى على الأقل عندي two modes، user وkernel. قلنا مين اللي بيـ support الـ modes دي؟ الـ hardware دي supported بالـ processor. مجرد ما بتخلي الـ bit بـ one يبقى user mode، zero يبقى supervisor. طول ما أنت user mode فانت معاك less privilege لو حاولت تـ access أي حاجة من الـ hardware مش مسموح لك تـ accessها.
بيترمى exception على طول بالـ hardware. وده أحد الحاجات اللي بتـ support الـ protection يعني. طبعا الـ OS هو دوره بقى إنه يتحكم إمتى أروح user وإمتى أروح kernel. بناكد على notes بشكل عام لو أي hidden slide في الـ presentation هي extra knowledge. النهارده عندنا تلات موضوعات رئيسية، الـ process management.
contents بتاعت الـ process والـ states المختلفة بتاعته. switching ما بين mode والتاني ما بين الـ user والـ kernel بيتم على أساس إيه وشكلين منه، شكلين رئيسيين منه. ونتيجة الـ switching ده ونتيجة الـ model اللي شغالين بيه هينتج عندنا.
مشكلة مشكلة خاصة بالـ concurrency فهنشوف إيه هي المشكلة وإيه سببها وإيه الحل بتاعها باستخدام الـ locks. دي الـ references. mainly يعني من الكتاب وفي extra references من lectures بتاعت Berkeley لو حد عايز يرجع ل.
تفاصيل أكتر. طيب الأول الـ OS كـ process management المفروض إنه يـ support خمس حاجات تخص الـ process. لازم يسمح إنه يبدل ما بين البرامج وبعض، ما فيش برنامج يستحوذ على الـ processor. يسمح له إنه يـ allocate resources، يعني البرنامج شغال وعايز يحجز memory.
لازم يدي له الحق في ده، عايز ياخد وقت على الـ processor لازم يدي له حقه، عايز يتعامل مع الـ printer مع الـ keyboard لازم يسمح له إنه يـ allocate resources. ولازم يضمن حاجتين في نفس الوقت والحاجتين عكس بعض، لازم يضمن الـ protection وفي نفس الوقت الـ sharing. protection by default والـ sharing لو أنت عايز. لو في اتفاق ما بين برامج إن هي تـ share حاجة.
زائد نقطة أخيرة إنه لازم يـ enable إن لو في processes شغالة مع بعض يـ enable إن هما لو عايزين يـ sync مع بعض، يتواصلوا مع بعض أو يـ sync مع بعض، لازم يسمح بحاجة زي كده. طيب دي الخريطة اللي اتكلمنا عنها الأسبوع اللي فات، الـ hardware تحت، الـ abstraction فوق، والبرامج الـ compiled zeros ones.
layer أعلى. البرنامج بيتكلم الـ hardware من خلال الـ abstractions دي واللي هي مجمعة كلها في struct سميناه process. فاحنا بنتكلم على الـ process. فمكونات الـ process هي mainly الـ address space وبقية الحاجات. الـ address space قلنا كل برنامج بيحتاج أربع مكونات رئيسية لازم.
تتحط له في الـ memory. الـ code اللي هو الـ machine code بتاعه، الـ global data اللي هي متعرفة pre-compiled يعني قبل الـ compilation ببقى عارفها. الـ stack والـ heap، واحد عشان function call والتاني علشان الـ dynamic allocation. ده ما يخص الـ memory. هكتب في الـ memory.
لازم يبقى ليه الاربع حاجات دول. بالاضافة بقى لأي معلومات تانية محتاجة أkeep track بيها عن البرنامج بحطها في struct داخلي اسمه process control block أو container يعني بخزن فيه أي attributes أنا محتاج أعرفها عن البرنامج.
غير الاربع حاجات دول زي ايه؟ الـ Time الـ Time الـ Time اللي هو اخده حتى الان الـ ID عشان اميزه عن غيره الـ Threads اللي هو شغل فيها الـ Threads اللي جوا قيم الـ Registers تاعتها كلها تابعة للـ Process
ال stack pointer سواء بتاعه هو او بتاع ال threads بتاعته. ال program counter او باختصار بقى قيم ال registers كلها ال program counter وال stack pointer وكل قيم ال registers كل دي معلومات محتاج ا keep track بيها عن ال process وهي شغاله.
فممكن اقسمها اقسام كده process info عامه، ID، priority، مين ال parent بتاعه لو هو جاي من parent، واي knowledge تانيه عامه عن الموضوع. اسمه، اسم البرنامج ده ايه. scheduling info، معلومات عن ال scheduling او عن ال threads، ايه ال threads بتاعته.
ال stack pointer بتاعه ال program counter بتاعه قيم registers بتاعه كل thread سواء ليه thread واحد او اكتر من thread. فاللي هما بنسميهم ال thread control block ممكن يبقى عندي block او اكتر. كل ده جوه ال process لان ال threads هي تعتبر من ضمن حاجات ال process. ال memory info
كل ما يخص ال memory مش احنا قولنا كل واحد بيبقى ليه memory خاصة بيه. فأنا عايز الجداول اللي هستخدمها عشان احول من ادرس وهمي virtual الى ادرس حقيقي physical محتاجه جداول بحتفظ بيها هنا. وكل اي حاجة تانية ايه مثلا ال devices اللي انا ماسكها دلوقتي او اللي انا مستني عليها ايه ال files اللي انا فاتحها دلوقتي.
ايه resources عموما اللي انا ماسكها دلوقتي. وكذلك ممكن يبقى عندي بعض ال accounting info زي وقت الprocessor واخد قد ايه من الprocessor. واخده قد ايه من الرامات كtotal. وهكذا كل دي معلومات عن كل process، كلها طبعا بشملها في.
struct يمثل ال process دي. طيب جوه ال code بقى بتاعنا اللي هو ان شاء الله هتشوفوه من معمل الاسبوع ده ابتداء من معمل الاسبوع ده يعني ده مكانه في ال code يعني في ال code عندنا struct اسمه env ده بيعبر عن ال process. هنبص نظره سريعه كده عنه في main info هو كله struct في الاخر.
main info عن ال process، اسمها، ال priority بتاعتها، حالتها إيه، ال state بتاعتها إيه، مين ال ID بتاعها وال parent بتاعها، كل دي general info عن ال process. تلاحظوا كلها عبارة عن integers، structs، pointers، مفيش حاجة غريبة يعني هو في الآخر code.
مثلا دي معلومات عن ال address space بتاعته مين الجدول اللي هستخدمه pointer على الجدول اللي هستخدمه عشان احول من address وهمي ل address حقيقي. عنده initially كام stack page انا مديهاله؟ مساحه ال stack قد ايه اللي انا مديهاله في الاول. ومكان ال stack فين. مكان ال stack بتاعه مثلا احنا هنا طبعا assuming ان احنا هنا.
في المعمل يعني شغالين single thread per process فعشان كده هو stack واحد بس. stack واحد للبرنامج. اه يعني historical point يعني هو هو ال FOS ده اللي هو ال OS اللي احنا شغالين بيه مبني على operating system قبله كان اسمه jos.
فهما كانوا مسمينه env فاحنا فضلنا مسمينه env يعني بس. عشان ما اقعدش نغير كتير في ال documentation بتاعتنا. وهكذا ومثلا دي statistics عن الموضوع عدد ال clocks اللي خدها على ال processor واخد كام clock حتى الان. عدد ال كلها counters لو تاخدوا بالكم كلها عباره عن counters او اعداد.
فكل دي info عامة عن الprocess يعني خلينا معلش احنا لسه في الاول فيعني مافيش معلومات كتير يعني لسه طيب ده ما يخص الprocess نيجي للstate بتاعت الprocess في الlife cycle بتاعتها
بتمر بمراحل. خلاص؟ فهنشوف المراحل الأساسية بتاعة ال process دي وإيه لازمة كل مرحلة منها. الأول ال five state، بنسميه five state model. معناه إن هي ال process ليها خمس حالات. ناخدهم بالترتيب.
new معناها process عملت لها ال struct بتاعها، اديتها بعض ال info العامة الخاصة بيها زي ال ID زي ال priority اسمها، بعض ال info العامة عنها لكن لسه ما حطتهاش في الmemory.
ده معنى new. يبقى new معناها إن process اتـ created، عايزة تشتغل بس لسه ما اتحطتش في الmemory. ده معنى new. أول ما أحطها في الmemory بتتنقل من حالة ال new إلى حالة ready. ready لإيه؟
ready إنه يشتغل على ال processor. ready إنه يشتغل على ال processor. ما تنسوش إن إحنا قلنا الأسبوع اللي فات أي process بتعمل حاجتين في حياتها كلها. يا بتـ execute على ال processor، يا بتتعامل مع device. بس فهي ready إن هي تـ execute على ال processor.
دي اسمها ready. وعادة عدد ال processes الـ ready بيبقى limited بال OS. يعني بيحدد عدد معين هو اللي بيبقى ready ما يزيدش عنه. ليه؟
يعنى هو ال protection مضمون كده كده. ما هو خلي بالكم إيه معنى إن هي ready؟ اتحطت في الmemory. فأنا لو فاتح الmemory يعني لو فاتح العدد.
هيكون كله هيخش يتخانق على ال memory كل واحد ياخد حتة صغيرة محدش هيعرف يشتغل في الآخر. فعشان كده في new وفي ready. new مفتوح كل اللي عايز يشتغل ok يستنى. عدد بقى الناس اللي هسمح لهم يخشوا في ال memory محدود علشان ما يحصلش.
إن الmemory تتملي ومحدش يعرف يشتغل. طيب. دخلت على ال processor خدت وقت على ال processor تبقى حالتها running. حالتها بقت running إن هي شغالة على ال processor. خلصت يعني البرنامج خلص خلاص بيخرج لحالة اسمها eg.
exit بسيبه في حالة exit على أساس أنت لو عايز تجمع statistics عنه بعد ما خلص عايز تعرف سبب ال-exiting ايه هل bug هل حاجة أي حاجة عايز تعرفها قبل ما أشيل البرنامج خلص من الmemory هي بتفضل في حالة
exit. exit. طيب ده الخط ده بس هو ممكن اثناء ما هو شغال يحتاج.. احنا خلي بالك احنا هنا شغالين مفيش طبعا ال model بتاع ال uni-programming ده انتهى خلاص. شغالين يا multi-programming يا multi-processing فكده كده البرنامج
بيبدل مع برامج تانية فممكن وهو شغال يحصل time out عليه يعني وقته اللي انا مديهوله خلص. بس هو لسه مخلصش يطلع يستنى فين؟ يطلع ياخد دور تاني فين؟ في ال ready. هو still في ال RAM بس طلعته من ال processor
وركنته قلتله استنى خد اللفه الجايه عشان ادخل حد غيرك. ده لو حصل time out يبقى بيتنقل من running إلى ready. او ممكن سبب تاني حضرتك يعني معلش احنا عايزين يعني استاذنكم يعني الاسئله نحاول تبقى minimize شويه لان
المحاضره يعني فيها content شويه فممكن لو حد لو في اسئله مش urgent ممكن نسجلها وممكن في ال break او بعد المحاضره. لو حاجه مش في صلب الفهم يعني
طبعا في فرق، في بقى فرق ما بين البرنامج هو اللي خلص safely يعني اشتغل وخلص او ان انا قفلته او ان هو رمى exception فتقفل كل دي بتتنقل لحالة exit
عايز بقى اعرف السبب اروح أcheck ال exit state دي او تساعدني في ان انا اعرف السبب. طيب فمن running لـ ready احد الاسباب ان ممكن يكون وقته خلص بس مش ده السبب الوحيد. ممكن يكون في واحد قبل ما وقته يخلص في واحد ليه high priority جه فبخرج ده عشان ادخل ده
ممكن يكون هو نفسه بيتطوع انه يسيب ال processor. في برامج كده اللي بنسميها ال background programs. programs بتشتغل في الخلفية. تشتغل شوية وهي لوحدها بتسيب ال processor لمدة وبعدين ترجع تطلبه تاني. كل دي اسباب بتخلي البرنامج يطلع من running إلى ready
طيب كل ده احنا بنتكلم على انه بيـ execute بنتكلم على الجزئيه دي. هو ما بيعملش ده بس، ممكن وهو شغال يحتاج I/O صح؟ حاجة من ال keyboard، حاجة يطلعها على الشاشة، على ال printer. ال I/O دايماً أبطأ حاجة في الجهاز. فأول ما يحتاج I/O
هو عادة مش هيعرف يكمل غير لما يخلص ال I/O request بتاعه. فبنقله من حالة ال running إلى حالة ال blocked. ان هو مستني على event، مستني على حاجة من ال keyboard. مستني الشاشة ال buffer بتاع الشاشة يفضى عشان احط فيه حاجة.
مستني ال printer تبقى جاهزة عشان أطبع، whatever مستني packet من ال network. كلها مستني مستني، فهو إيه؟ هو blocked. blocked عن مين؟ عن ال processor. blocked عن إنه يشتغل على ال processor. فهو واقف في طابور تاني بعيد عن ال processor. طيب
وهو blocked جاله ال event بتاعه، الحاجة اللي هو مستنيها جهزت. يرجع فين بقى؟ ready ولا running؟ ready ليه؟ ممكن في حد شغال بالظبط. فلو الحاجة اللي هو مستنيها ال waiting event جه، يتنقل من blocked إلى ready ياخد دور ويكمل.
كله على ال memory، كل ده على ال memory، كل ال states دي على ال memory، كلها على ال memory مفيش hard disk هنا. بعد كده في two in-direct states اللي هو ممكن من أي حالة غير ال running.
أطلع على exit على طول امتى؟ لو أنا اللي قفلته. أو قفلت ال parent بتاعه. يعني أنت مثلا فاتح Chrome، Chrome كل tab فيه بـ process. جيت قفلت ال Chrome كله كل اللي تحته بيتقفل، كل دي اسمهم children فكلهم بيتقفلوا.
فممكن whatever الحالة بتاعتك تطلع على طول على exit. طيب بنـ manage ال states دي ازاي بقى؟ يعني إحنا قلنا إن كل process بنعبر عنها بـ process control block اللي هو شايل ال struct اللي شايل معلومات عن ال process.
بعبر بقى عن ال states دي ازاي؟ كل state منهم وارد يبقى عليها أكتر من process. فأوقع وأسهل data structure استخدمها هنا هي إيه؟ queue طابور. اللي جه الأول.
ياخد يطلع الأول. اللي جه new الأول يطلع على ready الأول، اللي جه ready الأول يطلع على running الأول وهكذا، كلها عبارة عن queues. queue لل ready. queue لل ready.
queue لل waiting event اللي هم ال blocked. blocked 1, blocked 2, blocked 3 ليه في أكتر من blocked؟ على حسب أنا blocked على إيه؟ يعني اللي مستنيين على ال keyboard غير اللي مستنيين على ال scanner غير المستنيين على.
فكل حاجة blocked بـ block عليها بيتعمل لها queue بستنى عليها. طبعا مين بقى اللي بيتحط في ال queue دي؟ ال process. إيه اللي بيعبر عن ال process؟ ال process control block، ال PCB بتاعها.
فاللي بيتنقل من queue للتاني يعني ال queues دي شايلة إيه في الآخر؟ شايلة pointers على ال process control block بتاع ال process دي سواء ال process ال ready أو ال running أو الواقفة على event.
ال scheduling بقى فكرته إنه يختار مين؟ يعني أنا عندي في ناس كتير في ال ready أختار مين؟ ده بقى issue هنعالجها إن شاء الله كمان تلات أو أربع محاضرات. ال model ده اللي بنسميه five state model فيه مشكلة.
إحنا عارفين إن ال processor أسرع بكتير من ال devices. فبعد شوية بعد مدة هتلاقي إن ال processor خلص كل الناس اللي في ال ready. كلهم يا إما خلصوا يا إما بقوا مستنيين على على I/O. ونتيجة إن ال I/O بطيء
فهتلاقي إن في هنا most of the processes هنا أهو وده almost free. مفيش حد واقف على على الطابور بتاع ال processor. يعني ال processor فاضي والزحمة كلها على ال devices. ليه؟
ال processor سريع فخلص وال devices بطيئة فكله بقى إيه عطلان على ال devices وال processor قاعد إيه فاضي. طبعا ده ك resource manager سيء. تفتكرين الأسبوع اللي فات قلنا لازم هو ك resource manager يتأكد إن ال resources كلها مستغلة. فالوضع ده هيبقى
ما فيش ناس على ال processor وكله موجود فين؟ في ال I/O. ده مش efficient solution مش مش مش حاجة كويسة بالنسبة لل OS ك governor. طب يعمل إيه بقى ساعتها؟ يعمل إيه؟ يجيب ناس جديدة. طيب إيه اللي بيمنعه إنه يجيب ناس جديدة؟
memory. memory. فهو لو عنده إمكانية يجيب ناس جديدة هيجيب ناس جديدة على ال processor. طيب. بس ممكن ده ما يبقاش مفتوح لإن إحنا في الآخر في limit على العدد. لو
يبقى إيه؟ ما كده أنا ببطئ ال processor يعني أنا كده هو معايا ميزة وبخسرها. يعني يعني في الآخر ال processor أنا هو المشكلة عند ال devices مش عند ال processor. فهنا الحل فعلا إن أنا أجيب ناس. طب إيه اللي يمنعني إن أنا أجيب ناس؟ إن ال memory تكون مليانة.
طيب الmemory مليانة ودول كده كده عطلانين هم blocked يعني عطلانين تعمل إيه؟ حط على ال disk. ما هم كده كده على ال memory وعطلانين، ارميهم على ال disk. أو ارمي بعضهم على ال disk. ده اللي بنسميه suspend state. طلع من ال memory وارمي على ال disk
طلع من ال memory وارمي على على ال disk. طلع مين؟ أطلع من دول. من دول يروحوا على ال disk. فلما يروحوا على ال disk أقدر أدخل هنا new processes تاخد وقت ال processor.
لا على الوضع ال five state هما still في ال memory مش على ال disk. آه آه لا new هي لسة أصلا ما اتعملهاش حاجة غير ال struct بتاعها فقط. ال exit still حاجاتها في ال memory موجودة لحد أما أنت تقرر إن أنت تمسحها.
ال new ما فيش غير ال struct بتاعها هو اللي معمول. ال struct فقط، يعني لا اتعمل لها stack ولا heap ولا code ولا data، فهي لسه ال exe ما اتفتحش أصلا. هي بتـ indicate بس إن هي عايزة تشتغل. طيب فبيظهر عندنا هنا
two states جداد بنسميهم ال blocked suspend وال ready suspend. suspend يعني مركون على ال disk. طيب blocked suspend يعني إيه؟ blocked يعني أنا مستني على device وبما إني كده كده مستني فراح هو خدني وركني فين؟
على ال disk. خد كل كل البرنامج مساحته في ال memory راح واخدها كده من ال memory وراميها على ال disk. ده blocked suspend. ready suspend كنت أنا ready كنت أنا ready ومستني وقت ال processor رحت أنت راكني على ال disk.
ده معنى ready suspend. طب إمتى الحالة دي تظهر؟ هي الحالة دي غريبة، strange، يعني أنا كده كده جاهز ليه ترميني على ال disk؟ إن هو هو كان أصلا blocked على ال disk.
على ال disk. جاله ال event اللي هو مستنيه. اتنقل من blocked إلى ready وهو still على إيه؟ على ال disk. ده سبب. ده سبب لل state دي. خلاص؟ نيجي لل transitions بقى. إمتى بنقل من blocked إلى blocked suspend؟ لو ما فيش ناس على ال ready.
لو مفيش ناس على ال ready ومش عارف أدخل جديد فبرمي على ال disk. طيب فعشان بفضي memory يعني. من blocked suspend إلى ready suspend لو ال event جالي. من ready suspend إلى ready؟ إن أنا في إمكانية إن أدخل ناس جديدة.
سواء إن مفيش ناس على ال ready أصلا فبدخل من ال ready suspend أو إن في ناس ready suspend high priority عن الناس اللي ready دلوقتي. فببدل بخرج.
اللي كانوا ready وأدخل اللي كانوا suspended عشان هم high priority. يبقى سبب تاني من أسباب ready إلى ready suspend هو ال priority. سبب تاني إن لو عندي high priority.
لو في high priority عايز أدخلها. أو أو أنا ممكن يكون عندي ناس في ال ready وناس في ال blocked بس محدش عارف يشتغل ليه؟
كبروا، البرامج دي كبرت في ال memory فمبقاش عندي مساحة تكفي ولا برنامج عارف يشتغل. فبضطر ساعتها suspend، suspend حتى من ال ready. suspend من ال ready عشان أفضي مساحة من ال memory. لو أنا وصلت إن أنا بـ run out of memory.
memory. ما عنديش memory فبركن ناس من ال ready
state برضه جديدة، transition جديد اسف من ال new الى ready suspended ده عشان a maintain هو بصوا كده كده.
كده كده زي ما هنشوف ان شاء الله ابتداء من المحاضرة الجاية كده كده اي برنامج بيشتغل حاجته لازم تبقى محطوط منها نسخة على ال disk عشان اقدر أ swap in و out. فكده كده هو هيتركن على ال disk يعني حاجته هتتحط على ال disk.
فبدل ما استنى ان هو يبقى ready في ال memory وبعدين اما يبقى suspended اركن حاجاته على ال disk او اكتب له حاجاته على ال disk انا استغل ال offline في ال offline background ان انا a maintain pool من ال ready suspended.
مين ال ready suspended؟ اللي انتوا بقى قلتوها، ناس عايزة تشتغل كانوا new جهزت لهم حاجاتهم على ال disk. فوفرت الوقت ده، فيوم أما أعوز أسحب، أسحب على طول من فين؟ من هنا، ما استناش بقى إن أنا أحطهم new وبعدين أبقى أحط لهم نسخة على ال disk.
على ال disk استغل الوقت ده. خلاص؟ اخر transition ممكن من running الى ready suspended على طول ده في حالة لو في high priority فانا ما استناش اروح ready وبعدين اروح suspended اطلع على طول على ready suspend. في اي سؤال؟
ازاي ال event هيجيلي وانا blocked suspend اصلا؟ اصل ال event مش بيجيلك انت. ال event بيجي لل OS وال OS بيبقى عارف ان انت اللي مستنيه على على ال event ده. بالظبط ما هو يعني event جه على ال queue ده.
يروح ال OS مhandle ال event يشوف مين اللي كان مستني على ال queue ده؟ مين اللي مستني هنا؟ لا ما هو دلوقتي في event جه على مثلا ال keyboard، انا كنت مستني على ال keyboard اتركنت على ال disk فاتحطيت في queue اسمه اللي مستنين على ال keyboard.
في ال disk. فلما جه ال event بتاع ال keyboard بيبتدي ال OS يcheck مين اللي كان مستني على ال event ده؟ فيعرف ان هو انا يروح ناقلني من من ده لده وانا still على ال disk.
ما انا لسه ما خدتهوش انا هو just نقل حالتي من ان انا في طابور ال blocked suspended إلى طابور ال ready suspended يعني انا دلوقتي ينفع اخش على ال processor.
أه بس لازم أبقى ready الأول يعني لازم أبقى ready الأول يعني يرجعني تاني ال memory. طيب نيجي إلى ده كده اتكلمنا على concept ال process وال states بتاعته.
في concept تاني اللي هو ال dual mode. تعالوا نـ review سريعا ال dual mode ده نفتكره مع بعض. قلنا عندنا two modes, kernel mode بـ full privilege و user mode بـ less privilege. transitions من user لـ kernel ليها تلات أسباب
يا إما interrupts يعني حاجة خارجية بتوقفني علشان أنفذ حاجة وبعدين أرجع أكمل. في الغالب مثلا حرف من ال keyboard جهز، ال printer جهزت، ال screen جهزت فبيجي يوقفني لإن هو زي ما بتقولوا إيه ما بيصدق إن ال device جهز لإن ال device أصلا بطيء
فلما بصدق إنه يجهز فبـ interrupt و whatever مين اللي كان شغال بقوله إلحق ال device عايز تدخل دلوقتي عشان تمشي ال device وبعدين ترجع تكمل شغلك تاني. أو يا إما يبقى exception وده بيبقى internal جوه البرنامج رمى exception أو إن هو
system call يعني إيه؟ بيطلب حاجة من ال OS بإذن ال OS. فاتكلمنا عن الكلام ده الأسبوع اللي فات قلنا وأنا بـ execute البرنامج بنقله من أنا ببقى kernel أول ما بشغل برنامج بيتنقل على user mode. يفضل في ال user mode لحد أما يـ exit.
يرجعني تاني kernel وهو بقى شغال ممكن تحصل واحدة من التلاتة دول أو تلاتة. ممكن يحصل system call فبينادي ال kernel بيـ switch من user لـ kernel عشان ينفذ حاجة وبعدين يرجع تاني. أو ممكن يحصل interrupt فبيروح لل kernel يخدم ال interrupt ده ممكن يبقى رايح جاي أكتر من مرة وبعدين
يرجع تاني لل user لل program اللي كان حصل له interrupt. فهنا برضه ده سبب للنقلة من user لـ kernel. أو إنه يحصل exception. ال exception حاجة من اتنين يا هتعرف تهندله فترجع يا بتـ crash البرنامج. بتروح قافل البرنامج وده ما بيأثرش على بقية ال system لإن بقية كل برنامج ليه process فأنت قفلت بس
ال process دي. switching models بقى عشان أ switch من user إلى kernel عندي واحدة من تلاتة options يا إما كل user thread بيتعمل له corresponding kernel thread
kernel thread. يعني إيه الكلام ده؟ يعني كل برنامج code بيتنفذ كل أما يروح على ال kernel يبقى له thread خاص بيه بيخدمه. يبقى كل برنامج أو كل thread في ال user ليه thread بيخدمه في ال kernel.
إيه ميزة حاجة زي كده؟ لا هو ال transition كده كده هو وارد يعني بس هو كده كده في وقت ثابت علشان أ... أعمل transition أصلا ده كده كده وقت ثابت.
بالعكس أنت هنا ممكن يبقى ال thread ده شغال عند ال kernel، ال kernel بيخدمه وأنا مثلا عندي 8 processors فيبقى عندي 8 برامج
كلهم ال kernel بيخدمهم.parallel بيعمل لده حاجة ولده حاجة ولده حاجة هو هو ال kernel بس بينفذ لكل process حاجاتها. فهنا ده more parallelized يعني
يديني إمكانية ال parallelization أكتر خاصة أما بروح عند مين؟ عند ال kernel. لإن في الآخر هو kernel واحد. فمعنى إن كل thread في ال user ليه thread في ال kernel معناها إن أنا أقدر أ parallelize بشكل أفضل. بس عيبه إيه؟ آه يعني إيه thread هنا؟ يعني إيه كل thread هنا ليه thread هنا؟ يعني إيه
يعني struct و stack. يعني struct للقيم ال registers و stack جديد. يبقى كده كل thread عند ال user ليه registers و stack وأما بيروح عند ال kernel ليه register و stack. هنا بـ consume memory أكتر. البديل عكسه.
إن كله يروح على single entry point عند ال kernel. يعني هو single thread عند ال kernel. main entry point تدخلني عند ال kernel. فلو واحد عند ال kernel يبقى الباقي فين؟ لو محتاج ال kernel يستنى. ده حلو من ناحية
توفير ال memory بس مش حلو من ناحية ال parallelization. عكسه ده تماما عكس ده ده عكس ده. خلاص؟ ساعات بقى بيعملوا compromise بين الاتنين إن يعملوها many to many يعني multiple user threads ليهم multiple kernel threads بس مين طبعا اللي أقل في العدد؟
ال kernel threads خلاص؟ بس إحنا ال model اللي شغالين بيه في المعمل وفي المحاضرات أو في ال project يعني وفي المحاضرات هو ال model ده علشان ال parallelism عشان نقدر ندي performance أفضل يعني بغض النظر عن طيب إمتى بيحصل switching؟
قلنا يا interrupt يا exception يا system call. بيحصل بقى ازاي؟ يعني إيه الفكرة اللي وراه؟ بيبقى عنده كله جاي بسبب اللي بيبلغ بيه هو ال hardware. إيه في ال hardware؟ حاجة بنسميها
ال programmable interrupt controller.
 circuit على ال hardware اسمها PIC. بتعمل إيه ال circuit دي؟ لو أنا عندي hardware, printer, scanner, whatever, network card, clock timer
كل أما device من دول يعوز تدخل من ال OS يبعت interrupt. دي اللي بنسميها interrupts أو hardware interrupts إن ال device هو اللي عايز حد يخدمه. فدي بنسميها hardware interrupts. فبتبعت على ال controller ده.
أو ممكن يكون ال software البرنامج نفسه هو اللي رمى على ال controller ده يا إما رمى exception قسم على صفر ده exception يا إما طلب إيه؟ system call. فالاتنين دول جايين من ال software.
كله بيروح على ال interrupt controller دي. تعمل إيه ال controller؟ تبعت signal interrupt لل processor ومعاها ال ID بتاع ال interrupt. لإن أنت عندك أنواع وأشكال هنا ممكن تبقى system calls، ممكن تبقى exceptions، ممكن تبقى interrupts مختلفة فهو كل واحد ليه ID.
فبيروح باعت interrupt signal لل processor يقوله عايزك دلوقتي لازم توقف ويبعت ال ID بتاع ال interrupt دي. طيب بس ممكن يحصل إن في أكتر من حد يبقى جاهز في نفس الوقت. يعني ممكن يبقى في أكتر من device باعت interrupts في نفس الوقت.
صح؟ أو في exceptions اترميت exception مع interrupt جه في نفس الوقت. فاللي بيتحكم في ده هو ال controller ده. بيبقى عنده قدرة إنه يـ mask بعض ال interrupts. يعني أنت ممكن وأنت شغال تـ mask، mask يعني إيه؟ تمنع
تمنع بعض ال interrupts وتسمح ببعضها. ده مين اللي يعمل كده؟ هو هو ال controller عنده الإمكانية دي لكن مين اللي بيتحكم؟ ال OS. ال OS. خلاص؟ زائد إنه عنده برضه ال controller ده priority encoder.
بحيث ان انا لو جالي interrupts من كذا device هم مترتبين ب priorities بالظبط. مترتبين ب priorities، اللي ليه أعلى priority هو اللي يتبعت لل processor. لإن ما تنساش إن ال processor في الاخر هيقدر يخدم إيه؟ حاجة واحدة منهم بس.
طيب حقه ما هو كل في ال multiprocessor كل processor عنده عنده circuit من دي. خلاص؟ طيب بس ناخد بالنا من حاجة إن ال masking ده
ال masking ده valid بس على ال hardware interrupts. ما ينفعش أ mask exception من software. software عمل كارثة. ما هو exception يعني كارثة. ما ينفعش أ mask ده. فدول ما ينفع دول تلاحظوا الخط هنا بيعدي فكرة ال masking.
طيب طبعا اللي بيتحكم في ده كله هو ال OS. في برضه على مستوى ال processor كله interrupt flag. ده بقدر أخليه ب 1 أو ب 0 عن طريق set interrupt أو clear interrupt. لو خليته enabled يعني أنا سامح إنه يجيلي interrupts.
لو disabled يبقى أنا مانع مانع مين؟ ال interrupts. ال interrupts اللي هي جاية من ال hardware دول. مانع دول. مانعهم كلهم بفلاج واحد، أنا ممكن أمنع واحد واحد.
ممكن أمنعهم كلهم بالإيه؟ بالفلاج ده على مستوى ال processor كله. خلاص؟ لا يا شباب خلينا نكمل الصورة معلش وبعدين يعني ال flag لكل processor خاص بال processor ده في جوه ال processor.
زائد بقى إن في interrupts بنسميها non-maskable interrupts. هي interrupt جاية من hardware بس هي مش خاضعة لإيه؟ لل masking. مش خاضعة لل masking. دي في الغالب بتبقى بسبب ال hardware failure.
ال hardware failure أما hardware عندك يحصله failure ما ينفعش أ mask ال interrupt ده. بيسموها non-maskable interrupts. طيب دلوقتي ده كده من ناحية ال hardware يعني جالي ك processor
جالي signal interrupt اعمل إيه بقى المفروض إيه اللي يحصل؟ مين اللي يتدخل هنا؟ ال OS. ال OS. طيب كل واحد من دول المفروض ليه حاجة بتخدمه. يعني اللي بيخدم ال keyboard code مختلف عن اللي بيخدم ال printer عن اللي بيخدم
ال scanner عن اللي بيخدم ال exception بتاع ال device. فالمفروض إن كل واحد من دول على حسب ال ID بتاعه يوديني على مكان code يخدمه. لا ال CPU ده hardware.
registers منه هعرف مكان ال code اللي يخدم الحاجة دي. ازاي؟ عن طريق table اسمه ال interrupt descriptor table. جدول. الجدول ده فيه 256 entry.
كل entry مربوطة بال ID بتاع ال interrupt مش إحنا قولنا كل interrupt ليه ID. فأنا مثلا مثلا zero معناها إن أنا قسمت على صفر.
فلما يبعتلي هنا  0 يوديني على الجدول ده على نمرة 0 هنا. وهكذا واحد يوديني على واحد، اتنين يوديني على اتنين، يوديني automatic على الجدول ده. في إيه الجدول ده متخيلين؟ لا مش processes ده أنت أنت هنا رايح عند مين؟
عند ال process ولا عند ال kernel؟ يعني ال interrupt ده جاي مين اللي يخدمه؟ ال kernel. فأنا رايح عند ال kernel، رايح عند code في ال kernel. فالمفروض إن كل entry هنا فيها ممتاز ممتاز، address بتاع قطعة ال code اللي هتخدم
الحاجة دي اهو offset فيها طبعا حاجات كتير بس اللي يهمنا منها ال offset ده. ال offset يعني ال address بتاع ال entry point اللي في ال memory اللي هتخدم
ال corresponding interrupt ده. فكل ده مين اللي بيظبط الجدول ده؟ ال OS. أما بقى بيجيلي في ال hardware يجيلي interrupt automatic الإشارة اللي جاية دي
بالرقم بتخش هنا تتعامل مع الجدول ده على إنه array تروح عاملة indexing للجدول ده تطلع منه بالمكان اللي المفروض يخدم الحاجة دي يروح ينفذه. فاللي مظبط الجدول ده ال OS اللي بيـ access الجدول ده و
يوصل من ال ID إلى المكان المناظر ليه هنا ده hardware. ال addresses اللي هنا سؤال كويس جدا، ال addresses اللي هنا virtual ولا physical
virtual. virtual. لإن لسه هتخش على احنا قلنا الأسبوع اللي فات إن حتى ال OS حتى ال OS أي address بيطلع منه بيطلع إيه؟ address وهمي virtual لإن كده كده هيخش على ال memory management unit عشان تحوله ل physical.
حتى لو هو OS. ده محكوم بال hardware يعني يعني ال hardware نفسه مفيش connection طالع من ال address اللي جاي من ال processor إلى الرامات مباشرة. مفيش اصلا كـ hardware. يعني ال address اللي طالع من ال processor مش واصل على الرامات، واصل بإيه؟ memory management unit هي اللي
processor، حتة من ال processor.
 unit unit خاصة في ال processor. طيب يا شباب عشان الوقت بس معلش عشان الوقت. طيب
إيه اللي بيحصل بقى أما بتيجي interrupt؟ لو جالي أي interrupt سواء أيا كان سببه يعني. لو هو لو أنا كنت user لو أنا كنت شغال في user mode وجالي interrupt فبتنقل automatic من user ل kernel.
على ال model بتاعنا معناها بتنقل من ال stack بتاع ال user إلى ال stack بتاع ال corresponding kernel thread الخاص بيه. طب عشان يعرف يرجع محتاج يحتفظ بإيه؟ ال return address وكمان محتاج يحتفظ بال return stack، ما أنا نقلت من
من thread عند ال user إلى thread عند ال kernel يبقى لازم احتفظ بمكان ال stack اللي أنا جاي منه، ما أنا نقلت دلوقتي من stack للتاني فلازم احتفظ بمكان ال stack اللي هو ده ممثل في ال stack pointer وال stack segment واحتفظ بال return address
ال address اللي أرجع عليه. فده ال caller stack وال address اللي هرجع بيه. فأتوماتيك بيحصل pushing لل values دي automatically بال hardware.
ال interrupt cycle دي كلها managed بال hardware دلوقتي. يعني من ساعة ما جت وراحت للمكان اللي تخدمه كل ده hardware. فأتوماتيك بيروح حاطط في ال stack مكان عشان اعرف أرجع منه بال hardware برضو. كده بقى اتنقلت من ال stack ده إلى ال stack ده. ده عند مين؟ ده عند مين؟
kernel ده بتاع ال kernel الخاص بيا. أقلل الأسئلة شوية معلش. طيب العكس بقى لو أنا ممكن أكون كنت شغال في ال kernel وجالي interrupt. ما هو ما هو في آخر ال kernel ده code.
لو أنا كنت فاتح ال interrupt، ال flag عامله ب 1 وأنا في ال kernel، هيجيلي interrupts عادي. طيب بس أنا دلوقتي أنا في ال kernel وجالي interrupt، ما أنا في ال kernel. هروح فين؟ هفضل في ال kernel، يعني هفضل على نفس الإيه؟
ال stack. وبالتالي محتاج أ push إيه بس؟ ال IP، ال address. ال address اللي هرجع منه، ال IP فقط. ال IP اللي هو ال return address عشان أعرف أرجع. لكن لكن أنا على نفس ال stack.
لا لا مش على نفس ال thread. ما هو ال thread أنا كنت شغال في ال thread عند ال kernel، حصل exception، ال exception ده خاص بال thread ده. وأنا still عند ال kernel وبخدمه في ال kernel. kernel kernel في kernel يعني. خلاص؟ بس طبعا بيبقى في عندنا برضه flags دي اللي هي ال flags register.
أكيد سمعتوا عنه صح؟ اللي هو بيبقى فيه ال carry وال sign وال overflow flag، ال interrupt flag. ال flags اللي هي ال bits اللي بتـ indicate حاجة يعني. فكلها برضه بيحصلها pushing لإن وارد إن هي تتغير.
أما أجي أ return بقى يعني أنا خلصت ال interrupt أرجع على مين؟ على ال IP بالظبط، بس بتختلف على حسب السبب اللي جابني. لو أنا جاي بسبب hardware interrupt يبقى برجع بعد آخر instruction اتنفذت. بعد آخر instruction اتنفذت عشان أرجع أكمل.
لو أنا جاي بسبب system call فبرجع على بعد آخر بعد ال instruction اللي سببت ال system call. لو أنا جاي بسبب exception أرجع على اللي عملت ال exception ما هو مش هعديها. لازم أرجع لها هي عشان أتأكد إن هي باصت صح.
finally طبعا لو لو unhandled exception فبرجع بـ abort، abort signal يعني. في دقيقة ناخد أسئلة لو في حد ليه أسئلة.
على ال kernel ما أنا أنا كنت شغال في ال kernel code عند السطر الفلاني حصل interrupt هنقل على code تاني عايز أرجع بقى لل code ده. شباب الصوت لو سمحتوا معلش، الصوت عشان أسمع على الأسئلة.
صوت يا شباب. صوت. أستأذنكم الصوت عشان أسمع الأسئلة بتاعة زمايلكم. علي صوتك. لو في interrupt ومفيش code يهنندله
ده غلطة OS هيcrash ال system. هتلاقي هتلاحظوها في المعمل. أنتوا أما تيجوا تكتبوا الأسبوع ده واللي بعده في المعمل إحنا لسة مش مهندلين أي حاجة. أي غلطة صغيرة بتعملها تلاقي ال OS بيـ restart.
ليه بيـ restart لإن مفيش حاجة متهندلة. طيب نيجي بقى لشكلين من ال switching. إحنا شوفنا ال switching بيتم ازاي.
في شكلين ليه خلاص؟ شكلين لل switching ده. يا إما من process ل kernel وأرجع تاني لنفس ال process. يا إما process ل kernel يوديني على process تانية اللي هو بـ switch.
خلينا ناخد الأول ال scenario الأولاني، process ل kernel وأرجع تاني لنفس ال process، في إعادة للكلام برضه. أنا كنت شغال على ال processor، مين اللي شغال دلوقتي؟ user thread يعني user code و user stack.
حصل interrupt whatever سببه interrupt أو exception أو system call إيه اللي هيحصل؟ هطلع هنقل على kernel، أوتوماتيك هنقل على kernel. خلاص؟ فاتنقلت من user mode إلى kernel mode. فبقى ال stack pointer مشاور على stack ال kernel
وال IP مشاور على code ال kernel المناظر خلاص؟ اللي هو مين هنا؟ مين أول code هيشتغل مع أي interrupt؟ اللي جاي ممتاز من ال table، bonus برافو، اللي جاي جاي من ال table، من ال entry point بتاعة ال table.
هو ده اللي هروح عليه هنا. أوتوماتيكالي كده كده هيحصل pushing لتلات حاجات: ال stack وال IP وال flags. حصل لهم pushing فين؟ في ال stack. هل هم دول بس اللي المفروض يحصل لهم pushing؟
أنت دلوقتي اتنقلت من code ل code صح؟ أنت كنت شغال على code وكان في قيم على ال registers الباقية. كان في قيم على بقية ال registers. لو أنا نقلت على ال code بتاع ال kernel ما هو هيشتغل على ال registers دي.
هيـ overwrite القيم. فلازم لازم أحتفظ بإيه؟ ببقية ال registers. بس دي مش ال hardware بقى اللي بيعملها. ده ال flag بتاع ال OS هيروح مبوش بقية ال registers اللي هي باللون ده. دي بقية ال registers هيحصل لهم pushing
ده by ال handler، ال OS ال code بتاع ال OS اللي بيهندل هيبوش ال registers دي. بعد كده هيبتدي يهندل عادي ينادي بقى على code يخدم ال interrupt ده. وبعدين عايز يرجع، في ال scenario ده بيرجع على مين؟ على نفس ال process. يعني
يعني أه هو نفذ شوية حاجات وبعدين رجع فدلوقتي خلاص خلص عايز يرجع بقى لمين؟ لل بالظبط بتاع ال user. فيروح مرجع الأول ال registers اللي عمل لها push يرجعها.
وبعدين ينفذ I-Ret I-Ret Instruction Assembly اسمها Interrupt Retire عكس اللي حصل هنا اللي حصل هنا نقلني من User Mode إلى Kernel Mode Automatic
وعمل push لل registers دي أوتوماتيك بال hardware. ال iret العكس. تنقل من kernel إلى user و تبوب بقى مش تبوش. تبوب. تبوب ال registers اللي حصل لها pushing فيروح ناقلني من ال stack بتاع ال kernel
إلى stack ال user ومن code ال kernel إلى code ال user اللي أنا كنت جاي منه. مفهوم يا شباب؟ ال block بتاع ال registers ده اللي هو فيه ال stack وال IP وبقية ال registers كلها ده بنسميه
trap frame. افتكروا الاسم ده كويس هتلاقوه متكرر معاكم كتير في المعمل. trap frame هو مجموعة ال registers اللي حصل لها pushing في stack ال kernel أول ما اتنقلت من user ل kernel.
علشان هي دي اللي برجع عليها بعد كده. خلاص؟ طب تعالوا ناخد scenario animated لل system call. إيه اللي بيحصل في ال system call؟ وليكن مثلا printf. أنا دلوقتي user code برنامج عادي جه بينفذ printf عايز يطبع على إيه؟
مين يقدر يطبع على الشاشة؟ ال kernel. kernel. kernel. فأنا دلوقتي شغال على stack ال user, code user و flags user. ناديت C printf أو console.writeline أو whatever, C out أي function اللي هي بتطبع يعني. إيه اللي هيحصل؟ أول حاجة هـ switch من user
ل kernel ده automatic بال hardware. هنقل ال stack pointer بدل ما هو مشاور على stack user هيشاور على stack kernel. هبوش أوتوماتيكالي التلاتة registers ال stack وال flags وال IP.
بعدين أروح على الجدول. ما أنا عايز أعرف مين ال code اللي هيخدمني. هعرفه من الجدول. فبروح على ال interrupt descriptor table. كل ده hardware. كل ده بال hardware. ال interrupt descriptor table هيوصلني على مين؟
ال code اللي بيخدم مين بقى؟ system call. system call handler. ال code اللي بيخدم ال system calls. أنا طبعا عندي مجموعة system calls خلاص؟ بس قبل ما أشوف هي أنهي system call في حاجة لازم أعملها.
أكمل ال trap frame ممتاز bonus برافو. أكمل ال trap frame هبوش بقية ال registers. أما عملت push لبقية ال registers مين بقى دلوقتي القيم اللي هنا هتبقى بتاعة مين؟ ال kernel. ال code بتاع ال kernel بقى يشتغل.
يلعب في ال registers زي ما هو عايز، أنا معايا نسخة من من ال original registers بتاعة ال user أعرف أرجع له. خلاص؟ بعد كده هبتدي أ check بقى ما أنا عندي system calls كتير ممكن عايز أقرأ من ال keyboard، عايز أعرض على الشاشة، عايز أطبع على ال printer، في system calls كتير.
فكل system call ليها رقم. ه check الرقم أروح رايح على ال function اللي بتخدم ال system call دي. أنفذها وأخلص وأرجع. أما أجي أراجع أعمل إيه بقى؟ أه هرجع ه undo يعني ال registers اللي عملت لها push
هعمل لها pop. ده ال OS ال handler ده هيبوب ال registers. بعد كده ينفذ iret. iret هتعمل إيه؟ أهي هتبوب التلاتة دول وتـ switch من kernel إلى user.
فبقى التلاتة رجعوا تاني لمين؟ stack وأنهي سطر في ال code؟ لا اللي وراه اللي ورا ال print ما ال print خلصت لإن دي system call مش exception. لو كان exception كان هيرجع على مين؟ على نفس السطر.
طيب نيجي لسؤال بقى، أنت عشان تـ printf محتاج تباصي الحاجة اللي هتطبعها صح؟ parameters يعني. إزاي سؤال مهم هنا، إزاي أباصي parameters من user ل kernel؟ ممكن على ال stack. بس خلي بالكم ال stack ده tricky شوية.
لإن أنا وأنا user شغال على stack user. ما أقدرش أ access ال kernel. ولو رحت لل kernel فأنا ما ينفعش ال user ي access حاجة عند ال kernel بالظبط. فهنا ال stack tricky شوية.
الأسهل من ال stack إيه الحاجة المشتركة ما بينا؟ registers مين اللي قال؟ bonus برافو. هرمي على ال registers دي. هرمي parameters اللي عايز أباصيها على ال registers.
فيقوم هو أما اتنقلت على ال kernel يروح واخد ال parameters دي من عند ال registers. بس ما يكفيش كده. ال parameters دي جاية من عند ال user. أنت مفيش أي ثقة عند من ناحية ال user. ما ينفعش تثق في ال user نهائي. لإن ال user ده ممكن يبقى
virus, attack ممكن يبقى أي حاجة. لازم ال OS ي validate ال parameters اللي جاية دي. لازم لازم ي validate وإلا أنا ممكن أرمي له address عنده هو.
أنا مش كنتش أقدر أ accessه ساعتها. بس رحت رامي له address وأما اتنقل على kernel mode قدر هو ي accessه. يعملي بقى ينفذ لي مثلا code أكون أنا بيخدمني أو أعرف data ما كانش مسموح لي إن أنا أعرفها. كل دي ممكن أ overflow أبسط attack إن أنا أ overflow ال
ال buffer. ده بالنسبة لل system call. تعالوا نـ navigate كده سريعا اللي اتكلمنا عليه ده في ال code بتاعنا بتاع ال FOS ال operating system اللي إحنا شغالين عليه.
ده ال trap frame عبارة عن إيه؟ struct. متعرف في ال code أهو struct. لو بصيت عليه كده هتلاقي من تحت ده بتوع ال stack. بعد كده ال flags. بعد كده ال IP. دول اللي بيحصل لهم pushing automatic بمين؟
بال hardware. اطلع فوق شوية تلاقي ال error code اللي هو لو أنا في errors معينة ال exceptions ما أنا ممكن يبقى عندي exceptions في أكتر من نوع exception. فال exceptions ليها أكواد تفرق كل exception عن التاني. ال trap number اللي هو بعرف منه ال ID بتاعة اللي جايلي ده بتاع مين؟
اللي هو الجدول فاكرين 0 بتاع divide by على صفر، واحد مش عارف بتاع إيه، اتنين بتاع إيه وهكذا. بعد كده هتلاقوا فوق في struct تاني اسمه ال push registers اللي بقية ال registers اللي بيحصلها pushing بال OS.
كلها في struct اللي ممكن أباصي فيها ال parameters بالظبط اللي بباصي فيها بعضها ال parameters بسغلها كلها هنا. طيب ده بالنسبة لمين؟ ده بالنسبة لل trap frame. نيجي لل interrupt descriptor table. بص كده عبارة عن إيه في ال code؟ array.
فيها 256 entry من نوع struct. يعني مفيش إبداع في ال OS هو في الآخر code. اللي بتفهمه hardware أو theoretical بيتحول code بـ structs و pointers و integers و data types. خلاص؟ فهو array من 256 entry.
ببتدي أنا كـ OS أ initialize ال interrupt table ده إن أنا أ set بالظبط. مثلا ال interrupt بتاع ال clock، ال clock أنا بيبقى عندي timer بحيث أول ما يحصل time out يبعت لي interrupt وقتك خلص.
عشان أخرجه من running لـ ready فاكرين؟ فأهو بقول له اعمل لي setting في ال entry اللي عند الرقم بتاع ال clock، كل واحدة ليها رقم. set ده لو جالك ده روح على ال handler ده.
ده address على code. ولو جالك ده روح على ده، ولو جالك system call روح على ال handler بتاع ال system call. دي عبارة عن إيه لو تاخدوا بالكم قبلها إيه؟ address. address بتاع code. روح على address ده اللي هو ال entry point اللي سميناه entry point.
فين ال entry points دي بتت set فين؟ ما هو مين اللي هيـ set ال entry point؟ هو ال OS برضه. أهو بيـ setها في ملف اسمه trap entry.s مش مهم التفاصيل دي يعني المهم الفكرة العامة يعني. ده macro بستخدمه عشان أ set ال entry point بديها
اسم الtrap ورقمه. الاسم اللي هستخدمه هنا. والرقم اللي هو مربوط. يروح عامل هو إيه؟ سيبكوا من عامل global label. أنتوا ما خدتوش assembly مش مشكلة تفاصيل دي يعني، معرف label يعني، معرف address
اللي هو ده أو ده أو ده أو ده، بنادي ده أكتر من مرة يعني مثلا بناديها عشان ال double fault، بناديها عشان ال page fault. أول ما أناديها في حاجة تروح عاملة لي هي global variable اللي هو يمثل ال entry point اللي هحط ال address بتاعها هنا. وبيقول إن نوعها function.
وبعدين هيـ jump على all traps. هيـ jump على address. ال address ده هيعمل إيه؟ إيه أول حاجة بتتhandle بال OS بعد أما راح؟ push registers.
بيـ push ال DS وال ES و push all اللي هي بقية ال registers كلها. هيبوش بقية ال registers كلها يكمل ال trap frame. وبعدين يـ call function عند ال C اللي هي ال trap.
دي اللي هتcheck بقى مين اللي جايلي عشان أروح أخدمه. هروح أخدمه وأرجع. أما أرجع هرجع على مين؟ على code ال assembly اللي ناداني. بقية ال code ده في إيه بقى؟ عكس اللي فوق. هنا كنت بـ push
هنا بعمل إيه؟ pop بالعكس. بـ pop وبعدين بـ iret. iret اللي هي إيه؟ ترجعني تاني على ال stack اللي كنت جاي منه وال IP اللي كنت جاي منه. اللي هم بتوع مين؟
بتاع ال user. بتاع ال user. مفهومة الفكرة؟ دي task بقى ليكوا أنتوا ممكن navigate كده ال printf، ال C printf في ال FOS. افتح ال FOS روح على ال function C printf اللي هتستخدموها في المعمل الأسبوع ده. امشي وراها. شوفها بتنادي إيه بتنادي إيه بتنادي إيه شوف ال printf دي هتوصلك لفين في
لو عرفت ترسم ال cycle كاملة لحد أما ترجع أنت كده فهمت المحاضرة. أو فهمت الجزء ده من المحاضرة. طيب خلينا نـ break خمس دقايق. ناخد break خمس دقايق ونرجع تاني إن شاء الله. لو حد ليه أسئلة يتفضل هنا أهو، اللي كان ليه أسئلة يتفضل يعني.
ورجعت على نفس ال process. في بقى إن أنا أروح على process تانية. اللي بنسميه context switching. أنا كنت برنامج شغال وقتي خلص أو جه واحد أعلى priority أو أنا احتجت I/O.
whatever السبب فأنا رحت لل kernel برضه بس علشان يـ switch على برنامج تاني. فالجزئية اللي في الأول هي هي. اللي في الأول ده هو هو زي اللي فات. بس الفرق إيه بقى؟ إن أنا أما رحت هنا وأنا عند ال kernel
قد أكون اشتغلت شوية يعني ال kernel كان بيخدمني في حاجات. فالحاجات دي ممكن بـ بنادي functions أو حاجة فاتحطت على ال stack. في قيم في ال registers اتغيرت. نتيجة إن ده thread ال kernel الخاص بمين؟
بيا انا thread  ال kernel الخاصة بال thread ال user ده صح؟ دلوقتي عايز أ switch ال scheduler يعني عايز أ switch على برنامج تاني لازم أحتفظ بمين بقى؟ ال registers دي دلوقتي اتغيرت صح؟
عن اللي كنت محتفظ بيها. اللي كنت محتفظ بيها دي ده ساعة ما جيت من user ل kernel. اللي باللاحمر ده بتاعتى أنا أما كنت عند ال kernel بنسميها ال context بتاعي. فلازم أ push ال context ده في ال memory في ال stack.
اللي هو باللون الأحمر ده هـ push خلاص؟ بعدين هـ switch هروح على مين بقى؟ على process تانية. على وأنا خلي بالك أنا still عند ال kernel. still أنا عند ال kernel. فأنا هروح على
kernel thread بتاع process تانية. هـ switch ال kernel threads يعني إيه؟ يعني هروح على stack جديد مش بتاعي مش بتاع البرنامج ده على stack kernel بتاع مين؟ برنامج تاني خالص اللي هو باللون الأخضر اهو.
خلاص مفهومة ومش بس كده. لاحظوا هنا في حاجة مكتوبة بخط صغير اسمها address space. أنا هنا كل ده كان على ال memory بتاعة مين؟ البرنامج الأولاني، سواء user أو kernel كلها كانت على ال address space
بتاع البرنامج الأزرق الأولاني. أنا هنقل على برنامج تاني process تانية يعني address space تاني خلاص؟ و stack تاني و context تاني. يعني registers تانية بتاعة مين كل دول؟ بتاعة الأخضر.
بتاعة البرنامج الأخضر اللي هو بشرطة خلاص؟ عايز أرجع بقى أعمل إيه؟ خلاص؟ ما أنا معايا هنا مين؟ ده مين ده؟ ده ال trap frame بتاع البرنامج اللي أنا كنت رحت لل kernel stack بتاعه. هعمل العكس العملية العكسية. هـ pop
ال registers وأعمل iret فيرجعني على user. أنهي user بقى؟ الأخضر. أنهي stack؟ بتاع الأخضر. user stack بتاع الأخضر. أنهي code؟ ال code بتاع الأخضر. أنهي memory address space؟ بتاع الأخضر. مفهومة الفكرة؟
ده الاختلاف. يبقى زاد عليها إيه هنا؟ فكرة الإيه؟ غيرت ال address space ولازم كنت أحتفظ بال context. أنهي؟ موجود على stack الأحمر. زي ما هو. stack الأزرق آسف، ال stack ده
هو موجود ما أنا خلي بالك هنا أنا عملت إيه؟ أنا نقلت على stack تاني. خلاص؟ تعالوا نشوف ال function دي pseudo-code ليها كده. أنا عايز أ switch من current ل new من thread current إلى thread new أعمل إيه؟ أحتفظ بال context القديم
اللي هي حتى هنا مكتوبة بأسماء ال registers اللي خدتوها في ال architecture. 
R0 و R1 و R2 و R3 و SP فاكرين ال registers دي؟ بحتفظ بيها فين؟ في ال stack اللي هي اللي سميناها ال context.
هي محطوطة على ال stack ومعايا pointer عليها فين؟ اللي عارف هياخد bonus. 
pointer على ال context ده؟ لا أنا معايا أنا حطيت ال context على ال stack.
معايا pointer عليه فين؟ pointer ده بنحتفظ بيه فين؟ ما هو ده ليه وده ليه بس محطوط فين بتاع ده وده بتاع بتاع ده؟ في ال trap frame بتاع لا ال... اللي ابتدينا بيه المحاضرة.
مش قلنا ال process جوه process control block، جوه ال process control block في thread control block، ال thread control block هو ال registers الخاصة بال thread ده. هي هناك. طيب بعد كده هـ load هـ load
هـ load بتوع البرنامج الأحمر. ده كله ده على ال assembly. بعدين هـ return. أما أ return ال return دي أنتوا عارفين أما بكون في assembly code وأعمل return برجع على ال address اللي متخزن فين؟ في طبعا على ال stack وعلى حسب ال stack وعلى حسب
ال PC، ال program counter. أنا هنا غيرت ال program counter بتاع ال processor خليته بتاع البرنامج التاني مش الأولاني. فلما هـ return هنا هـ return على مين؟ على البرنامج التاني. ده ال context switch عشان كده سميناه context switch. يعني أنا رحت على code assembly
اهو بص تعالوا نشوفها code ده في ال FOS في ال OS بتاعنا. ده struct ال context. واخدين بالكم فيه registers كلها أسماء registers. وده code ال switch اللي هيـ switch من old ل new.
في الأول شوية push إنه بيرمي ال registers بتاعة مين؟ بتاعة القديم بتاعة القديم اللي أنا بـ switch منه. وبعدين هنيجي للسؤال ده. هيـ switch ال stacks. هيحتفظ بال stack pointer القديم
بعد أما عملت push أحتفظ بمكان ال stack pointer القديم في ال parameter اللي أنت مباصيهولي. وأ load في ال stack pointer الجديد ال context الجديد. كده أنا عملت switch لل stacks. يعني
فأي push أو pop جايين هيتعملوا على أنهي pointer؟ على أنهي stack؟ على stack البرنامج التاني. هعمل إيه في stack البرنامج التاني؟ هـ pop منه ال context. هـ pop منه registers. نفس مجموعة ال registers دي هعملها pop pop pop pop وفي الآخر بـ return.
هيـ return على مين ده؟ على ال IP أو ال program counter بتاع البرنامج التاني أو بلأخص بقى ال kernel thread بتاع البرنامج التاني. في سؤال مهم هنا، اللي يعرف ياخد اتنين bonus مش bonus واحد.
بصوا هنا دي ال registers أهي دي ISI, IDX مش عارف إيه لحد ال IP. ال push طبعا بيتعمل بالعكس. BB, AX, BX, CX, DX, SI, DI فين ال IP؟
لا ال context لازم فيه ال IP عشان أعرف أرجع عليه. فين ال IP هنا؟ ما عملتلوش push.
بس فين برضه ال IP فين؟ لا ما أنا أما أعوز أرجع لازم أرجع على لا مش على ال stack بس، هو أنت أما رحت للبرنامج الأخضر ده sorry البرنامج التاني يعني عملت pop pop pop pop pop وعملت return، ال return وديتك على
على ال IP بتاع البرنامج التاني اللي كان اللي أنت كنت محتفظ بيه ساعتها. تخيل بقى إن الدنيا مشيت ورجعت ورجعت تاني على مين؟ على البرنامج ده. عايز أرجع على ال IP بتاعه، فين ال IP بتاعه؟ فين ده؟
مش ال hardware أوي يعني. لا. متخزن في ال stack فين؟ هو هو ده ال return address.
متخزن في ال... هو متخزن في ال stack صح؟ إمتى تخزن في ال stack؟ لا لا ده القديم. طب خلاص عشان الوقت معلش. هو مش دي function؟
automatic أنت أما بتنادي أي function أول حاجة بتحصل أما بتنادي function إيه؟ بـ push ال return address على ال stack. يعني أنا أما ناديت context switch أوتوماتيك ال address اللي وراها على طول حصل له pushing على ال stack.
هو ده ال address اللي المفروض أرجعه لما أرجع هنا تاني. خلاص؟ طيب نيجي بقى لموضوع تاني أو ناتج من ده.
مشكلة ال interleaving. تعالوا كده نجمع اللي اتعلمناه حتى الآن في المحاضرة دي في رسمة كبيرة. أنا user code أهو. حصل trap أيا كان سببه.
حصل trap أيا كان سببه. في حاجات automatic هتحصل إن هتحول من user ل kernel، ال interrupt هتتقفل أوتوماتيك، هيحصل pushing للتلات حاجات: stack و return address و flags.
وهيحصل setting ليهم بالحاجات اللي عند ال kernel وهوديني على ال handler بتاع المناظر لل trap اللي جاي. ال handler ده هيعمل إيه؟ هيpush بقية ال registers، إحنا بنـ summarize اللي فات يعني تاني بنعيده أهو.
هيpush ال registers بقية ال registers وينادي على function trap. trap دي اللي هتـ check وتhandle وترجع. أما تيجي تتcheck بتوقف ال clock علشان وأنا شغال محدش يوقفني. ال clock لو عدت عليا وأنا شغال هنا
هتعطلني وأنا مش عايز أعطل وأنا هنا. مش عايز حد يعطلني وأنا هنا. فبوقف ال clock. بروح على واحدة من أربع حاجات أساسية، تلاتة اللي هم ال exception أو interrupt أو system call أو special case اللي هي ال timer. لو أنا رحت على exception، exception حاجة من اتنين
يا unhandled فبقتل البرنامج. خلاص ما برجعلوش تاني. يا إما handled فبهندله وأرجع لل trap تاني يعني أروح أ handle وأرجع تاني لل function دي.
لو هو interrupt hardware بروح أ handle ال hardware ده.
جاي من ال keyboard أروح أ handle ال keyboard، جاي من ال mouse أ handle ال mouse، whatever يعني ال hardware اللي جايلي منه ال interrupt بروح أ handle ه وأرجع تاني لل trap. لو أنا timer، لو اللي جايلي ده time out يعني أنا وقتي خلص هـ switch اللي لسة قايلينها من شوية.
هـ switch على برنامج تاني وممكن التاني ده يـ switch على تالت ورابع وخامس يروحوا صح؟ وبعدين في الآخر هيرجعوا لي تاني بس وقت أما يجي عليا الدور. فبعد أما يروحوا whatever راحوا قد إيه
وفي الآخر رجعوا لي تاني هرجع تاني على إيه؟ على ال trap. finally لو أنا system call فبروح أهندل ال system call دي. خلي بالكم في التلاتة دول ال interrupt ماله؟ disabled. ممنوع يحصلي interrupt وأنا هنا.
دول لازم يتعملوا على بعض كتلة على بعض. الحاجة أما تخش هنا لازم أعملها كاملة. الوحيد اللي بفتح فيه ال interrupt ال system call. لإن ال system call دي حاجة ليا أنا حاجة للبرنامج طالبها والحاجة دي ممكن تاخد وقت.
وهي محسوبة عليا فبسمح إن يحصل interrupts. مفهومة؟ بسمح إن يحصل interrupt. يعني بـ enable ال flag بتاع ال interrupt و resume ال clock بعد لإن ده محسوب على وقتي. وبالتالي كده ممكن وأنا شغال هنا يحصل إيه؟
interrupt. فال interrupt لما يحصل هنا هيوديني على مين؟ لفة بقى تانية، يوديني على واحد والتاني ممكن يدخلني اللفة دي يوديني يوديني يوديني بس في الآخر هعمل إيه؟ ليه؟ لإن كل واحد ليه ال stack بتاعه فأنا لما بروح مهما رحت في الآخر برجع تاني.
بعد أما رجعت برجع على ال trap. فكله بيرجعني على ال trap مرة تانية. ال trap تعمل إيه؟ تـ resume ال clock وترجعني لل handler. ال handler زي ما عمل push يـ pop وبعدين ينفذ
interrupt return تروح هي عاكسة ال mode مرجعاني user فاتحة ال interrupts وعاملة pop لل registers اللي كانت pushed automatically هنا اللي هو بقية ال trap frame.
ده بقى إيه مشكلته دلوقتي؟ مشكلته في حتتين. في المنطقتين دول. المنطقتين دول أنا فين هنا؟ في ال kernel صح؟ أنا في ال kernel. وأنا في ال kernel وبخدم برنامج
رحت على برنامج تاني قبل ما أكمل شغلي. صح؟ أهو سواء هنا أو هنا رحت على تاني والتاني راح على تالت whatever صح؟ اللي بنسميها interleave، بـ interleave البرامج. ويعني وأنا في النص ممكن ما أكملش بقية حاجتي وأقف في النص عشان أروح
لبرنامج تاني والتاني يروح ل... آه في الآخر هرجع تاني هترجع لي تاني. بس إيه مشكلة ده؟ مشكلته بنسميها issues بتاعة ال concurrency إن أنت سواء بتبدل ما بين برامج أو برامج شغالة parallel في الحالتين في نوع من ال non-determinism.
اللي ممكن يحصل بسبب إيه؟ ال threads دي بتـ run بأي ترتيب وال switching ممكن يحصل في أي وقت. فتخيل معايا لو أنت عندك تلاتة threads إيه ال possible scenarios اللي ممكن يشتغلوها.
لا لا لا نهائي. هم تلاتة code و code و code خلاص؟ وأنت ممكن تـ switch في أي وقت وتشغلهم بأي ترتيب وتبدل ما بينهم بأي بأي لحظة. اديني كده إيه ال possible execution scenarios اللي ممكن تحصل.
لا نهائي. ممكن ده يشتغل وبعدين ده وبعدين ده. ممكن يشتغلوا parallel لو أنا عندي تلاتة processors. ممكن يقعدوا حتت، ده حتة وده حتة وده حتة سيناريوهات لا نهائية. ده بنسميه non-deterministic behavior.
ينتج عنه إيه بقى؟ ينتج عنه مشكلة أساسية لازم تتحل بال design. عشان كده بنشرح الفكرة دي. ما ينفعش تستنى أما ال bug تظهر في ال scenario ده وتروح تعالجها. أنت أصلا ممكن ما تعرفش إن ال bug
بسبب حاجة زي كده إيه سببها؟ فلازم ال correctness بايظة. إيه بقى إيه المشكلة الأساسية؟ أي shared resource، يعني إيه shared resource؟ يعني حاجة واحدة وأكتر من حد ممكن يستخدمها.
أي shared resource وأنت عندك concurrency يعني بتبدل بـ non-deterministic behavior أو بتشتغل parallel ال shared resource ده هتحصل عليه مشكلة. تأكد إنه هتحصل عليه مشكلة.
من غير ما تفكر إيه هي المشكلة. خدوها حلقة في ودنكم، هناخد أمثلة دلوقتي، بس خدها قاعدة عامة. بتبدل ما بين برامج أو بتشغلهم parallel وفي حاجة shared ما بينهم هتحصل مشكلة على ال shared resource ده.
تأكد بنسبة 99.9% إن هتحصل مشكلة على ال shared resource ده. تعالوا ناخد مثال، أمثلة بسيطة كده. تخيل عندك thread بيعمل X = Y + 1 وthread تاني بيعمل Y ب 2 وبعدين Y بيضرب Y في 2 ويحطها في
والاثنين initial بصفر. ده thread وده thread. اديني كده إيه ال possible values بتاعة X؟ واحد، تلاتة، خمسة. واحد تحصل إزاي؟
لو أنا اشتغلت thread 1 فبقت ال X بصفر بلس واحد. وبعدين اشتغلت thread 2 ما غيرش حاجة في ال X فضلت واحد. تبقى بتلاتة إمتى؟
thread 2 نفذ أول سطر بعدين thread 1 نفذ X = Y + 1 فبقت 2 و 1، 3 وبعدين thread 2 كمل هيغير ال Y مش مشكلة ال X بقت بكام؟ 3. ال scenario ده
thread 2 اشتغل لحد الآخر خلاها ال Y بأربعة، بعدين thread 1 اشتغل. أنت متخيل إن برنامج فيه تلات سطور code مجرد ما شغلته concurrently يعني سمحت إن يحصل تبديل ما بينهم
ادت ممكن 3 possible values في تلات سطور code. تخيل الفكرة. ده بنسميه non-deterministic behavior. فاهمين الفكرة؟
أنت ATM teller مكنة بتاعة البنك خلاص؟ وأنت وأخوك بتعملوا إيداع في نفس الحساب في نفس الوقت. أنت مدخل وهتحط 1000 جنيه أو 1000 دولار والتاني هيروح حاطط 2000 دولار خلاص؟ function ال deposit بتعمل إيه؟ تاخد ال ID والكمية.
بـ retrieve ال account بتاعك عشان تتأكد من ال ID ومن ال password ومن الحاجات دي. وبعدين تزود على ال balance بتاعك الكمية اللي أنت ضفتها وبعدين ترجع تخزنها تاني على ال disk. أنت هتعمل ده وأخوك هيعمل ده. إيه ال possible values بتاعة ال account؟ هيزيد بكام بعد في نهاية العملية؟
ممكن 1000 ممكن 2000 ممكن 3000. يا ويلك لو زادت ب 1000. أنت بتحط 3000 دولار وفي الآخر الحساب سمع ب 1000 بس. صح؟ كل ده وارد يحصل. ليه؟ لإن بيحصلوا parallel في نفس الوقت أو ببدل يعني أنا جبت الحساب
والتاني جاب الحساب نفس الحساب. ده جه يزود على القيمة القديمة وده زود على القيمة القديمة. فده زود 1000 على القديم وده زود على 2000 على القديم. ده رجع خزن 1000 زيادة 1000 وده رجع خزن زيادة 2000 في الآخر واحدة منهم اللي اتخزنت.
كارثة صح؟ كارثة. إيه حل المشاكل دي؟ ممتاز، أشتغل في الحتت ال critical دي sequential. طب هي كان إيه سببها أصلا؟ shared, shared ال account shared، ال balance shared.
ال X وال Y variables اللي كانوا في المثال اللي فات shared. فالحل هنا مين اللي قال تشتغل sequential؟ bonus برافو. إن الحتت دي تشتغل sequential. يعني واحد بس اللي يخش وما يسيبش إلا لما يخلص.
بنسميها critical section. critical section. مثال كمان عشان نعرف الكوارث اللي ممكن تحصل يعني. in-queue أدي queue مشاور على ال head بتاعه، عشان أ in-queue بحتفظ بال head القديم.
دخل ال head يشاور على الحاجة الجديدة والجديد يشاور على ال head القديم. يعني عشان أ in-queue حاجة هنا لازم أعمل التلات سطور دول. تخيل عندك two kernel threads بـ in-queue process في نفس الوقت. جت الأولانية احتفظت بال head في temp عندها.
جت التانية احتفظت بال head في temp بتاعتها عندها. الاتنين مشاورين على ال head. جت الأولانية اشتغلت خلت ال head يشاور على ال parameter بتاعها هي. جت التانية خلت ال head هو نفس ال head، ما هو في الآخر هو head واحد.
خليته يشاور عليها هي. ده راح فين؟ طار خلاص. طار. يجي في بعد كده ده يخلي ده يشاور على ال head القديم والأولاني يخليه يشاور على ال head القديم. فين ال queue في الآخر؟ ال queue بقى
بيشاور على B2 B2 بيشاور على باقى ال queue فين B1؟ بيف راحت. إيه سبب ده؟ ال non-deterministic. إيه الحل؟ sequential. critical section. بيتعمل بإيه بقى ال critical section ده؟ بـ if. هسميه if
lock. if لا if lock. بس software يعني lock معمول بال software.
 if. قبل ما تخش لو القفل مفتوح لا لو مفتوح خش واقفله.
خش واقفله ولو القفل مقفول ما تخشش واستنى لحد مين؟ أما اللي جوه يخرج فيفتح القفل بنسميها release. دي بنسميها acquire و release.
acquire ال lock يعني إيه؟ اقفله لو مفتوح، اقفله وراك وخش. ولو مقفول استنى. و release افتحه للي وراك لو في حد وراك، طب لو مفيش؟ افتحه وسيبه مفتوح عشان اللي يجي. فاهمين الفكرة ببساطة
يبقى القاعدة العامة هنا المشكلة الأساسية إيه؟ منين ما تلاقي shared resource تأكد إن في مشكلة. أحلها إزاي by design؟ sequential code. ال shared resource sequential code لازم يتحمي بـ critical section.
how to? إزاي أ implement ال lock دي؟ قلنا ال lock ليها حاجتين acquire و release. بستخدمها إن قبل ما أخش أ acquire وبعد أما أخرج أ release. فبالتالي بيخلي ال code ده sequential فعلا يعني لو عندي
المنطقة ال critical دي وفي تلاتة بيحاولوا يدخلوا عليها حتى لو parallel هيضطر يحصل لهم serialization يعني يخشوا واحد ورا التاني. مين اللي يخش تختلف مش يعني تختلف على حسب ال implementation بس في الآخر هيخشوا إيه؟
واحد يعني لو A هو اللي دخل التانيين بره. لحد أما ال A يخلص يدخل اللي وراه. ده يخلص يدخل اللي وراه. ده يخلص يفتح ال lock مفتوح. يتعمل إزاي بقى ال lock ده؟
أبسط وأسهل فكرة ليه إن أنا أقفل ال interrupt. فاكرين هو إيه اللي بيخليني أ... فاكرين أما عملت highlight الحتتين اللي فيهم مشكلة؟ كان واحدة بسبب ال timer
والتانية بسبب ال clock إن أنا أصلا فتحت ال interrupt قبلها. عشان أسمح إن يحصل switching. طيب ok مفيش مشكلة إنه يحصل switch وأروح أنفذ برنامج تاني. القصة دي كلها مفيهاش مشكلة. بس أول ما أجي على حتة فيها shared وعايز أ force إن ال code ده يشتغل
sequential أعمل إيه؟ أقفل ال interrupt. يعني أما أجي أ acquire ال lock، acquire يعني ببساطة أعمل إيه؟ أقفل ال interrupt. و release؟ أفتح ال interrupt. فأنت كده لو أنت قفلت ال interrupt حد هيعرف... ماحدش هيعرف يوقفك.
طول ما أنت بتنفذ ال code ده محدش هيعرف يخرجك. لإن ال interrupts مالها؟ ال interrupts مقفولة. مش هتقدر تـ switch على برنامج تاني لإن ال interrupts مالها؟ مقفولة. بس إيه مشكلة الحل ده؟
هو خلي بالك أنت لو قفلت ال interrupt محدش مفيش حد بيشتغل. يعني hardware تجهز وتبعث لك وأنت ولا معبرها.
برامج عايزة تشتغل مش هتعبرها. وقتك خلص مش هتعبر ده. لإن ال interrupts مالها؟ مقفولة. فمبدئيا ما ينفعش الحل ده أديه ل user program.
لإنه تخيل ال scenario ده. قفل ال interrupt ودخل في while true. خلاص. ببساطة جدا إنسى إن ال system ده هيشتغل تاني.
خلاص كده؟ فما ينفعش أسمح إن ده يحصل عند مين؟ عند ال user. يبقى مبدئيا الحل ده ينفع بس عند مين؟ في حتت ال kernel، ال shared اللي عند ال kernel. ok وده اللي يهمنا دلوقتي إحنا بنتكلم على مشاكل عند ال kernel يعني. طيب بس في مشكلة تانية إن ده ما بيشتغلش غير على إيه؟
على أما بتقفل أنت interrupt ده بتقفله على مين؟ على processor واحد. ده ما بيقفلش الباقيين. ما بيقفلش فممكن أنت ok قفلت على ده في التاني اللي بيتخانق معاك على ال shared resource شغال على processor تاني أصلا. أنت ما قفلتش عليه.
فإذا الحالة ده ما بينفعش غير على إيه؟ على ال uniprocessor. المشكلة التالتة هي اللي أنت قلتيه- قلتيها إن مفيش guarantee على ال timing. يعني حتى لو أنا بقفل ورايا مين قال إن الوقت اللي هاخده قد إيه؟ ممكن آخد وقت كبير فأنا كده معطل ال system كله. خلاص؟
فبنقل على حل تاني أحسن منه شوية. تستخدم ال interrupt علشان تعمل ال if. مش تخليها هي ال if. خلي بالكم الفكرة كلها إن أنا بعمل إيه؟ if ومفتاح. خلاص؟ ال scenario الأولاني خلى ال if والمفتاح هو مين؟
ال interrupt. لا ال scenario التاني لا. أنا معايا if، ملوش علاقة بال interrupt. أهو اسمه if if my lock. في الآخر ده code على خلي بالكم هو integer في الآخر. initially ب free.
يعني ب 0 مثلا.خلاص initially ال lock مفتوح. عايز تـ acquire تعمل إيه؟ تcheck ال if. لو ال if busy مقفول تعمل إيه؟ آه go to sleep
go to sleep يعني إيه؟ اركن. يعني تبقى ال status بتاعتك إيه؟ blocked. لا مش اركن أوي كده يعني. suspended ده يعني
اركن على ال disk، لا لا مش أوي كده. اركن ما تخشش على ال processor دلوقتي. blocked، حالتي blocked. خلاص؟ ده لو القفل إيه؟ مقفول. فأنا مش هعرف أكمل. طب لو القفل مفتوح؟ كان free؟ اقفله يعني خليه busy
وكمل أنت. فمين اللي كمل؟ اللي منادي ال acquire. بس قفل وراه القفل. بس كده أنا قفلت القفل صح؟ أي حد هيجي ورايا يلاقي القفل ماله؟ مقفول. طيب العكس، أما أجي أ release أعمل إيه؟
أنا خلصت. آه أما أجي أ release الأول أشوف في حد مستني؟ آه في حد جه القفل مقفول فاستنى عليا. فما ينفعش أنا أروح أفتح القفل. آخد من الناس اللي مستنيه لإن هو جه الأول ومستني.
فلو في حد في ال waiting queue بـ releaseـه، يعني أخلي حالته إيه؟ ready، ready ممتاز، ready، ready. دخل لي حالته ready. طب ولو مفيش حد في ال queue؟ افتح القفل.
خليه تاني free. طب خلاص كده ال lock خلص. فين ال interrupt؟ مفيش interrupt. ال lock ده بالنسبة للكودين دول إيه؟ shared.
ال lock variable ده بالنسبة لل acquire وال release shared resource مش ده shared variable؟ واحدة واحدة عليا.
بص بالراحة بالراحة. أنت عامل القفل ده عشان تحمي منطقة shared. القفل نفسه shared.
الـ القفل هو integer. integer variable. ال acquire بتبص عليه وال release بتبص عليه. تخيل معايا ال scenario ده أنا وحضرتك داخلين نعمل acquire في نفس الوقت. يحصل ولا ما يحصلش؟
وارد يحصل. أنا هcheck على ال lock هلاقيه إيه؟ free. وأنت هcheck على ال lock؟ free. إحنا الاتنين بقينا فين؟ اتنين داخلين على ده. ده هيـ acquire وده هيـ acquire.
ده ه check هنا وده ه check هنا. B1 ه check و B2 ه check .
 B1 initially ال lock free. B1 لقيته free عملت إيه؟ المفروض تعمل إيه؟ تخليه busy وتدخل. أه بس إحنا قلنا مفيش guarantee على ال timing.
فممكن أنا وأنت وأنتِ نتcheck على ال lock في نفس الوقت. كلنا هنلاقيه free. كلنا هنخليه busy. كلنا هنخش. ما عملناش حاجة. إيه سبب المشكلة دي؟ إن ال lock shared. إن ال lock shared.
فالحل إن ال lock يتحمي. ال lock نفسه يتحمي. أحمي ال lock بإيه بقى؟ أ disable ال interrupt قبل ما أ check و أ enable ال interrupt
بعد أما خلص تعامل مع ال lock. وهنا نفس الفكرة، بـ check على ال lock أ disable قبل و أ enable بعد. كده ضمنت إن الحتة دي على بعض هتشتغل إيه؟ على بعضها. مفيش إن أنا أجي أ check ال lock وقبل ما أكمل تخرجني
وتخش أنت فتلاقي ال lock فاضي، يخرجك تخش أنت تلاقي ال lock فاضي، مفيش الكلام ده. لإن أنا أما دخلت أنا قفلت ورايا إيه؟ ال interrupts أصلا. فخلاص أكون أنا عملت ال lock خليته busy. خلاص؟
آخر نقطة في الجزئية دي وهختم المحاضرة إن شاء الله. ميزة ده ميزة ده إيه أولا؟ إن ال code اللي أنت هتعمل عليه interrupt disable و enable code صغير في الآخر. المساحة دي إيه؟
وقتها صغير. ده مش code أنت ضامن إن هي limited time. أ check وأ sleep وخلاص. بس في نقطة تانية بقى مهمة. وأنت رايح تنام أنت قفلت
ال interrupt عشان تتشيك ال lock. لقيت القفل مقفول. هتروح تـ block نفسك. تـ block نفسك وال interrupts مالها؟ مقفولة. ما عملناش حاجة. محدش هيشتغل.
فلازم وأنت رايح تـ block نفسك تفتح ال interrupts. بس still ده ما ينفعش يشتغل غير فين برضه؟ عند ال kernel لإن فيها disable لل interrupts. disable interrupts ما ينفعش أسمح ده لل user.
خلاص؟ طيب negatives ما ينفعش أدي لل user ما ينفعش يشتغل على multiprocessor دول المشكلتين الرئيسيين. شوف حلول لده يمكن المرة الجاية أو يمكن نرجع لها later on في محاضرات متقدمة بعد كده يعني. شكرا جزيلا بعتذر عن الإطالة المحاضرة دي دسمة فيها معلومات كتير هتلاقوا الدنيا داخلة في بعض بس تأكد
لو أنت روحت إن شاء الله قريت الحاجات دي أو سمعت video هتلاقي الدنيا سلسة إن شاء الله وهتجمعها مع بعض. شكرا وبتوفيق إن شاء الله.