- Refresh user manual with up-to-date installation instructions,
and a reviewed chapter about extending the system with your own policies git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@1065 3ecf2c5c-341e-0410-92b4-d18e462d057c
This commit is contained in:
parent
0c02a29f8b
commit
b065d0f099
|
@ -17,7 +17,7 @@
|
||||||
This is SGPEMv2 Developer Manual (version @value{VERSION},
|
This is SGPEMv2 Developer Manual (version @value{VERSION},
|
||||||
@value{UPDATED}).
|
@value{UPDATED}).
|
||||||
|
|
||||||
Copyright @copyright{} 2005 University of Padova, dept. of Pure
|
Copyright @copyright{} 2005-2006 University of Padova, dept. of Pure
|
||||||
and Applied Mathematics
|
and Applied Mathematics
|
||||||
|
|
||||||
Permission is granted to copy, distribute and/or modify this document
|
Permission is granted to copy, distribute and/or modify this document
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
This is SGPEMv2 User Manual (version @value{VERSION},
|
This is SGPEMv2 User Manual (version @value{VERSION},
|
||||||
@value{UPDATED}).
|
@value{UPDATED}).
|
||||||
|
|
||||||
Copyright @copyright{} 2005 University of Padova, dept. of Pure
|
Copyright @copyright{} 2005-2006 University of Padova, dept. of Pure
|
||||||
and Applied Mathematics
|
and Applied Mathematics
|
||||||
|
|
||||||
Permission is granted to copy, distribute and/or modify this document
|
Permission is granted to copy, distribute and/or modify this document
|
||||||
|
@ -89,6 +89,10 @@ Free Documentation License''.
|
||||||
@unnumbered History
|
@unnumbered History
|
||||||
|
|
||||||
@table @strong
|
@table @strong
|
||||||
|
@item 2006, September 8th @r{-- Matteo Settenvini}
|
||||||
|
Update chapters about building and installation. Rewrite some of the
|
||||||
|
chapter about extending SGPEMv2 with custom CPU policies, and add a
|
||||||
|
more complex example.
|
||||||
@item 2006, September 7th @r{--- Luca Vezzaro}
|
@item 2006, September 7th @r{--- Luca Vezzaro}
|
||||||
First attempt at expanding the manual structure with the
|
First attempt at expanding the manual structure with the
|
||||||
stuff we'll need in the forthcoming beta testing
|
stuff we'll need in the forthcoming beta testing
|
||||||
|
@ -130,11 +134,14 @@ First draft of this document.
|
||||||
@cindex description
|
@cindex description
|
||||||
|
|
||||||
SGPEM is an Italian acronym, standing for ``@emph{Simulatore della Gestione dei Processi
|
SGPEM is an Italian acronym, standing for ``@emph{Simulatore della Gestione dei Processi
|
||||||
in un Elaboratore Multiprogrammato}'' (in English, ``@emph{Multitasking Computer Process
|
in un Elaboratore Multiprogrammato}'' (in English, ``@emph{Process
|
||||||
Management Simulator}'').
|
Management Simulator for a Multitasking Computer}'').
|
||||||
It was initially developed for use inside the ``Operating Systems'' teaching,
|
It was initially developed for use inside the ``Operating Systems'' teaching,
|
||||||
part of the Computer Science course of the University of Padova, Italy.
|
part of the Computer Science course of the University of Padova, Italy.
|
||||||
The aim of SGPEM is to provide an for simulating policies applied to sort processes, and for assigning resources in a multitasking computer. SGPEMv2 is a didactic software, and it can help students to understand better the functionality of Operating Systems.
|
The aim of SGPEM is to provide an easy-to-use environment for
|
||||||
|
simulating process scheduling policies, and for assigning resources in
|
||||||
|
a multitasking computer. SGPEMv2 is an educational software, and it can
|
||||||
|
help students to better understand the functionality of operating systems.
|
||||||
|
|
||||||
|
|
||||||
@c % --------------------------------------------------
|
@c % --------------------------------------------------
|
||||||
|
@ -143,8 +150,8 @@ The aim of SGPEM is to provide an for simulating policies applied to sort proce
|
||||||
@section How to read this manual?
|
@section How to read this manual?
|
||||||
@cindex manual
|
@cindex manual
|
||||||
|
|
||||||
We recommend that you read the manual following the the structure that we imposed for it.
|
We recommend that you read the manual following the the structure that
|
||||||
You will be guided trough the Installation, Configuration and Usage process of SGPEM v2.
|
we layed out for it. You will be gently led trough Installation, Configuration and Usage of SGPEMv2.
|
||||||
If you find yourself in trouble reading the manual, please don't hesitate to contact us at
|
If you find yourself in trouble reading the manual, please don't hesitate to contact us at
|
||||||
@email{swe@@thgnet.it}.
|
@email{swe@@thgnet.it}.
|
||||||
|
|
||||||
|
@ -156,7 +163,7 @@ If you find yourself in trouble reading the manual, please don't hesitate to con
|
||||||
@cindex reporting
|
@cindex reporting
|
||||||
|
|
||||||
We welcome bug reports and suggestions for any aspect of the SGPEM v2 system, program in general,
|
We welcome bug reports and suggestions for any aspect of the SGPEM v2 system, program in general,
|
||||||
documentation, installation, anything.Please email us at @email{swe@@thgnet.it}.
|
documentation, installation... anything. Please email us at @email{swe@@thgnet.it}.
|
||||||
For bug reporters, include enough information for us to reproduce the problem. In general:
|
For bug reporters, include enough information for us to reproduce the problem. In general:
|
||||||
@itemize
|
@itemize
|
||||||
@item
|
@item
|
||||||
|
@ -193,14 +200,13 @@ You can use the program from your own shell, or if you prefer you can use the mi
|
||||||
@item
|
@item
|
||||||
The output of the simulation is textual, and you can see it on the main GUI window or on your Terminal window.
|
The output of the simulation is textual, and you can see it on the main GUI window or on your Terminal window.
|
||||||
@item
|
@item
|
||||||
The policy in use if First Come First Served.
|
The policy in use is First Come First Served.
|
||||||
@item
|
@item
|
||||||
You can write your own policies.
|
You can write your own policies.
|
||||||
For more information see @ref{Writing new policies}.
|
For more information see @ref{Writing new policies}.
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@c % --------------------------------------------------
|
@c % --------------------------------------------------
|
||||||
|
|
||||||
@node Installation, Basics, Overview of SGPEM, Top
|
@node Installation, Basics, Overview of SGPEM, Top
|
||||||
|
@ -232,32 +238,22 @@ And if you find this section misses something / it lists
|
||||||
the wrong version of a program, please let us know!
|
the wrong version of a program, please let us know!
|
||||||
|
|
||||||
@c % ---- new subsection
|
@c % ---- new subsection
|
||||||
@subsection Developers
|
@subsection Runtime dependencies
|
||||||
|
|
||||||
Other than the tools needed by users building from sources,
|
To run SGPEMv2, you require:
|
||||||
you'll need:
|
|
||||||
|
|
||||||
@table @emph
|
@table @emph
|
||||||
@item GCC with C++ support
|
|
||||||
as well as the other standard GNU binutils and tools: make, sed, ld...
|
|
||||||
GCC version >=3.4 is highly recommended. Please don't report
|
|
||||||
compiling-related problems with any previous version.
|
|
||||||
|
|
||||||
@item Automake >= 1.9
|
@item Gtkmm >= 2.8 with Cairo support
|
||||||
We use a single @file{Makefile.am} to avoid
|
The popular C++ jacket for the even-more popular GIMP
|
||||||
recursive make. Older versions of automake didn't play right
|
ToolKit. We use Cairo to draw our custom widgets.
|
||||||
with it. See @url{http://aegis.sourceforge.net/auug97.pdf} for
|
|
||||||
the motivations that led to this choice.
|
|
||||||
|
|
||||||
@item Autoconf, libtool, autopoint @dots{}
|
@item Python >= 2.3
|
||||||
The standard autotool family.
|
We use Python to let the user write her own policies
|
||||||
|
in a simple and complete language.
|
||||||
|
|
||||||
@item Subversion >= 1.2
|
@item libXML2 >= 2.6.10
|
||||||
If you need to update the sources from our repository, or commit
|
An XML library we use to save and load files to/from disk.
|
||||||
your changes, you'll need Subversion built with SSL support.
|
|
||||||
|
|
||||||
@item Dejagnu >= 1.4
|
|
||||||
The testsuite framework we use as a platform for running tests.
|
|
||||||
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
|
@ -275,23 +271,36 @@ Python can use, starting from a simple interface specification.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@c % ---- new subsection
|
@c % ---- new subsection
|
||||||
@subsection Runtime dependencies
|
@subsection Developers
|
||||||
|
|
||||||
To run SGPEMv2, you require:
|
Other than the tools needed by users building from sources,
|
||||||
|
you'll need:
|
||||||
|
|
||||||
@table @emph
|
@table @emph
|
||||||
|
@item GCC with C++ support
|
||||||
|
as well as the other standard GNU binutils and tools: make, sed, ld...
|
||||||
|
GCC version >=3.4 is highly recommended. Please don't report
|
||||||
|
compiling-related problems with any previous version. There are some
|
||||||
|
known issues with certain versions of GCC 4.0. @xref{Building}.
|
||||||
|
|
||||||
@item Gtkmm >= 2.8 with Cairo support
|
@item Automake >= 1.9
|
||||||
The popular C++ jacket for the even-more popular GIMP
|
We use a single @file{Makefile.am} to avoid
|
||||||
ToolKit. We use Cairo to draw our custom widgets.
|
recursive make. Older versions of automake didn't play right
|
||||||
|
with it. See @url{http://aegis.sourceforge.net/@/auug97.pdf} for
|
||||||
|
the motivations that led to this choice.
|
||||||
|
|
||||||
@item Python >= 2.3
|
@item Autoconf, libtool, autopoint @dots{}
|
||||||
We use Python to let the user write her own policies
|
The standard autotool family.
|
||||||
in a simple and complete language.
|
|
||||||
|
@item Subversion >= 1.2
|
||||||
|
If you need to update the sources from our repository, or commit
|
||||||
|
your changes, you'll need Subversion built with SSL support.
|
||||||
|
|
||||||
|
@item Dejagnu >= 1.4
|
||||||
|
The testsuite framework we use as a platform for running tests.
|
||||||
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
|
|
||||||
@c % --------------------------------------------------
|
@c % --------------------------------------------------
|
||||||
|
|
||||||
@node Building, (none), Prerequisites, Installation
|
@node Building, (none), Prerequisites, Installation
|
||||||
|
@ -300,49 +309,70 @@ in a simple and complete language.
|
||||||
|
|
||||||
@noindent To ensure a clean build, follow these steps:
|
@noindent To ensure a clean build, follow these steps:
|
||||||
|
|
||||||
|
@sp 1
|
||||||
@example
|
@example
|
||||||
@code{cd <this directory>}
|
@code{cd <the package root directory>}
|
||||||
@code{mkdir =build}
|
@code{mkdir =build}
|
||||||
@code{cd =build}
|
@code{cd =build}
|
||||||
@code{CXXFLAGS="what you want" ../configure --prefix=/usr/local}
|
@code{CXXFLAGS="what you want" ../configure --prefix=/usr/local}
|
||||||
@end example
|
@end example
|
||||||
@sp 2
|
@sp 1
|
||||||
|
|
||||||
@noindent This will check you have all the needed software installed.
|
@noindent This will check you have all the needed software installed.
|
||||||
|
|
||||||
@noindent Choosing good @env{CXXFLAGS} to optimize your build.
|
@noindent Choose good @env{CXXFLAGS} to optimize your build.
|
||||||
For example, on my machine, I would use:
|
For example, on my machine, I would use:
|
||||||
|
|
||||||
|
@sp 1
|
||||||
@example
|
@example
|
||||||
@code{CXXFLAGS="-O3 -pipe -march=pentium4" ../configure --prefix=/usr/local}
|
@code{CXXFLAGS="-O3 -pipe -march=pentium4" ../configure --prefix=/usr/local}
|
||||||
@end example
|
@end example
|
||||||
@sp 2
|
@sp 1
|
||||||
|
|
||||||
@noindent Being a developer, though, if I had to debug SGPEM, I would type:
|
@noindent Being a developer, though, if I had to debug SGPEM, I would
|
||||||
|
type:
|
||||||
|
|
||||||
|
@sp 1
|
||||||
@example
|
@example
|
||||||
@code{CXXFLAGS="-O0 -g -ggdb -pg" ../configure \}
|
@code{../configure --prefix=`pwd`/../=inst --enable-debug}
|
||||||
@code{ --prefix=`pwd`/_inst}
|
|
||||||
@end example
|
@end example
|
||||||
@sp 2
|
@sp 1
|
||||||
|
|
||||||
|
@noindent Please note that those around ``pwd'' are backticks, and not
|
||||||
|
normal apostrophes.
|
||||||
|
|
||||||
@strong{Warning}: at the moment, we are aware that passing
|
@strong{Warning}: at the moment, we are aware that passing
|
||||||
@option{--disable-shared} to configure doesn't work. We'll look into it
|
@option{--disable-shared} to configure doesn't work. We'll look into it
|
||||||
sooner or later, but in the meantime just build shared libraries.
|
sooner or later, but in the meantime just build shared libraries.
|
||||||
|
|
||||||
@noindent Once succesfully configured SGPEMv2, just type:
|
@noindent Once succesfully configured SGPEMv2, just type:
|
||||||
|
|
||||||
|
@sp 1
|
||||||
@example
|
@example
|
||||||
@command{make}
|
@command{make}
|
||||||
@end example
|
@end example
|
||||||
@sp 2
|
@sp 1
|
||||||
|
|
||||||
@noindent And upon a succesful build, you can install it just by:
|
@noindent Some versions of GCC 4, usually those before the 4.1 series,
|
||||||
|
present some problems with the newly-added visibility support for DSO
|
||||||
|
object symbols. For example, OpenSuSE 10.0 is known to have such
|
||||||
|
issues. If you encounter problems during building and in linking stage
|
||||||
|
about unresolved symbols in libraries, please re-run
|
||||||
|
@command{configure} with the @option{--disable-visibility-support}
|
||||||
|
option. You'll then have to run @command{make clean && make}.
|
||||||
|
|
||||||
|
|
||||||
|
@noindent Upon a succesful build, you can install SGPEMv2 just by hitting:
|
||||||
|
|
||||||
|
@sp 1
|
||||||
@example
|
@example
|
||||||
@code{su -c "make install"}
|
@code{su -c "make install"}
|
||||||
@end example
|
@end example
|
||||||
@sp 2
|
@sp 1
|
||||||
|
|
||||||
@noindent Root password will be required (of course, if you're
|
@noindent Root password will be required (of course, if you're
|
||||||
installing it with a prefix placed inside your home directory,
|
installing it with a prefix placed inside your home directory,
|
||||||
you won't need administrative rights, and just ``@samp{make install}''
|
you won't need administrative rights, and just ``@command{make install}''
|
||||||
will sufficit).
|
will sufficit).
|
||||||
|
|
||||||
See the ``@file{INSTALL}'' file in this folder for an overview of other
|
See the ``@file{INSTALL}'' file in this folder for an overview of other
|
||||||
|
@ -353,10 +383,11 @@ See the ``@file{INSTALL}'' file in this folder for an overview of other
|
||||||
We added Doxygen support to the project. If you've installed it,
|
We added Doxygen support to the project. If you've installed it,
|
||||||
you can simply run @command{make apidox} from the package
|
you can simply run @command{make apidox} from the package
|
||||||
top source directory. The documentation will be outputted into
|
top source directory. The documentation will be outputted into
|
||||||
the @samp{$@{BUILD_DIR@}/docs/API/} directory.
|
the @samp{$@{BUILD_DIR@}/docs/API/} dir.
|
||||||
|
|
||||||
If you'd like to generate nicier inheritance graphs, you've just to
|
If you'd like to generate nicier inheritance graphs, you've just to
|
||||||
install @command{dot}, part of the @emph{Graphviz} package.
|
install @command{dot}, part of the @emph{Graphviz} package. If you
|
||||||
|
didn't have it previously installed, you may need to re-run @command{configure}.
|
||||||
|
|
||||||
@c % --------------------------------------------------
|
@c % --------------------------------------------------
|
||||||
|
|
||||||
|
@ -548,8 +579,6 @@ Each schedulable entity is represented by its name followed by its priority encl
|
||||||
|
|
||||||
@c % ------------------------------------------------
|
@c % ------------------------------------------------
|
||||||
|
|
||||||
@c % -------------------------------------------------
|
|
||||||
|
|
||||||
@node Extending SGPEM, License, Using SGPEM, Top
|
@node Extending SGPEM, License, Using SGPEM, Top
|
||||||
@chapter Extending SGPEM
|
@chapter Extending SGPEM
|
||||||
@cindex extending
|
@cindex extending
|
||||||
|
@ -561,16 +590,30 @@ Each schedulable entity is represented by its name followed by its priority encl
|
||||||
|
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
|
@c % -------------------------------------------------
|
||||||
|
|
||||||
@node Writing new policies, Writing plugins, Extending SGPEM, Extending SGPEM
|
@node Writing new policies, Writing plugins, Extending SGPEM, Extending SGPEM
|
||||||
@section Writing new policies
|
@section Writing new policies
|
||||||
@cindex writing policies
|
@cindex writing policies
|
||||||
|
|
||||||
All policies are implemented in Python, but don't worry (be happy!). You don't have to be a Python expert to write a new policy.
|
All built-in policies are implemented in Python, but don't worry: you
|
||||||
We'll explain you how to write a new policy on an simple example of FCFS policy. Now let's start, all you have to do is change the few bold-ed lines, of the following example.
|
don't have to be a Python expert to write a new policy. We'll explain
|
||||||
@sp 1
|
you how to write a new policy on an simple example of FCFS
|
||||||
|
policy. Then a more complex example will follow: a Round Robin policy
|
||||||
|
that uses pre-emption by priority.
|
||||||
|
|
||||||
|
Now let's get started, all you have to do to create your own policy is
|
||||||
|
to change the few bold lines of the following example. Also remember
|
||||||
|
that the name of the class have to be the same of the name of the file
|
||||||
|
(minus the @code{.py} file extension, of course).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@c % --------- new subsection
|
||||||
|
@subsection A beginner example: First Come First Served
|
||||||
|
|
||||||
@example
|
@example
|
||||||
01 from Policy import Policy
|
01 from CPUPolicy import CPUPolicy
|
||||||
02 class fcfs(Policy) :
|
02 class fcfs(Policy) :
|
||||||
03 def __init__(self):
|
03 def __init__(self):
|
||||||
04 pass;
|
04 pass;
|
||||||
|
@ -586,48 +629,220 @@ We'll explain you how to write a new policy on an simple example of FCFS policy.
|
||||||
|
|
||||||
11 def sort_queue(self, event, queue):
|
11 def sort_queue(self, event, queue):
|
||||||
@strong{12 cmpf = lambda a, b: \
|
@strong{12 cmpf = lambda a, b: \
|
||||||
a.get_schedulable().get_arrival_time() < \
|
a.get_schedulable().get_arrival_time() <= \
|
||||||
b.get_schedulable().get_arrival_time()
|
b.get_schedulable().get_arrival_time()
|
||||||
13 self.sort(queue,cmpf)}
|
13 self.sort(queue,cmpf)}
|
||||||
@end example
|
@end example
|
||||||
@sp 2
|
@sp 2
|
||||||
|
|
||||||
|
|
||||||
@itemize
|
@table @asis
|
||||||
@item body of @code{def configure(self):} line 06 - Configure policy to initial values.
|
@item body of @code{def configure(self)}: line 06
|
||||||
This is called just before a simulation starts, and is responsible to define
|
|
||||||
|
Configure policy to initial values. This is called just before a
|
||||||
|
simulation starts, and it is responsible to define
|
||||||
the parameters the policy wants to expose to the user. For example, it may make
|
the parameters the policy wants to expose to the user. For example, it may make
|
||||||
the return value of is_preemptive configurable, or register an integer value for
|
the return value returned by @code{is_preemptive()} configurable, or
|
||||||
a the time slice duration.
|
to register an integer value for a the time slice duration.
|
||||||
@sp 1
|
|
||||||
@item body of @code{def is_preemptive(self):} line 08 - It says whether the policy wants to be preemptive, other than by normal time slice termination.
|
@item body of @code{def is_preemptive(self):} line 08
|
||||||
|
|
||||||
|
It says whether the policy wants to be preemptive, other than by
|
||||||
|
normal time slice termination (if a positive time slice has been provided).
|
||||||
|
|
||||||
The possible return values are:
|
The possible return values are:
|
||||||
@enumerate
|
@enumerate
|
||||||
@item True
|
|
||||||
If the policy declares it wants the running process to be released if a process at higher priority is put at the beginning of the ready processes queue
|
|
||||||
|
|
||||||
@item False
|
@item
|
||||||
If the policy always waits the end of the time slice (or a process blocking/termination, of course) before selecting a new running process, even if it has greater priority than the current one.
|
@code{True}: If the policy returns True, it declares that it wants the running
|
||||||
|
thread to be released if a thread at higher priority is put at the
|
||||||
|
beginning of the ready threads queue.
|
||||||
|
|
||||||
|
This is achieved by putting the current running thread, if there is
|
||||||
|
one, onto the ready queue. It is up to you, into the
|
||||||
|
@code{sort_queue()} method, to manage this special case.
|
||||||
|
|
||||||
|
@item
|
||||||
|
@code{False}: The policy always waits the end of the time slice (or a thread
|
||||||
|
blocking/termination) before selecting a new running thread, even if it
|
||||||
|
has greater priority than the current one.
|
||||||
|
|
||||||
|
There will never be a running thread in the ready queue passed to
|
||||||
|
@code{sort_queue()}.
|
||||||
|
|
||||||
@end enumerate
|
@end enumerate
|
||||||
|
|
||||||
Please note how the word ``priority'' here has a general meaning: it indicates every process than
|
Please note how the word ``priority'' here has a general meaning: it indicates every thread than
|
||||||
can bubble up the sorted ready queue and come before another. So it's up
|
can bubble up the sorted ready queue and come before another. So it's up
|
||||||
to Policy.sort_queue() to give it a precise meaning.
|
to Policy.sort_queue() to give it a precise meaning.
|
||||||
|
|
||||||
@sp 1
|
@sp 1
|
||||||
@item body of @code{def get_time_slice(self):} line 10 - Returns how long is a time-slice for this policy.
|
@item body of @code{def get_time_slice(self):} line 10
|
||||||
A time sliced policy should return a positive integer value, a policy which doesn't use slices should instead
|
|
||||||
return -1. You're encouraged to use a user-configurable parameter via Policy.configure() if the policy is
|
Returns how long is a time-slice for this policy.
|
||||||
|
A time sliced policy should return a positive integer value, a policy
|
||||||
|
which doesn't use slices should instead
|
||||||
|
return @code{-1}. You're encouraged to use a user-configurable
|
||||||
|
parameter via @code{Policy.configure()} if the policy is
|
||||||
time-sliced, to ensure greater flexibility.
|
time-sliced, to ensure greater flexibility.
|
||||||
|
|
||||||
@sp 1
|
@sp 1
|
||||||
@item body of
|
@item body of @code{ def sort_queue(self, event, queue):} line 12,13
|
||||||
@code{ def sort_queue(self, event, queue):}
|
|
||||||
line 12,13 - Sort ready processes queue.
|
|
||||||
This method is called by the scheduler at each step of the simulation to sort the ready processes queue.
|
|
||||||
|
|
||||||
@end itemize
|
Sort the queue of ready threads. This method is called by the
|
||||||
|
scheduler at each step of the simulation to sort the ready threads
|
||||||
|
queue. It is the core of your policy: when scheduler has to select
|
||||||
|
a new thread it will always try to take the first of the queue. If it
|
||||||
|
cannot run for some reason (for example, it immediately blocks), the
|
||||||
|
second is selected and so on, until the end of the queue.
|
||||||
|
|
||||||
|
Remember that if @code{is_preemptible()} returns True, you may have
|
||||||
|
a running thread in the queue. See the following example for some tips
|
||||||
|
about how to manage this case.
|
||||||
|
|
||||||
|
Pay attention to the fact that we used the @code{<=} relation at line @samp{12}, and
|
||||||
|
not a simple @code{<}. This is because @code{queue.sort()} uses a
|
||||||
|
in-place implementation of quicksort, which is stable only when
|
||||||
|
employed with a minor-or-equal relation. Otherwise the queue would be
|
||||||
|
sorted, but two adjacent threads that have the same value for a given
|
||||||
|
priority would be swapped. If your policy behaves strangely, this may
|
||||||
|
be the cause.
|
||||||
|
|
||||||
|
@end table
|
||||||
|
|
||||||
|
@c % --------- new subsection
|
||||||
|
@subsection Exposed interface: what you can use
|
||||||
|
|
||||||
|
@anchor{Configuring parameters}
|
||||||
|
@subsubsection Configuring parameters
|
||||||
|
|
||||||
|
TODO: list and describe all methods exposed from PolicyParameters.
|
||||||
|
|
||||||
|
@subsubsection Methods for manipulating the ready queue
|
||||||
|
|
||||||
|
TODO: list and describe all methods exposed from ReadyQueue.
|
||||||
|
|
||||||
|
@subsubsection Properties of schedulable entities
|
||||||
|
|
||||||
|
TODO: list and describe all methods exposed from Schedulable,
|
||||||
|
Thread and Process
|
||||||
|
|
||||||
|
|
||||||
|
@c % --------- new subsection
|
||||||
|
@subsection A more complete example: Round Robin with priority
|
||||||
|
|
||||||
|
Now, let's see a more interesting (and a little more complex) example:
|
||||||
|
a Round Robin by priority policy that can optionally also work with
|
||||||
|
pre-emption by priority.
|
||||||
|
|
||||||
|
@sp 2
|
||||||
|
@example
|
||||||
|
00 from CPUPolicy import CPUPolicy
|
||||||
|
01
|
||||||
|
02 class rr_priority(CPUPolicy) :
|
||||||
|
03 """Round Robin scheduling policy that takes priority in account.
|
||||||
|
04
|
||||||
|
05 No lower priority thread can run if a higher
|
||||||
|
06 priority thread exists. If pre-emptive by priority, a
|
||||||
|
07 higher-priority thread becoming ready even in the middle
|
||||||
|
08 of a time slice will pre-empt the running thread. Else,
|
||||||
|
09 the time slice will have to end before the former can run."""
|
||||||
|
10
|
||||||
|
11 def __init__(self):
|
||||||
|
12 pass;
|
||||||
|
13
|
||||||
|
14 def configure(self):
|
||||||
|
15 param = self.get_parameters()
|
||||||
|
16 param.register_int("Time slice", 1, 10000, True, 2)
|
||||||
|
17 param.register_int("Is preemptive?", 0, 1, True, 1)
|
||||||
|
18
|
||||||
|
19 def is_preemptive(self):
|
||||||
|
20 value = self.get_parameters().get_int("Is preemptive?")
|
||||||
|
21 if value == 0:
|
||||||
|
22 return False
|
||||||
|
23 else:
|
||||||
|
24 return True
|
||||||
|
25
|
||||||
|
26 def get_time_slice(self):
|
||||||
|
27 return self.get_parameters().get_int("Time slice")
|
||||||
|
28
|
||||||
|
29 def sort_queue(self, queue):
|
||||||
|
30 by_ltime = lambda a, b: \
|
||||||
|
31 a.get_last_acquisition() <= \
|
||||||
|
32 b.get_last_acquisition()
|
||||||
|
33 by_prio = lambda a, b: \
|
||||||
|
34 a.get_current_priority() <= \
|
||||||
|
35 b.get_current_priority()
|
||||||
|
36
|
||||||
|
37 self.sort(queue,by_ltime)
|
||||||
|
38 self.sort(queue,by_prio)
|
||||||
|
39
|
||||||
|
40 # manage preemption: see if we've a running thread
|
||||||
|
41 # in the ready queue, and if it can still run
|
||||||
|
42 if self.is_preemptive() == True:
|
||||||
|
43 higher_prio = queue.get_item_at(0).get_current_priority()
|
||||||
|
44 i = 0
|
||||||
|
45 while i < queue.size():
|
||||||
|
46 sched = queue.get_item_at(i)
|
||||||
|
47 priority = sched.get_current_priority()
|
||||||
|
48 if(priority != higher_prio):
|
||||||
|
49 break
|
||||||
|
50 if sched.get_state() == "running":
|
||||||
|
51 queue.bubble_to_front(i)
|
||||||
|
52 i += 1
|
||||||
|
@end example
|
||||||
|
|
||||||
|
We've also added a description of the class immediately
|
||||||
|
following the class declaration (lines @samp{03-09}). This is what is
|
||||||
|
returned as the policy description in the frontend. You may want to
|
||||||
|
document your policies in the same way too.
|
||||||
|
|
||||||
|
Now, let's see the most complex parts together:
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@item configure()
|
||||||
|
|
||||||
|
There are three types of parameters you can register in the value
|
||||||
|
returned by @code{self.get_parameters()}, and they are integer
|
||||||
|
parameters, float parameters and strings. Usually boolean values can
|
||||||
|
be simulated by registering a integer parameter limited in the
|
||||||
|
interval [0, 1]. @xref{Configuring parameters} for the exposed interface.
|
||||||
|
|
||||||
|
@item is_preemptive()
|
||||||
|
|
||||||
|
TODO: write me
|
||||||
|
|
||||||
|
@item sort_queue()
|
||||||
|
|
||||||
|
Here there are quite a lot of things going on, so let's tackle them
|
||||||
|
one by one.
|
||||||
|
|
||||||
|
At line @samp{30} we create a lambda-function that says to sort the queue
|
||||||
|
by last aquisition time, so that threads that have been aquired
|
||||||
|
recently end up at the back of the queue (which is exactly what a
|
||||||
|
Round Robin policy should do).
|
||||||
|
|
||||||
|
Then, at line @samp{33}, we create another lambda-function, this time
|
||||||
|
because we want to sort the queue by priority, too.
|
||||||
|
|
||||||
|
Done this, we let quicksort do the hard job at lines @samp{37-38}.
|
||||||
|
|
||||||
|
Since we may have pre-emption enabled, we may have a running thread on
|
||||||
|
the ready queue (if one exists at the current instant). But what
|
||||||
|
happens if the running thread was put in the queue, and we just sorted it?
|
||||||
|
|
||||||
|
Unfortunately, having the greatest last aquisition time, the running thread would end
|
||||||
|
at the back of the queue, thus never being selected to run for more
|
||||||
|
than a single time unit if the queue is non-empty and there are other
|
||||||
|
threads with the same priority!
|
||||||
|
|
||||||
|
The solution is to check if there is a thread with state ``running''
|
||||||
|
at the beginning of the queue, between those that have the same
|
||||||
|
priority. If there's one, we make it bubble to the top of the queue.
|
||||||
|
|
||||||
|
This is the explanation for lines @samp{42-52}.
|
||||||
|
|
||||||
|
@end table
|
||||||
|
|
||||||
|
|
||||||
@c % -------------------------------------------------
|
@c % -------------------------------------------------
|
||||||
|
@ -636,6 +851,7 @@ This method is called by the scheduler at each step of the simulation to sort th
|
||||||
@section Writing plugins
|
@section Writing plugins
|
||||||
@cindex plugins
|
@cindex plugins
|
||||||
|
|
||||||
|
TODO: write me
|
||||||
|
|
||||||
@c % -------------------------------------------------
|
@c % -------------------------------------------------
|
||||||
@c include license text
|
@c include license text
|
||||||
|
|
Loading…
Reference in New Issue