| 1 | = Modules design = |
| 2 | As mentioned above, what is needed in large-scale programming is a comprehensive |
| 3 | '''view''' of function relationship, which permits engineering enhancements, such |
| 4 | as improvement of function interaction in order to avoid code redundancy. |
| 5 | |
| 6 | == Phase 1 == |
| 7 | According to this, we tried from beginning to read project specifications with |
| 8 | such wide view, noticing a sort of parallelism between `remove`ing and `out`ing |
| 9 | functions. In fact, relationship among them is the same in PCB module as in ST |
| 10 | one: `out` work on a specified element, while `remove` do the same on an |
| 11 | element which is a priori known. Looking deeper, become clearer that they |
| 12 | complete the same operation - dequeuing a process. So we decided to let |
| 13 | `outProcQ` carry out the dirty work, reducing replicated code and our workload |
| 14 | `:)`. |
| 15 | Translating this idea into `pcb.c` code was trivial, but was not the same for |
| 16 | `st.c`, because `outProcQ` can be called only after determining the precise |
| 17 | semaphore's queue to work on. Because of the fact that both `outBloked` and |
| 18 | `removeBlocked` have to search that queue, we discarded to make one function |
| 19 | calling the other avoiding searching twice. |
| 20 | So, we developed '''`captureBlocked`:''' an internal specialized routine called by |
| 21 | them, which searches, removes the process using `outProcQ` and, if the queue |
| 22 | becomes empty (and semaphore become inactive) it removes the associated |
| 23 | semaphore descriptor from the tree. In the latter case, this function saves the |
| 24 | other doing a hard job - binary search tree properties maintenance. |
| 25 | |
| 26 | Moreover we found another evident situation where function interaction would |
| 27 | have made code more simple and coding funnier. It comes from the whole st.c |
| 28 | module, where almost all functions need of |
| 29 | [wiki:DataStructures#a3.Semaphorebinarytree looking for] a semaphore descriptor. |
| 30 | So we created '''`searchSemd`''', which carries out the majority of scanning-tree |
| 31 | iterations load. In the name of code re-usability and non-determinism, we |
| 32 | created a function capable to be called by different functions with different |
| 33 | targets. It returns a reference to a possible result of the tree search; this |
| 34 | output will be interpreted by removal function as the place where "victim" is, |
| 35 | while by inserting one as the place where to put in. |
| 36 | |
| 37 | == Phase 2 == |
| 38 | Nucleus is all but linear, because of the intrinsic web of calls, passes up and |
| 39 | invocations inside the code. A modularized structure eases not only writing and |
| 40 | maintaining the code, but also understanding it. |
| 41 | |
| 42 | === Scheduler adaptability === |
| 43 | Designing Phase 2, we distinguished between two strictly correlated operations: scheduling and dispatching. In fact we intend the first as the action of analyzing ready processes and then choose one for execution, together with its time-quantum length. On the other hand, dispatching means to put into effect (and guarantee) that decision, that is loading the right processor state. |
| 44 | Therefore we divided them, [wiki:Architecture#a2.2.Phase2 confining] the scheduler in a '''capsule''' which obfuscates its real implementation details. This highly increase scheduler adaptability, easing future changes in every scenarios. |
| 45 | Moreover our implementation is oriented to run-time changes of scheduling algorithm, in order to provide an operating system that is ''general''-purpose and not ''generic''-purpose. |
| 46 | In fact the scheduler's interface consist of a series of pointers to the specific-implementation functions. They are initialized by `initSched()` according to the configuration chosen in the [source:trunk/phase2/Makefile Makefile]. |
| 47 | Run-time switch between scheduling algorithms can be easily implemented with a function which performs a trivial update to interface pointers and internal data structure: the ready queue. |
| 48 | |
| 49 | === modularizzazione in ph2 === |
| 50 | An important and unexpected benefit of modularization, convinces us of applying such principle in Phase 2 designing too. In fact, we escaped from the needing of generating exceptions after errors or, more generally, after abnormal situations. Consequently we opted for a direct '''function-call strategy''', which clearly minimizes the over-head caused by recursive raising of exceptions, in other words it reduces the number of context switches. |