ΕΘΝΙΚΟ ΜΕΤΣΟΒΙΟ ΠΟΛΥΤΕΧΝΕΙΟ ΣΧΟΛΗ ΗΛΕΚΤΡΟΛΟΓΩΝ ΜΗΧΑΝΙΚΩΝ KΑΙ ΜΗΧΑΝΙΚΩΝ ΥΠΟΛΟΓΙΣΤΩΝ ΤΟΜΕΑΣ ΤΕΧΝΟΛΟΓΙΑΣ ΠΛΗΡΟΦΟΡΙΚΗΣ ΚΑΙ ΥΠΟΛΟΓΙΣΤΩΝ ΕΡΓΑΣΤΗΡΙΟ ΥΠΟΛΟΓΙΣΤΙΚΩΝ ΣΥΣΤΗΜΑΤΩΝ http://www.cslab.ece.ntua.gr Λειτουργικά Συστήματα 7ο εξάμηνο, Ακαδημαϊκή περίοδος 2009-2010 Άσκηση 4: Χρονοδρομολογητής Κυκλικής Επαναφοράς 1 Ζητούμενα 1.1 Υλοποίηση χρονοδρομολογητή στο χώρο χρήστη Ζητείται η υλοποίηση ενός χρονοδρομολογητή κυκλικής επαναφοράς (round-robin scheduler). Ο χρονοδρομολογητής εκτελείται ως γονική διεργασία, στο χώρο χρήστη, κατανέμοντας τον υπολογιστικό χρόνο σε διεργασίες-παιδιά. Για τον έλεγχο των διεργασιών, ο χρονοδρομολογητής θα χρησιμοποιεί τα σήματα SIGSTOP και SIGCONT για την διακοπή και την ενεργοποίησή κάθε διεργασίας, αντίστοιχα. Κάθε διεργασία εκτελείται για χρονικό διάστημα το πολύ ίσο με το κβάντο χρόνου tq. Αν η διεργασία τερματιστεί πριν από το τέλος του κβάντου χρόνου, ο χρονοδρομολογητής την αφαιρεί από την ουρά των έτοιμων διεργασίών και ενεργοποιεί την επόμενη. Αν το κβάντο χρόνου εκπνεύσει χωρίς η διεργασία να έχει ολοκληρώσει την εκτέλεσή της, διακόπτεται, τοποθετείται στο τέλος της ουράς έτοιμων διεργασιών και ενεργοποιείται η επόμενη. Η λετουργία του χρονοδρομολογητή ζητείται να είναι ασύγχρονη, βασισμένη σε σήματα. Ένας χρονοδρομολογητής χώρου πυρήνα ενεργοποιείται από διακοπές χρονιστή. Αντίστοιχα, ο υπό εξέταση χρονοδρομολογητής θα χρησιμοποιεί τα σήματα SIGALRM και SIGCHLD για να ενεργοποιείται στις εξής δύο περιπτώσεις: Εκπνοή κβάντου χρόνου: Όταν το κβάντο χρόνου εκπνεύσει, σταματά την τρέχουσα διεργασία. Η περίπτωση αυτή αντιστοιχεί σε χειρισμό του σήματος SIGALRM. Παύση/τερματισμός διεργασίας: Όταν η τρέχουσα διεργασία πεθάνει ή σταματήσει, επειδή εξέπνευσε το κβάντο χρόνου της, ο χρονοδρομολογητής διαλέγει την επόμενη από την ουρά, θέτει τον χρονιστή ώστε να παραδοθεί σήμα SIGALRM μετά από tq δευτερόλεπτα, και την ενεργοποιεί. Η περίπτωση αυτή αντιστοιχεί σε χειρισμό του σήματος SIGCHLD.
ια γονική διεργασία (scheduler) κατανέμει τον πολογιστικό χρόνο ανάμεσα σε διεργασίες-παιδιά κκίνηση παύση διεργασιών με σήματα IGCONT καιsigstop " at 10.95pt έχουσα διεργασία όπτεται μετά απόtq sec Scheduler SIGSTOP SIGCONT P 0 P 1 P 3 P 2 Σχήμα 1: Ο χρονοδρομολογητής σταματά την P 0 και ξεκινά την P 1. Το τελικό παραδοτέο είναι το πρόγραμμα του χρονοδρομολογητή, το οποίο θα εκτελείται με ορίσματα τα εκτελέσιμα προς χρονοδρομολόγηση: $./scheduler prog1 prog2 prog3 prog4 Για κάθε όρισμα κατασκευάζεται μία διεργασία, η οποία εκτελεί το αντίστοιχο πρόγραμμα. Μετά τη δημιουργία των διεργασιών ξεκινά η διαδικασία χρονοδρομολόγησης. Ο χρονοδρομολογητής εμφανίζει κατάλληλα μηνύματα κατά την ενεργοποίηση, διακοπή και τερματισμό των διεργασιών. Όταν όλες οι διεργασίες έχουν ολοκληρώσει την εκτέλεσή τους, τερματίζεται. Ζητήματα Υλοποίησης: Στη σχεδίαση αυτή, το σύνολο της διαδικασίας χρονοδρομολόγησης αναλαμβάνεται από δύο συναρτήσεις χειρισμού σημάτων, οι οποίες ενεργοποιούνται ασύγχρονα, ενώ το κύριο πρόγραμμα της διεργασίας-χρονοδρομολογητή μπορεί να εκτελείται ανεξάρτητα. Ο χρονοδρομολογητής χρειάζεται να διαθέτει κατάλληλες δομές δεδομένων για την τήρηση της ουράς εκτέλεσης και της κατάστασης των διεργασιών. Απαιτείται δομή ανάλογη του Process Control Block, μία για κάθε διεργασία. Το PCB θα περιέχει τουλάχιστον τα εξής πεδία: id: Ο σειριακός αριθμός της διεργασίας. N διεργασίες αριθμούνται από 0 έως N 1. pid: Το PID της διεργασίας στο Linux, χρησιμοποιείται κατά την αποστολή σημάτων έλεγχου. name[]: Πίνακας χαρακτήρων στον οποίο αποθηκεύεται το όνομα της διεργασίας (το όνομα του εκτελέσιμού της). Επιπλεόν, χρειάζεται δομή για την τήρηση της ουράς εκτέλεσης. Μπορείτε να χρησιμοποιήσετε συνδεδεμένες λίστες, ή πίνακα σταθερού μεγέθους, υποθέτοντας ένα μέγιστο αριθμό διεργασιών, ή όποια άλλη δομή θεωρείτε κατάλληλη, μετά από συνεννόηση με τους βοηθούς του εργαστηρίου. Για το κβάντο χρόνου προτείνεται τιμή tq = 5s, έτσι ώστε να είναι εύκολα αντιληπτή η διαδικασία χρονοδρομολόγησης. Στον κατάλογο /home/oslab/code/sched σας δίνονται: το πρόγραμμα prog.c, το οποίο θα εκτελείται στις υπό χρονοδρομολόγηση διεργασίες, το execve-example.c για τη χρήση της κλήσης συστήματος execve() και ένας σκελετός του χρονοδρομολογητή, scheduler.c. Τα εκτελέσιμα prog1, prog2,... μπορούν να προκύπτουν είτε με αντιγραφή του prog είτε με σύνδεση προς αυτό, ώστε να διευκολύνεται η διαδικασία αλλαγής του κώδικά του. Για να δημιουργήσετε έναν σύνδεσμο από το prog1 προς το prog μπορείτε να χρησιμοποιήσετε την εντολή:
ln -s prog prog1 και να επιβεβαιώσετε με την εντολή ls -l prog1 ότι πράγματι το prog1 είναι σύνδεσμος προς το prog. Προτείνεται να επεκτείνεται το Makefile που σας δίνεται ώστε να το υποστηρίζει αυτό. Για περισσότερες πληροφορίες σχετικά με θέματα υλοποίησης της άσκησης, προτείνεται να συμβουλευτείτε την παρουσίασή της, που είναι διαθέσιμη εδώ: http://www.cslab.ece.ntua.gr/courses/os/files/2009-10/os-lab-04-scheduler. pdf. Βήματα: 1. Ξεκινώντας από το scheduler.c, επεκτείνετέ το ώστε να δημιουργεί τις απαραίτητες διεργασίες και να τις αφήνει να εκτελούνται παράλληλα, έως ότου όλες τερματιστούν. Χρησιμοποιήστε συνάρτηση χειρισμού του σήματος SIGCHLD για να καταγράφετε το θάνατο διεργασιών-παιδιών, έως ότου δεν έχουν απομείνει άλλα προς εκτέλεση. Το κύριο πρόγραμμα του χρονοδρομολογητή πρέπει να είναι ένας άεργος βρόχος: while (pause()) ; 2. Δημιουργήστε κατάλληλες συναρτήσεις χειρισμού των σημάτων SIGALRM και SIGCHLD, οι οποίες θα αναλαμβάνουν τη διαδικασία χρονοδρομολόγησης. Ο χρονοδρομολογητής πρέπει να εκτυπώνει ενημερωτικά μηνύματα κατά την ενεργοποίηση, διακοπή και θάνατο διεργασιών. Δεν επιτρέπονται αλλαγές στον κώδικα του prog.c και η χρήση της κλήσης συστήματος sleep() στον κώδικα του χρονοδρομολογητή. Σημείωση: Βεβαιωθείτε ότι το πρόγραμμα λειτουργεί σωστά σε κάθε βήμα πριν προχωρήσετε στο επόμενο. Αν όχι, βρείτε τι δεν πηγαίνει καλά και διορθώστε το, μέχρι να λειτουργήσει. Ερωτήσεις: 1. Τι συμβαίνει αν το σήμα SIGALRM έρθει ενώ εκτελείται η συνάρτηση χειρισμού του σήματος SIGCHLD ή το αντίστροφο; Πώς αντιμετωπίζει ένας πραγματικός χρονοδρομολογητής χώρου πυρήνα ανάλογα ενδεχόμενα και πώς η δική σας υλοποίηση; Υπόδειξη: μελετήστε τη συνάρτηση install_signal_handlers() που δίνεται. 2. Κάθε φορά που ο χρονοδρομολογητής λαμβάνει σήμα SIGCHLD, σε ποια διεργασίαπαιδί περιμένεται να αναφέρεται αυτό; Τι συμβαίνει αν λόγω εξωτερικού παράγοντα (π.χ. αποστολή SIGKILL) τερματιστεί αναπάντεχα μια οποιαδήποτε διεργασίαπαιδί; 3. Γιατί χρειάζεται ο χειρισμός δύο σημάτων για την υλοποίηση του χρονοδρομολογητή; θα μπορούσε ο χρονοδρομολογητής να χρησιμοποιεί μόνο το σήμα SIGALRM για να σταματά την τρέχουσα διεργασία και να ξεκινά την επόμενη; Τι ανεπιθύμητη συμπεριφορά θα μπορούσε να εμφανίζει μια τέτοια υλοποίηση; Υπόδειξη: Η παραλαβή του σήματος SIGCHLD εγγυάται ότι η τρέχουσα διεργασία έλαβε το σήμα SIGSTOP και έχει σταματήσει.
Scheduler P 0 Shell P 3 P 2 P 1 Σχήμα 2: Το πρόγραμμα-φλοιός ελέγχει τη λειτουργία του χρονοδρομολογητή Ο φλοιός αλληλεπιδρά με τοχρήστη Εντολές γιαδυναμική δημιουργία και καταστροφή εργασιών Πώς επικοινωνεί ο φλοιός με το χρονοδρομολογητή; 1.2 Έλεγχος λειτουργίας χρονοδρομολογητή μέσω φλοιού Ζητείται η επέκταση του χρονοδρομολογητή RR του προηγούμενου ερωτήματος, ώστε να υποστηρίζεται Δίνονταιrequest.h,shell.c. ο έλεγχος της λειτουργίας του μέσω προγράμματος-φλοιού. Ο χρήστης του συστήματος έχει τη δυνατότητα να ζητά δυναμική δημιουργία και τερματισμό διεργασιών, αλληλεπιδρώντας με το πρόγραμμα του φλοιού. Ο φλοιός δέχεται εντολές από το χρήστη, κατασκευάζει αιτήσεις κατάλληλης μορφής τις οποίες αποστέλλει προς τον χρονοδρομολογητή, λαμβάνει απαντήσεις που ενημερώνουν για την έκβαση της εκτέλεσής τους (επιτυχία / αποτυχία) και ενημερώνει για το αποτέλεσμά τους το χρήστη. Ο φλοιός διαθέτει τέσσερις εντολές: Εντολή p : Ο χρονοδρομολογητής εκτυπώνει στην έξοδο κατάλογο με τις υπό εκτέλεση διεργασίες, στον οποίο φαίνεται το id, το PID και το όνομα (name[]) της κάθε μίας. Επιπλέον, επισημαίνεται η τρέχουσα διεργασία. Εντολή k : Δέχεται όρισμα το id μιας διεργασίας (προσοχή: όχι το PID) και ζητά από το χρονοδρομολογητή τον τερματισμό της. Εντολή e : Δέχεται όρισμα το όνομα ενός εκτελέσιμου στον τρέχοντα κατάλογο, π.χ. prog2 και ζητά τη δημιουργία μιας νέας διεργασίας από τον χρονοδρομολογητή, στην οποία θα τρέχει αυτό το εκτελέσιμο. Εντολή q : Ο φλοιός τερματίζει τη λειτουργία του. Αντίστοιχα, ο χρονοδρομολογητής επεκτείνεται ώστε να υποστηρίζει δυναμική δημιουργία και τερματισμό διεργασιών, όταν λαμβάνει ανάλογες αιτήσεις από το φλοιό. Υποστηρίζονται οι αιτήσεις: REQ_PRINT_TASKS: Αίτηση εκτύπωσης λίστας διεργασιών. REQ_KILL_TASK: Αίτηση τερματισμού διεργασίας με βάση το id της. REQ_EXEC_TASK: Αίτηση δημιουργίας νέας διεργασίας στην οποία θα τρέχει συγκεκριμένο εκτελέσιμο. Τελικό παραδοτέο είναι νέα έκδοση του χρονοδρομολογητή, η οποία θα δημιουργεί επιπλέον των διεργασιών που ορίζονται στη γραμμή εντολών και διεργασία για το πρόγραμμα του φλοιού. Ο φλοιός ζητείται να χρονοδρομολογείται μαζί με τις υπόλοιπες διεργασίες, όντας στην ουρά εκτέλεσης και λαμβάνοντας κβάντα χρόνου σύμφωνα με τον αλγόριθμο RR. Ο χρονοδρομολογητής θα τερματίζεται όταν όλες οι διεργασίες που χειρίζεται τερματίσουν, συμπεριλαμβανομένου του φλοιού.
Σας δίνεται το πρόγραμμα του φλοιού, shell.c και το αρχείο request.h που ορίζει τη μορφή των αιτήσεων από το φλοιό προς τον χρονοδρομολογητή με βάση τη δομή struct request_struct. Ζητήματα Υλοποίησης: Για την υποστήριξη του φλοιού είναι απαραίτητος ένας μηχανισμός επικοινωνίας από το φλοιό προς τον χρονοδρομολογητή και αντίστροφα. Εφόσον ο φλοιός εκτελείται σε διεργασία-απόγονο του χρονοδρομολογητή, μπορούμε να χρησιμοποιήσουμε το μηχανισμό των σωληνώσεων για την επικοινωνία ανάμεσά τους. Θα χρησιμοποιηθούν δύο σωληνώσεις, μία για την αποστολή αιτήσεων από το φλοιό και μία για την παραλαβή απαντήσεων (επιτυχής, ανεπιτυχής) από τον χρονοδρομολογητή. Ο φλοιός είναι άλλο πρόγραμμα, οπότε δεν κληρονομεί τις τιμές των περιγραφητών αρχείων (τους αριθμούς) για τα άκρα των σωληνώσεων. Ο φλοιός που σας δίνεται υποστηρίζει το πέρασμα δύο αριθμών, ενός περιγραφητή για αποστολή αιτήσεων και ενός για παραλαβή απαντήσεων ως ορίσματα στη γραμμή εντολών (παράμετρος argv[] της main()). Ο χρονοδρομολογητής χρειάζεται να περνά κατάλληλες τιμές κατά την εκτέλεση (execve()) του προγράμματος-φλοιού. Οποιαδήποτε αλλαγή στο πρόγραμμα του φλοιού μπορεί να γίνει μόνο έπειτα από συνεννόηση με τους βοηθούς τους μαθήματος. Πιο συγκεκριμένα, νέες διεργασίες που προστίθενται δυναμικά στο σύστημα πρέπει να δημιουργούνται ως παιδιά του χρονοδρομολογητή, όχι με fork() από το φλοιό. Τέλος, δίνονται οι συναρτήσεις signals_disable() και signals_enable(), οι οποίες απενεργοποιούν προσωρινά και ενεργοποιούν, αντίστοιχα, την παραλαβή των σημάτων SIGALRM και SIGCHLD από τον χρονοδρομολογητή. Κλήσεις σε αυτές τις συναρτήσεις θα συμπεριληφθούν γύρω από τον κώδικα του χρονοδρομολογητή που υλοποιεί αιτήσεις του φλοιού για δημιουργία και καταστροφή διεργασιών. Βήματα: 1. Επεκτείνετε το χρονοδρομολογητή ώστε να δημιουργεί τη διεργασία του φλοιού μαζί με τις υπόλοιπες. Προς το παρόν δεν χρειάζεται να την εισάγει στην ουρά χρονοδρομολόγησης. Υλοποιήστε από την πλευρά του χρονοδρομολογητή το μηχανισμό επικοινωνίας με το φλοιό μέσω των δύο σωληνώσεων. 2. Μεταβάλετε τον άεργο βρόχο στο κύριο πρόγραμμα του φλοιού, έτσι ώστε να δέχεται εντολές από το φλοιό και ως μόνη επεξεργασία τους να εμφανίζει το περιεχόμενό τους στην οθόνη: for (;;) { receive_shell_request(); } signals_disable(); process_shell_request(); signals_enable(); return_reply_to_shell(); Βεβαιωθείτε ότι οι αιτήσεις εμφανίζονται κανονικά και τα ορίσματά τους περνούν χωρίς πρόβλημα μέσα από τη σωλήνωση. Βεβαιωθείτε ότι οι απαντήσεις (επιτυχής έκβαση) επιστρέφονται κανονικά στη διεργασία του φλοιού. 3. Επεκτείνετε τον χρονοδρομολογητή ώστε να υλοποιεί τις αιτήσεις από το φλοιό. Βεβαιωθείτε ότι μπορείτε να δημιουργήσετε και να τερματίσετε δυναμικά διεργασίες κι ότι ο χρονοδρομολογητής παρακολουθεί κανονικά την εξέλιξή τους και ενημερώνει σωστά την ουρά εκτέλεσης καθώς διεργασίες δημιουργούνται και πεθαίνουν.
4. Επεκτείνετε το χρονοδρομολογητή ώστε και ο φλοιός να υφίσταται χρονοδρομολόγηση. Ελέγξτε ότι ο φλοιός συμπεριλαμβάνεται στις υπό εκτέλεση διεργασίες και λαμβάνει κβάντα χρόνου περιοδικά. Ερωτήσεις: 1. Όταν και ο φλοιός υφίσταται χρονοδρομολόγηση, ποια εμφανίζεται πάντοτε ως τρέχουσα διεργασία στη λίστα διεργασιών (εντολή p ); Θα μπορούσε να μη συμβαίνει αυτό; Γιατί; 2. Γιατί είναι αναγκαίο να συμπεριλάβετε κλήσεις signals_disable(), _enable() γύρω από την συνάρτηση υλοποίησης αιτήσεων του φλοιού; Υπόδειξη: Η συνάρτηση υλοποίησης αιτήσεων του φλοιού μεταβάλλει δομές όπως η ουρά εκτέλεσης των διεργασιών. 2 Εξέταση άσκησης και αναφορά Η προθεσμία για την εξέταση της άσκησης στο εργαστήριο είναι η Πέμπτη 14/01/2010. Μετά την εξέταση η κάθε ομάδα θα πρέπει να συντάξει μια (σύντομη) αναφορά και να τη στείλει μέσω e-mail στους βοηθούς εργαστηρίου. Η προθεσμία για την αναφορά είναι μια εβδομάδα μετά την εξέταση της άσκησης. Η αναφορά αυτή θα περιέχει, για καθένα από τα ερωτήματα: Τον πηγαίο κώδικα (source code) του ζητούμενου προγράμματος Ενδεικτική έξοδο από την εκτέλεση του χρονοδρομολογητή. Σύντομες απαντήσεις στις ερωτήσεις, μαζί με αντίστοιχη έξοδο του προγράμματος που να τις υποστηρίζει.