This action might not be possible to undo. Are you sure you want to continue?
Kaya Kernel – phase 2
Gino Cappelli – Andrea Melis – Andrea Catalini GLOBALVAR.E: This files contains all global variables defined as extern, this means that all files that include globalvar.e can access these variables. GLOBALVAR.C: It includes globalvar.e and contains the variables declaration. initial.e, interrupts.e, exceptions.e, scheduler.e and syscalls.e include globalvar.e. // INITIAL.C: In this files are initialized all global variables and finally the scheduler is called. An important task done in this file consists in the starting of first process, all field of the new process are initialized and finally it's added to the ready queue. The ready queue (struct list_head readyQueue) contains all processes in the system: each new process is added on the tail of the ready queue by the scheduler. Each process in the system (apart the current process that is placed in the currentProcess variable) is either in the ready queue or blocked on a semaphore (device semaphore or an external semaphore). An other task: the four new Areas in the ROM Reserved Frame are populated. // SYSCALLS.C: This files contains syscalls implementation: • SYS1 (CREATEPROCESS): Alloc a process control block for the new process and, after initialized, add it to the ready queue. • SYS2 (TERMINATEPROCESS): Terminate a process. • SYS3 (VERHOGEN): Perform a V() operation on a semaphore passed in input. • SYS4 (PASSERN): Perform a P() operation on a semaphore passed in input. • SYS5 (GETPID): Return the pid of the current process. • SYS6 (GETCPUTIME): Return the time of cpu used by the process from it's start moment. • SYS7 (WAITCLOCK): Perform a P() on the pseudoClockTimer semaphore. • SYS8 (WAITIO): Perform a P() on a device semaphore and return the device status register of that device. V() it's done by the interrupt handler every 100 microseconds. • SYS9 (GETPPID): Return the pid of the parent.
SYS10-11-12 (SPECTLBVECT-SPECPGMVECT-SPECSYSVECT): Calling process attemps to (re)define (indicate) it's own handler for tlb (program trap-sysbp) exceptions. SEMAPHORES MANAGEMENT: We use four array of semaphores, one array for each type of device (terminal, disk, tape, printer). Plus one semaphore for interval timer (the pseudoClockTimer semaphore). Every array has eight semaphores since there are max eight line for each device. Actually for the terminal we use a matrix 8x2: eight rows for each available line and two coloumns, one for the receive and another one for the trasmission.
These semaphores are defined in globalvar.c and can be accessed through globalvar.e. It would have been possible to use a unique array of semaphores, but we've used four separate arrays for readability and simplicity. PID MANAGEMENT: The management of the pid it has been made in a way to make efficient the calculation of the pointer at the structure pcb_t, so in O(1) instead of O(n). It has created an Array of pid of length Maxpid , where each index of the array corresponds at a pointer at process. The SYS1 acts through a counter ( pidcount ) to assign the correct pid at the process and to insert in base at the index the pointer at process made in the chart of the pid. Sure enough they increase the pidcount before they assign it. The SyS2 acts instead, once that you have in a great time the pointer at process, for reset a NULL the cell of the array that corresponds him (this option is managed by the function (massacre) ).
Finally always the SYS1 manages the situation if the counter pidcount arrives at MAXPID. In this case the SYS1 provides creating the first cell empty of the array of the pid and to assign it at the process created. TIME MANAGEMENT: Whenever a SYSCALL 6 is called, the kernel must be able to return the elapsed time of cpu used by the calling process. To accomplish this task we update an integer (unsigned integer) in the process control block of the process, in this way we can return it in every moment. In particular we update this value before each SYS6 (because it couldn't be perfectly updated at that time) and in the scheduler. An other problem is raised by the interval timer, infact we must perform a V() operation on the pseudoClockTimer every 100 microseconds. We use two global variables (intervalFlag, a boolean, and elapsedTime, an integer): every time the execution is passed to the scheduler it update elapsedTime with the amount of time elapsed from the last time that the execution was passed there. If elapsedTime reaches 100 microseconds, intervalFlag is setted. In this way the interrupt timer can know if perform the V() on on the pseudoClockTimer seeing the intervalFlag. // EXCEPTIONS.C: This file contains the sysbk exception handler, it handle each type of system call: • SYS1: Execute a SYS1 and continue with the current process. • SYS2: Terminate a process and all it's progeny. In case of success return 0, -1 otherwise. If the process has been terminated load next process. • SYS3: Perform a V() operation on a semaphore and then continue with current process. • SYS4: Perform the P() operation: if the process must be blocked. (semaphore value < 0) call the scheduler with the blocking mode (see SCHEDULER), otherwise continue with the current process. • SYS5: Return the pid and continue with the current process. • SYS6: Like SYS5, continue with the current process after the syscall. • SYS7: Perform a P() on the pseudoclockTimer, so if the process must be blocked call the scheduler with the blocking mode, otherwise continue/load the current process. • SYS8: Like SYS7 but on a semaphore device. • SYS9: Return the pid of the parent and continue with the current process. • SYS10-11-12: In case of success continue with the current process, otherwise the current process has been terminated so continue with next process in ready queue. PROGRAM TRAP TLB HANDLERS AND ABOVE FUNCTION: , All these three functions do the same actions: • If the offending process has issued a SYS10-11-12 save the new old area in the current process and "pass up" the handling of the exception. • Terminate the current process otherwise.
ERROR HEANDLING: The calling process could call a system call in user mode: in this case we simulate a programTap (moving the “reserved instruction” command in the cause register so the pgmTrap handler can know which type of error has occurred and calling it). The calling process could also call an undefined system call (>=13), in this case we call the aboveExceptions function. // INTERRUPTS.C: This file contains the interrupt exception handler, it handle each type of interrupt: • Interrupt timer: sblock all precesses on the pseudo clock timer, acknowledge the interval timer with a long time slice (SCHED_BOGUS_SLICE) and call the scheduler with mode 5 (see SCHEDULER). • Disk, tape and printer interrupt: acknowledge the corresponding device writing ACKNOWLEDGE code (1) in the device register and perform a V() operation on the corresponding semaphore line. Then call the scheduler in blocking mode (see SCHEDULER). • Terminal interrupt: acknowledge the terminal writing ACKNOWLEDGE code (1) in the device register (find the corresponding field, one for the receive and another one for the transmission) and perform a V() operation on the corresponding semaphore line. Then call the scheduler in blocking mode (see SCHEDULER). CASE OF THE TERMINAL INTERRUPT:
// SCHEDULER.C: The scheduler is the most important part of the kernel, our scheduler has five modes ( scheduler(int mode) ): • 0: Base mode, load next process from the ready queue. The scheduler is called in this mode the first time (from initial.c) and at each context switch (interval timer in interrupts.c). • 1: Current process it's been blocked on a semaphore, so load next process (and do not insert the current process in ready queue! ). In case of P() or SYS7() the scheduler can be called with this mode. • 2: Terminate mode (SYS2): simply load next and do not upload the process cpu time (because the process no longer exists!). The scheduler can be called in this mode after a SYS2 or in case of some errors. • 3: Continue with the current process. Most of the time the scheduler is called in this mode. • 4: WAITIO mode: call checkdeadlock() and wait until an interrupt arrives. After each SYS8 the scheduler can be called with this mode. • 5: Scheduler caller is the interval timer, load next but don't set the time slice: it's been already done by the interval time (with SET_IT(SCHED_BOGUS_SLICE), see INTERRUPTS). At each occurrence the scheduler upload the amount of cpu time used by the current process and the global variable elapsedTime, when this variable reaches 100 microseconds intervalFlag is setted (see SYSCALLS – timing management). Before returning the control at the new current process (with LDST() funtion ) loaded from the head of the ready queue, the old current process is inserted to the tail of the ready queue (obviously not in cases 2,3 and 4). // END
This action might not be possible to undo. Are you sure you want to continue?
We've moved you to where you read on your other device.
Get the full title to continue reading from where you left off, or restart the preview.