revisions 846:897 into trunk, with approval and peer review of manager (Luca). git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@898 3ecf2c5c-341e-0410-92b4-d18e462d057c
This commit is contained in:
parent
2ff87baadf
commit
e27ba77fed
16
Makefile.am
16
Makefile.am
|
@ -49,6 +49,7 @@ bin_PROGRAMS =
|
||||||
pkglib_LTLIBRARIES =
|
pkglib_LTLIBRARIES =
|
||||||
plugin_LTLIBRARIES =
|
plugin_LTLIBRARIES =
|
||||||
noinst_HEADERS =
|
noinst_HEADERS =
|
||||||
|
noinst_DATA =
|
||||||
pkginclude_HEADERS =
|
pkginclude_HEADERS =
|
||||||
EXTRA_DIST =
|
EXTRA_DIST =
|
||||||
MAINTAINERCLEANFILES =
|
MAINTAINERCLEANFILES =
|
||||||
|
@ -408,3 +409,18 @@ CLEANFILES += \
|
||||||
|
|
||||||
endif #~ if COND_TESTS
|
endif #~ if COND_TESTS
|
||||||
|
|
||||||
|
# ############################################################
|
||||||
|
#
|
||||||
|
# extra files to distribute
|
||||||
|
#
|
||||||
|
# ############################################################
|
||||||
|
|
||||||
|
noinst_DATA += \
|
||||||
|
src/testsuite/scheduling-wizards \
|
||||||
|
src/testsuite/scheduling-wizards/wizard-deadlock-test \
|
||||||
|
src/testsuite/scheduling-wizards/wizard-gap-fail \
|
||||||
|
src/testsuite/scheduling-wizards/wizard-assert-fail \
|
||||||
|
src/testsuite/scheduling-wizards/wizard-unblock-test \
|
||||||
|
src/testsuite/scheduling-wizards/wizard-complex-test \
|
||||||
|
src/testsuite/scheduling-wizards/wizard-priority-inversion-porno \
|
||||||
|
src/testsuite/scheduling-wizards/wizard-block-fail
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
src/plugin.cc
|
||||||
|
src/python_cpu_policy.cc
|
||||||
|
src/python_cpu_policy_manager.cc
|
||||||
|
src/testsuite/test-python_loader.cc
|
|
@ -0,0 +1,5 @@
|
||||||
|
src/plugin.cc
|
||||||
|
src/testsuite/test-xml_serializer.cc
|
||||||
|
src/xml_serializer.cc
|
||||||
|
src/xml_serializer_factory.cc
|
||||||
|
src/xml_visitor.cc
|
118
po/POTFILES.in
118
po/POTFILES.in
|
@ -1,46 +1,74 @@
|
||||||
# List of source files which contain translatable strings.
|
# List of source files which contain translatable strings.
|
||||||
./src/parse_opts.cc
|
src/backend/concrete_environment.cc
|
||||||
./src/parse_opts.hh
|
src/backend/concrete_history.cc
|
||||||
./src/graphical_simulation.hh
|
src/backend/concrete_simulation.cc
|
||||||
./src/observer.cc
|
src/backend/cpu_policies_gatekeeper.cc
|
||||||
./src/observer.hh
|
src/backend/cpu_policy.cc
|
||||||
./src/start_gui.cc
|
src/backend/cpu_policy_exception.cc
|
||||||
./src/start_gui.hh
|
src/backend/cpu_policy_manager.cc
|
||||||
./src/main_window.cc
|
src/backend/dynamic_process.cc
|
||||||
./src/main_window.hh
|
src/backend/dynamic_request.cc
|
||||||
./src/main.cc
|
src/backend/dynamic_resource.cc
|
||||||
./src/main.hh
|
src/backend/dynamic_schedulable.cc
|
||||||
./src/io_manager.hh
|
src/backend/dynamic_sub_request.cc
|
||||||
./src/graphical_terminal_io.cc
|
src/backend/dynamic_thread.cc
|
||||||
./src/graphical_terminal_io.hh
|
src/backend/environment.cc
|
||||||
./src/simulation.cc
|
src/backend/global_preferences.cc
|
||||||
./src/simulation.hh
|
src/backend/global_preferences_serializer.cc
|
||||||
./src/backend/observed_subject.cc
|
src/backend/history.cc
|
||||||
./src/backend/observed_subject.hh
|
src/backend/history_observer.cc
|
||||||
./src/backend/schedulable.cc
|
src/backend/holt_graph.cc
|
||||||
./src/backend/schedulable.hh
|
src/backend/invalid_plugin_exception.cc
|
||||||
./src/backend/policy_parameters.cc
|
src/backend/key_file.cc
|
||||||
./src/backend/policy_parameters.hh
|
src/backend/malformed_policy_exception.cc
|
||||||
./src/backend/policy_manager.cc
|
src/backend/module.cc
|
||||||
./src/backend/policy_manager.hh
|
src/backend/null_policy_exception.cc
|
||||||
./src/backend/string_utils.cc
|
src/backend/plugin_manager.cc
|
||||||
./src/backend/string_utils.hh
|
src/backend/policy_parameters.cc
|
||||||
./src/backend/policy.cc
|
src/backend/process.cc
|
||||||
./src/backend/policy.hh
|
src/backend/ready_queue.cc
|
||||||
./src/backend/history.cc
|
src/backend/request.cc
|
||||||
./src/backend/history.hh
|
src/backend/resource.cc
|
||||||
./src/backend/scheduler.cc
|
src/backend/resource_policies_gatekeeper.cc
|
||||||
./src/backend/scheduler.hh
|
src/backend/resource_policy.cc
|
||||||
./src/backend/slice.cc
|
src/backend/resource_policy_manager.cc
|
||||||
./src/backend/slice.hh
|
src/backend/schedulable.cc
|
||||||
./src/backend/schedulable_status.cc
|
src/backend/scheduler.cc
|
||||||
./src/backend/schedulable_status.hh
|
src/backend/serializer.cc
|
||||||
./src/backend/process.cc
|
src/backend/serializer_error.cc
|
||||||
./src/backend/process.hh
|
src/backend/serializers_gatekeeper.cc
|
||||||
./src/backend/schedulable_queue.cc
|
src/backend/serialize_visitor.cc
|
||||||
./src/backend/schedulable_queue.hh
|
src/backend/simulation.cc
|
||||||
./src/standard_io.cc
|
src/backend/static_process.cc
|
||||||
./src/standard_io.hh
|
src/backend/static_request.cc
|
||||||
./src/text_simulation.cc
|
src/backend/static_resource.cc
|
||||||
./src/text_simulation.hh
|
src/backend/static_schedulable.cc
|
||||||
./src/templates/smartp.hh
|
src/backend/static_sub_request.cc
|
||||||
|
src/backend/static_thread.cc
|
||||||
|
src/backend/string_utils.cc
|
||||||
|
src/backend/sub_request.cc
|
||||||
|
src/backend/thread.cc
|
||||||
|
src/backend/user_interrupt_exception.cc
|
||||||
|
src/cairo_elements.cc
|
||||||
|
src/cairo_widget.cc
|
||||||
|
src/graphical_preferences_editor.cc
|
||||||
|
src/gui_builder.cc
|
||||||
|
src/main.cc
|
||||||
|
src/parse_opts.cc
|
||||||
|
src/schedulables_tree_widget.cc
|
||||||
|
src/simulation_widget.cc
|
||||||
|
src/templates/deletor.tcc
|
||||||
|
src/templates/parameter.tcc
|
||||||
|
src/templates/prova.cc
|
||||||
|
src/templates/sequences.tcc
|
||||||
|
src/templates/singleton.tcc
|
||||||
|
src/templates/smartp.tcc
|
||||||
|
src/testsuite/stubs/history.cc
|
||||||
|
src/testsuite/stubs/policy_manager.cc
|
||||||
|
src/testsuite/stubs/prrpolicy.cc
|
||||||
|
src/testsuite/test-global_preferences_serialization.cc
|
||||||
|
src/testsuite/test-history.cc
|
||||||
|
src/testsuite/test-key_file.cc
|
||||||
|
src/testsuite/test-parse_command.cc
|
||||||
|
src/testsuite/test-stepforward.cc
|
||||||
|
src/text_simulation.cc
|
||||||
|
|
710
po/sgpemv2.pot
710
po/sgpemv2.pot
|
@ -8,7 +8,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: matteo@member.fsf.org\n"
|
"Report-Msgid-Bugs-To: matteo@member.fsf.org\n"
|
||||||
"POT-Creation-Date: 2006-06-13 15:23+0200\n"
|
"POT-Creation-Date: 2006-08-18 01:35+0200\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
@ -16,266 +16,542 @@ msgstr ""
|
||||||
"Content-Type: text/plain; charset=CHARSET\n"
|
"Content-Type: text/plain; charset=CHARSET\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
|
||||||
#: src/parse_opts.cc:89
|
#: src/backend/concrete_simulation.cc:180
|
||||||
#, c-format
|
msgid "unable to change policy and to restore the previous: "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/backend/concrete_simulation.cc:186
|
||||||
|
msgid "unable to change policy: "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/backend/string_utils.cc:88 src/backend/string_utils.cc:120
|
||||||
|
msgid "too few or too many tokens"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/backend/string_utils.cc:110
|
||||||
|
msgid "incorrect number format"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/backend/string_utils.cc:142
|
||||||
|
msgid "incorrect boolean"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/graphical_preferences_editor.cc:144
|
||||||
|
#: src/graphical_preferences_editor.cc:173
|
||||||
|
msgid "Select a directory to add"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/gui_builder.cc:137
|
||||||
|
msgid "Filename to open: "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/parse_opts.cc:68
|
||||||
|
msgid "starts the program in command line mode"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/parse_opts.cc:69
|
||||||
|
msgid "adds this directory to the default modules search path"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/parse_opts.cc:70
|
||||||
|
msgid "adds this directory to default plugin search path"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/parse_opts.cc:71
|
||||||
|
msgid "a list of savefiles; only the first will be opened"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/parse_opts.cc:91
|
||||||
msgid ""
|
msgid ""
|
||||||
"[EE] Wrong number of parameters. Please see \n"
|
"SGPEMv2, a graphical simulator for process scheduling in a multitasking "
|
||||||
"%s --help\n"
|
"computer"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/parse_opts.cc:108
|
#: src/parse_opts.cc:136
|
||||||
#, c-format
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"SGPEMv2 is an educational software acting as a process scheduling simulator\n"
|
" [II] To see a list of commands available,\n"
|
||||||
"\n"
|
" [II] please type \"help\" and hit the ENTER key."
|
||||||
"\n"
|
|
||||||
"Usage : sgpemv2 [options] filename\n"
|
|
||||||
"\n"
|
|
||||||
"Options:\n"
|
|
||||||
"\t-h, --help this help you're reading\n"
|
|
||||||
"\t-N, --no-gui starts the program in command line mode\n"
|
|
||||||
"\t-P dir, --policies-dir=dir\n"
|
|
||||||
"\t add this directory to the default modules\n"
|
|
||||||
"\t search path\n"
|
|
||||||
"\t-M dir, --modules-dir=dir\n"
|
|
||||||
"\t add this directory to default plugin\n"
|
|
||||||
"\t search path\n"
|
|
||||||
"\n"
|
|
||||||
"Filename:\n"
|
|
||||||
"\t a valid SGPEMv2 XML file\n"
|
|
||||||
"\t to be opened.\n"
|
|
||||||
"\n"
|
|
||||||
"Long options are available only on GNU systems.\n"
|
|
||||||
"\n"
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/main_window.cc:42
|
#: src/parse_opts.cc:160
|
||||||
msgid "Exit"
|
msgid "Bad invocation: "
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/graphical_terminal_io.cc:46
|
#: src/parse_opts.cc:161
|
||||||
msgid "Textual Simulation Log"
|
msgid "Use the `-?' or `--help' option to see the help"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/graphical_terminal_io.cc:69
|
#: src/text_simulation.cc:108
|
||||||
msgid "Send Command"
|
msgid "ERROR: this command requires at least "
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/backend/scheduler.cc:97
|
#: src/text_simulation.cc:108
|
||||||
|
msgid " arguments\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:114
|
||||||
|
msgid "WARNING: some arguments will be ignored\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:124
|
||||||
msgid ""
|
msgid ""
|
||||||
"\n"
|
"WARNING: Simulation was not recently saved. If you continue some changes to "
|
||||||
"No initial state inserted!!\n"
|
"the simulation might be lost.\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/text_simulation.cc:103
|
#: src/text_simulation.cc:129
|
||||||
msgid ""
|
msgid "Continue? [y/n] "
|
||||||
"\n"
|
|
||||||
"-- RUN COMMAND --\n"
|
|
||||||
"Starts the simulation. It can be continuous or step-by-step depending on the "
|
|
||||||
"mode configured with SetMode (default=continuous).\n"
|
|
||||||
"\n"
|
|
||||||
"The output of RUN is one or more rows each of which represents the state of "
|
|
||||||
"the schedulable entities. It can be RUNNING, READY, BLOCKED, FUTURE or "
|
|
||||||
"TERMINATED.\n"
|
|
||||||
"The row begins with the number of the instant described by the following "
|
|
||||||
"lists of states. The instant 0 represents the INITIAL STATE during which no "
|
|
||||||
"process is running. The scheduler activity begins at instant 1. Each "
|
|
||||||
"schedulable entity is represented by its name followed by its priority "
|
|
||||||
"enclosed between round parenthesis."
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/text_simulation.cc:120
|
#: src/text_simulation.cc:137
|
||||||
msgid ""
|
msgid "n"
|
||||||
"\n"
|
|
||||||
"ERROR: "
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/text_simulation.cc:122
|
#: src/text_simulation.cc:139
|
||||||
msgid ""
|
msgid "y"
|
||||||
"\n"
|
|
||||||
"Simulation is now stopped"
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/text_simulation.cc:131
|
#: src/text_simulation.cc:242
|
||||||
msgid ""
|
msgid "ERROR: Provided value is out of range\n"
|
||||||
"\n"
|
|
||||||
"-- PAUSE COMMAND --\n"
|
|
||||||
"Pauses the simulation. The next call to RUN will restart it."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/text_simulation.cc:141
|
|
||||||
msgid ""
|
|
||||||
"\n"
|
|
||||||
"-- STOP COMMAND --\n"
|
|
||||||
"Stops the simulation. The next call to RUN will bring the simulation to the "
|
|
||||||
"FIRST instant and start it."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/text_simulation.cc:152
|
|
||||||
msgid ""
|
|
||||||
"\n"
|
|
||||||
"-- RESET COMMAND --\n"
|
|
||||||
"Resets the simulation jumping back to the first instant."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/text_simulation.cc:162
|
|
||||||
msgid ""
|
|
||||||
"\n"
|
|
||||||
"-- QUIT COMMAND --\n"
|
|
||||||
"Exits the program."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/text_simulation.cc:165
|
|
||||||
msgid ""
|
|
||||||
"\n"
|
|
||||||
"\n"
|
|
||||||
"*** Thank you for using SGPEM by Sirius Cybernetics Corporation ***\n"
|
|
||||||
"\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/text_simulation.cc:173
|
|
||||||
msgid ""
|
|
||||||
"\n"
|
|
||||||
"-- Do you really want me to explain what HELP means? --\n"
|
|
||||||
" ************** YOU ARE JOKING ME !!! ************\n"
|
|
||||||
"\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/text_simulation.cc:195
|
|
||||||
msgid ""
|
|
||||||
"\n"
|
|
||||||
"-- SetMode COMMAND --\n"
|
|
||||||
"Permits to change the mode of the simulation.\n"
|
|
||||||
"\n"
|
|
||||||
"Sintax: Setmode <param>\n"
|
|
||||||
"\t<param> can take values:\n"
|
|
||||||
"\n"
|
|
||||||
"\t\tCONTINUOUS - when calling RUN the simulation will show an animation "
|
|
||||||
"using the wait-interval set by SETTIMER\n"
|
|
||||||
"\n"
|
|
||||||
"\t\tSTEP - when calling RUN the simulation will show only one step of the "
|
|
||||||
"animation\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/text_simulation.cc:202
|
|
||||||
msgid ""
|
|
||||||
"\n"
|
|
||||||
"ERROR: wrong number of parameters.\n"
|
|
||||||
"Type HELP SETMODE for the description of the sintax"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/text_simulation.cc:211
|
|
||||||
msgid ""
|
|
||||||
"\n"
|
|
||||||
"ERROR: the second parameter can be only CONTINUOUS or STEP"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/text_simulation.cc:219
|
|
||||||
msgid ""
|
|
||||||
"\n"
|
|
||||||
"-- GetMode COMMAND --\n"
|
|
||||||
"Returns\n"
|
|
||||||
"\tCONTINUOUS : if the simulation is shown with an animation\n"
|
|
||||||
"\tSTEP : if if the simulation is shown step-by-step"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/text_simulation.cc:224
|
|
||||||
msgid ""
|
|
||||||
"\n"
|
|
||||||
"CONTINUOUS"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/text_simulation.cc:226
|
|
||||||
msgid ""
|
|
||||||
"\n"
|
|
||||||
"STEP"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/text_simulation.cc:233
|
|
||||||
msgid ""
|
|
||||||
"\n"
|
|
||||||
"-- SetTimer COMMAND --\n"
|
|
||||||
"Permits to change the interval between a step and the following one during a "
|
|
||||||
"continuous animation.\n"
|
|
||||||
"\n"
|
|
||||||
"Sintax: SetTimer <param>\n"
|
|
||||||
"\t<param> must be an integer value > 0 and < 10000.\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/text_simulation.cc:239
|
|
||||||
msgid ""
|
|
||||||
"\n"
|
|
||||||
"ERROR: wrong number of parameters.\n"
|
|
||||||
"Type HELP SETTIMER for the description of the sintax"
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/text_simulation.cc:248
|
#: src/text_simulation.cc:248
|
||||||
msgid ""
|
msgid "ERROR: Please provide a valid numeric value\n"
|
||||||
"\n"
|
|
||||||
"ERROR: the second parameter has a wrong value.\n"
|
|
||||||
"Type HELP SETTIMER for the description of the sintax"
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/text_simulation.cc:256
|
#: src/text_simulation.cc:257
|
||||||
msgid ""
|
msgid "ERROR: This is a mandatory attribute; you MUST provide a valid value!\n"
|
||||||
"\n"
|
|
||||||
"-- GetTimer COMMAND --\n"
|
|
||||||
"Returns the number of milliseconds the simulation in the continuous mode "
|
|
||||||
"waits between a step and the following one"
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/text_simulation.cc:269
|
#: src/text_simulation.cc:293 src/text_simulation.cc:345
|
||||||
msgid ""
|
msgid "ERROR: This is a mandatory atribute; you MUST provide a valid value!\n"
|
||||||
"\n"
|
|
||||||
"-- JumpTo COMMAND --\n"
|
|
||||||
"Permits to jump to a desired instant of the simulation. All states of the "
|
|
||||||
"simulation before <param> will be recalculated and printed out.\n"
|
|
||||||
"\n"
|
|
||||||
"Sintax: JumpTo <param>\n"
|
|
||||||
"\t<param> must be an integer value >= 0"
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/text_simulation.cc:276
|
#: src/text_simulation.cc:339
|
||||||
msgid ""
|
msgid "ERROR: Please provide a valid boolean value ('true' or 'false')\n"
|
||||||
"\n"
|
|
||||||
"ERROR: wrong number of parameters.\n"
|
|
||||||
"Type HELP JUMPTO for the description of the sintax"
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/text_simulation.cc:285
|
#: src/text_simulation.cc:367 src/text_simulation.cc:373
|
||||||
msgid ""
|
#: src/text_simulation.cc:391 src/text_simulation.cc:695
|
||||||
"\n"
|
#: src/text_simulation.cc:1386 src/text_simulation.cc:1423
|
||||||
"ERROR: the second parameter has a wrong value.\n"
|
msgid "ERROR: "
|
||||||
"Type HELP JUMPTO for the description of the sintax"
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/text_simulation.cc:293
|
#: src/text_simulation.cc:369 src/text_simulation.cc:393
|
||||||
msgid ""
|
msgid ""
|
||||||
"\n"
|
"\n"
|
||||||
"-- GetPolicy COMMAND --\n"
|
"Simulation is now stopped\n"
|
||||||
"Returns the name and the description of the current applied policy."
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/text_simulation.cc:303
|
#: src/text_simulation.cc:375
|
||||||
msgid ""
|
msgid ""
|
||||||
"\n"
|
"\n"
|
||||||
"-- GetPolicyAttributes COMMAND --\n"
|
"Simulation is now stopped, and the current policy will be deactivated\n"
|
||||||
"Returns the list of attributes of the current applied policy.\n"
|
|
||||||
"The description of each parameter includes:\n"
|
|
||||||
"\tthe NAME of the marameter with its type\n"
|
|
||||||
"\tits current VALUE\n"
|
|
||||||
"\tits LOWER and UPPER bounds\n"
|
|
||||||
"\twhether the parameter is REQUIRED"
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/text_simulation.cc:365
|
#: src/text_simulation.cc:384
|
||||||
msgid ""
|
msgid "FATAL ERROR: unable to deactivate the policy: "
|
||||||
"\n"
|
|
||||||
"Command not recognized: "
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/text_simulation.cc:367
|
#: src/text_simulation.cc:424
|
||||||
|
msgid "ERROR: No policy actually selected for the simulation\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:430
|
||||||
|
msgid "Please provide a value for each attribute:\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:431
|
||||||
|
msgid ""
|
||||||
|
"Mandatory arguments are marked with an asterisk (*)\n"
|
||||||
|
"\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:433
|
||||||
|
msgid "Integer arguments:\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:453
|
||||||
msgid ""
|
msgid ""
|
||||||
"\n"
|
"\n"
|
||||||
"Typer HELP for a list of avaiable commands."
|
"Floating-point arguments:\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:475
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
"String arguments:\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:507
|
||||||
|
msgid ""
|
||||||
|
"Avaiable commands:\n"
|
||||||
|
"RUN\n"
|
||||||
|
"STOP\n"
|
||||||
|
"PAUSE\n"
|
||||||
|
"CONFIGURE-CPU-POLICY\n"
|
||||||
|
"HELP\n"
|
||||||
|
"GET\n"
|
||||||
|
"SET\n"
|
||||||
|
"SHOW\n"
|
||||||
|
"ADD\n"
|
||||||
|
"REMOVE\n"
|
||||||
|
"SAVE\n"
|
||||||
|
"LOAD\n"
|
||||||
|
"QUIT\n"
|
||||||
|
"\n"
|
||||||
|
"HELP followed by a command name shows help about it.\n"
|
||||||
|
"ex. `HELP RUN` shows help about the command RUN\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:513
|
||||||
|
msgid ""
|
||||||
|
"-- RUN COMMAND --\n"
|
||||||
|
"Starts the simulation. It can be continuous or step-by-step depending on the "
|
||||||
|
"mode configured with SET CONTINUOUS (default=true).\n"
|
||||||
|
"\n"
|
||||||
|
"The output of RUN is a snapshot of the state of the simulation at each "
|
||||||
|
"instant.\n"
|
||||||
|
"The instant 0 represents the initial state, during which no process is "
|
||||||
|
"running. The scheduler activity begins at instant 1.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:522
|
||||||
|
msgid ""
|
||||||
|
"-- STOP COMMAND --\n"
|
||||||
|
"Stops the simulation. The next call to RUN will bring the simulation to the "
|
||||||
|
"first instant and start it.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:525
|
||||||
|
msgid ""
|
||||||
|
"-- PAUSE COMMAND --\n"
|
||||||
|
"Pauses the simulation. The next call to RUN will continue it.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:528
|
||||||
|
msgid ""
|
||||||
|
"-- CONFIGURE-CPU-POLICY COMMAND --\n"
|
||||||
|
"Configure parameters exposed by the cpu policy.\n"
|
||||||
|
"\n"
|
||||||
|
"This is currently the only way to control the behaviour of cpu policies "
|
||||||
|
"without modifying their source code.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:532
|
||||||
|
msgid ""
|
||||||
|
"-- HELP COMMAND --\n"
|
||||||
|
"The help you're reading.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:534
|
||||||
|
msgid ""
|
||||||
|
"-- GET COMMAND --\n"
|
||||||
|
"Syntax: GET <attr_name>\n"
|
||||||
|
"\twhere <attr_name> may be simulation-tick or continuous.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:537
|
||||||
|
msgid ""
|
||||||
|
"-- SET COMMAND --\n"
|
||||||
|
"Syntax: SET <attr_name> [=] <value>\n"
|
||||||
|
"\twhere <attr_name> may be simulation-tick, continuous or cpu-policy.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:540
|
||||||
|
msgid ""
|
||||||
|
"-- SHOW COMMAND --\n"
|
||||||
|
"Displays the name of the entities (if available) and other informations "
|
||||||
|
"prefixed by its numeric identifier.\n"
|
||||||
|
"\n"
|
||||||
|
"Syntax depends from entities being displayed:\n"
|
||||||
|
"`SHOW processes|resources|cpu-policies|resource-policies`\n"
|
||||||
|
"`SHOW threads <process_id>` with <process_id> being the numeric identifier "
|
||||||
|
"of the parent process\n"
|
||||||
|
"`SHOW requests <process_id> <thread_id>` with <thread_id> being the numeric "
|
||||||
|
"identifier of the thread child of process identified by <process_id>\n"
|
||||||
|
"`SHOW subrequests <process_id> <thread_id> <request_id>` where the numeric "
|
||||||
|
"ids follow the same logic of the previous commands\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:551
|
||||||
|
msgid ""
|
||||||
|
"-- ADD COMMAND --\n"
|
||||||
|
"Adds an entity by using a questionary-like approach.\n"
|
||||||
|
"\n"
|
||||||
|
"Syntax depends from entity being added:\n"
|
||||||
|
"`ADD process|resource`\n"
|
||||||
|
"`ADD thread <process_id>` with <process_id> being the numeric identifier of "
|
||||||
|
"the parent process\n"
|
||||||
|
"`ADD request <process_id> <thread_id>` with <thread_id> being the numeric "
|
||||||
|
"identifier of the thread child of process identified by <process_id>\n"
|
||||||
|
"`ADD subrequest <process_id> <thread_id> <request_id>` where the numeric ids "
|
||||||
|
"follow the same logic of the previous commands\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:561
|
||||||
|
msgid ""
|
||||||
|
"-- REMOVE COMMAND --\n"
|
||||||
|
"Removes an entity.\n"
|
||||||
|
"\n"
|
||||||
|
"Syntax depends from entity being removed:\n"
|
||||||
|
"`REMOVE process|resource <id>` where <id> is the process or resource "
|
||||||
|
"identifier\n"
|
||||||
|
"`REMOVE thread <process_id> <thread_id>` with <process_id> being the "
|
||||||
|
"identifier of the parent process, and <thread_id> the id of the thread to be "
|
||||||
|
"removed\n"
|
||||||
|
"`REMOVE request <process_id> <thread_id> <request_id>` where the numeric ids "
|
||||||
|
"follow the same logic of the previous commands\n"
|
||||||
|
"`REMOVE subrequest <process_id> <thread_id> <request_id> <subrequest_id>` "
|
||||||
|
"where the numeric ids follow the same logic of the previous commands\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:571
|
||||||
|
msgid ""
|
||||||
|
"-- SAVE COMMAND --\n"
|
||||||
|
"Saves the simulation.\n"
|
||||||
|
"\n"
|
||||||
|
"Syntax: SAVE <filename>\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:574
|
||||||
|
msgid ""
|
||||||
|
"-- LOAD COMMAND --\n"
|
||||||
|
"Loads the simulation.\n"
|
||||||
|
"\n"
|
||||||
|
"Syntax: LOAD <filename>\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:577
|
||||||
|
msgid ""
|
||||||
|
"-- QUIT COMMAND --\n"
|
||||||
|
"Gently closes the program.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:579
|
||||||
|
msgid "ERROR: Sorry, no help available for this command.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:590
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
"Bye.\n"
|
||||||
|
"\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:617
|
||||||
|
msgid ""
|
||||||
|
"ERROR: invalid attribute name. Accepted are: simulation-tick, continuous\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:652
|
||||||
|
msgid "ERROR: you must provide a valid unsigned integer value\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:691
|
||||||
|
msgid "ERROR: invalid unsigned integer or not a valid policy index\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:711
|
||||||
|
msgid "ERROR: you must provide a valid boolean value ('true' or 'false')\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:715
|
||||||
|
msgid ""
|
||||||
|
"ERROR: invalid attribute name. Accepted are: simulation-tick, cpu-policy, "
|
||||||
|
"continuous\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:746 src/text_simulation.cc:947
|
||||||
|
#: src/text_simulation.cc:1163
|
||||||
|
msgid "ERROR: invalid argument\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:793
|
||||||
|
msgid "ERROR: provided process identifier is not a valid integer\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:798
|
||||||
|
msgid "ERROR: this process identifier does not belong to an existing process\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:829 src/text_simulation.cc:867
|
||||||
|
#: src/text_simulation.cc:1009 src/text_simulation.cc:1058
|
||||||
|
#: src/text_simulation.cc:1104 src/text_simulation.cc:1187
|
||||||
|
#: src/text_simulation.cc:1224 src/text_simulation.cc:1260
|
||||||
|
#: src/text_simulation.cc:1300 src/text_simulation.cc:1343
|
||||||
|
msgid "ERROR: provided identifier(s) not a valid integer\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:834 src/text_simulation.cc:872
|
||||||
|
#: src/text_simulation.cc:1014 src/text_simulation.cc:1063
|
||||||
|
#: src/text_simulation.cc:1109 src/text_simulation.cc:1192
|
||||||
|
#: src/text_simulation.cc:1229 src/text_simulation.cc:1265
|
||||||
|
#: src/text_simulation.cc:1305 src/text_simulation.cc:1348
|
||||||
|
msgid "ERROR: the identifier(s) do not belong to an existing entity\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:912
|
||||||
|
msgid "FIXME: Not implemented\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:927
|
||||||
|
msgid "WARNING: Simulation is not stopped, it will be automatically stopped\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:957 src/text_simulation.cc:975
|
||||||
|
#: src/text_simulation.cc:1018
|
||||||
|
msgid "name"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:958 src/text_simulation.cc:1020
|
||||||
|
msgid "arrival time"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:959 src/text_simulation.cc:1650
|
||||||
|
msgid "priority"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:976
|
||||||
|
msgid "pre-emptable?"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:977
|
||||||
|
msgid "places"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:978
|
||||||
|
msgid "availability"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:1019
|
||||||
|
msgid "cpu time"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:1021
|
||||||
|
msgid "base priority"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:1067
|
||||||
|
msgid "instant"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:1113
|
||||||
|
msgid "resource key"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:1114
|
||||||
|
msgid "duration"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:1123
|
||||||
|
msgid "ERROR: invalid resource identifier\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:1145
|
||||||
|
msgid "WARNING: Simulation is not stopped, it will be automatically stopped"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:1220
|
||||||
|
msgid "invalid resource id"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:1382 src/text_simulation.cc:1419
|
||||||
|
msgid "ERROR: No registered serializer available\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:1489
|
||||||
|
msgid "ERROR: command not supported\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:1507
|
||||||
|
msgid "RUNNING @"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:1510
|
||||||
|
msgid "READY"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:1513
|
||||||
|
msgid "BLOCKED"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:1516 src/text_simulation.cc:1540
|
||||||
|
msgid "FUTURE"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:1519
|
||||||
|
msgid "TERMINATED"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:1534
|
||||||
|
msgid "UNALLOCABLE"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:1537
|
||||||
|
msgid "ALLOCATED"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:1543
|
||||||
|
msgid "EXHAUSTED"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:1546
|
||||||
|
msgid "ALLOCABLE"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:1573
|
||||||
|
msgid "READY QUEUE: { "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:1581
|
||||||
|
msgid " ~ "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:1584
|
||||||
|
msgid "}"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:1598
|
||||||
|
msgid "RESOURCES:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:1604
|
||||||
|
msgid ", with "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:1605
|
||||||
|
msgid " places"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:1610
|
||||||
|
msgid "queue: { "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:1626
|
||||||
|
msgid " }"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:1644
|
||||||
|
msgid "PROCESSES:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:1646
|
||||||
|
msgid "state"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:1647
|
||||||
|
msgid "arrival"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:1648
|
||||||
|
msgid "requiring"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:1649
|
||||||
|
msgid "elapsed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/text_simulation.cc:1651
|
||||||
|
msgid "resource_id"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
|
@ -60,7 +60,7 @@ ConcreteEnvironment::ConcreteEnvironment(const ConcreteEnvironment& ce) :
|
||||||
{
|
{
|
||||||
const Processes& ce_proc = ce._processes;
|
const Processes& ce_proc = ce._processes;
|
||||||
insert_iterator<Processes> dest(_processes, _processes.begin());
|
insert_iterator<Processes> dest(_processes, _processes.begin());
|
||||||
for (Iseq<Processes::const_iterator> orig = iseq(ce_proc); orig; orig++)
|
for (Iseq<Processes::const_iterator> orig = const_iseq(ce_proc); orig; orig++)
|
||||||
*dest++ = new DynamicProcess(dynamic_cast<const DynamicProcess&>(**orig));
|
*dest++ = new DynamicProcess(dynamic_cast<const DynamicProcess&>(**orig));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,14 +24,20 @@
|
||||||
#include "serialize_visitor.hh"
|
#include "serialize_visitor.hh"
|
||||||
|
|
||||||
#include "deletor.tcc"
|
#include "deletor.tcc"
|
||||||
|
#include "sequences.tcc"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <iostream>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
using namespace sgpem;
|
using namespace sgpem;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
typedef std::vector<DynamicThread*>::const_iterator ConstThreadIt;
|
||||||
|
typedef std::vector<DynamicThread*>::iterator ThreadIt;
|
||||||
|
|
||||||
|
|
||||||
DynamicProcess::DynamicProcess(StaticProcess* core) :
|
DynamicProcess::DynamicProcess(StaticProcess* core) :
|
||||||
DynamicSchedulable(), _core(core)
|
DynamicSchedulable(), _core(core)
|
||||||
{
|
{
|
||||||
|
@ -41,13 +47,9 @@ DynamicProcess::DynamicProcess(StaticProcess* core) :
|
||||||
DynamicProcess::DynamicProcess(const DynamicProcess &other) :
|
DynamicProcess::DynamicProcess(const DynamicProcess &other) :
|
||||||
Schedulable(), DynamicSchedulable(other), Process(),
|
Schedulable(), DynamicSchedulable(other), Process(),
|
||||||
_core(other._core)
|
_core(other._core)
|
||||||
{
|
{
|
||||||
typedef vector<DynamicThread*>::const_iterator ThreadIt;
|
for (Iseq<ConstThreadIt> seq = const_iseq(other._dynamic_threads); seq; ++seq)
|
||||||
|
new DynamicThread(*(*seq), this);
|
||||||
const vector<DynamicThread*>& other_threads = other._dynamic_threads;
|
|
||||||
|
|
||||||
for (ThreadIt it = other_threads.begin(); it != other_threads.end(); ++it)
|
|
||||||
new DynamicThread(*(*it), this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DynamicProcess::~DynamicProcess()
|
DynamicProcess::~DynamicProcess()
|
||||||
|
@ -71,101 +73,36 @@ DynamicProcess::get_threads() const
|
||||||
Schedulable::state
|
Schedulable::state
|
||||||
DynamicProcess::get_state() const
|
DynamicProcess::get_state() const
|
||||||
{
|
{
|
||||||
int total = _dynamic_threads.size();
|
|
||||||
int running = 0;
|
|
||||||
int ready = 0;
|
|
||||||
int blocked = 0;
|
|
||||||
int terminated = 0;
|
|
||||||
int future = 0;
|
|
||||||
|
|
||||||
unsigned int closest = 0;
|
|
||||||
|
|
||||||
vector<DynamicThread*>::const_iterator it = _dynamic_threads.begin();
|
|
||||||
for (; it != _dynamic_threads.end(); it++)
|
|
||||||
{
|
|
||||||
if ((**it).get_state() == state_running) running++;
|
|
||||||
if ((**it).get_state() == state_ready) ready++;
|
|
||||||
if ((**it).get_state() == state_blocked) blocked++;
|
|
||||||
if ((**it).get_state() == state_terminated) terminated++;
|
|
||||||
if ((**it).get_state() == state_future)
|
|
||||||
{
|
|
||||||
unsigned int arrival = (**it).get_arrival_time();
|
|
||||||
// if this is the first future occurrence, record its arrival;
|
|
||||||
// else record its arrival if and only if it is smaller then the recorded one
|
|
||||||
if (future == 0)
|
|
||||||
closest = arrival;
|
|
||||||
else
|
|
||||||
closest = (closest < arrival) ? closest : arrival;
|
|
||||||
future++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(total > 0);
|
|
||||||
assert(running == 1 || running == 0);
|
|
||||||
assert(running + ready + blocked + terminated + future == total);
|
|
||||||
|
|
||||||
if (running > 0)
|
|
||||||
return state_running;
|
|
||||||
if (ready > 0) // running == 0
|
|
||||||
return state_ready;
|
|
||||||
if (blocked > 0) // running == 0 && ready == 0
|
|
||||||
return state_blocked;
|
|
||||||
// Now check if a "hole" happens: if all threads are terminated
|
|
||||||
// or blocked the next
|
|
||||||
// thread to start, e.g. the one with the least arrival_time, has
|
|
||||||
// start time greater than the current process elapsed time, then
|
|
||||||
// pass from state_future to state_terminated:
|
|
||||||
if (closest > get_elapsed_time())
|
|
||||||
return state_terminated;
|
|
||||||
if (terminated > 0) // running == 0 && ready == 0 && blocked == 0
|
|
||||||
return state_terminated;
|
|
||||||
if (future > 0) // running == 0 && ready == 0 && blocked == 0 && terminated == 0
|
|
||||||
return state_future;
|
|
||||||
|
|
||||||
// I'm not sure if we can get here (maybe if there are no threads?),
|
|
||||||
// but I don't like this compiler warning: 'control reaches end of non-void function'
|
|
||||||
return state_future;
|
|
||||||
|
|
||||||
// Since premature optimization is the root of all evil, and the
|
|
||||||
// following code was very fast but also very wrong, the coder
|
|
||||||
// will be punished by allowing her to code in C++ just after
|
|
||||||
// having passed "Algoritmi 3" exam with full marks.
|
|
||||||
|
|
||||||
/*
|
|
||||||
typedef vector<DynamicThread*>::const_iterator ThreadIt;
|
|
||||||
static const int uninitialized = -1;
|
static const int uninitialized = -1;
|
||||||
|
|
||||||
assert(_dynamic_threads.size() > 0);
|
state result = state_terminated;
|
||||||
|
|
||||||
state result = state_future;
|
|
||||||
int next_thread_starts_at = uninitialized;
|
int next_thread_starts_at = uninitialized;
|
||||||
|
|
||||||
for(ThreadIt it = _dynamic_threads.begin(); it != _dynamic_threads.end(); ++it)
|
// This is the logic behind the code:
|
||||||
|
// If there is at least one running thread, the result is
|
||||||
|
// running. If not, it may be either blocked, ready, future or terminated.
|
||||||
|
|
||||||
|
// We have these cases (a state takes precedence over some other one):
|
||||||
|
// (a) if a thread is running, return immediately state_running
|
||||||
|
// (b) if a thread is ready, puts unconditionally result as state_ready,
|
||||||
|
// and continue iterating (to see if there's a running thread)
|
||||||
|
// (c) if a thread is blocked, and result is not state_ready, result
|
||||||
|
// becomes state_blocked, and continue iterating (to see if there are
|
||||||
|
// ready or running threads)
|
||||||
|
// (d) if a thread is future, and result is not state_ready or
|
||||||
|
// state_blocked, put result as state_future, and remember
|
||||||
|
// when the next thread will start (d1) (see at the end of this
|
||||||
|
// method for the rationale (d2)). Then continue iterating.
|
||||||
|
// (e) else (if all threads are state_terminated) put result as
|
||||||
|
// state_terminated.
|
||||||
|
|
||||||
|
|
||||||
|
for(Iseq<ConstThreadIt> seq = const_iseq(_dynamic_threads); seq; ++seq)
|
||||||
{
|
{
|
||||||
state thread_state = (*it)->get_state();
|
state thread_state = (*seq)->get_state();
|
||||||
|
|
||||||
// This is the logic behind the code:
|
|
||||||
// If there is at least one running thread, the result is
|
|
||||||
// running. If not, it may be either blocked, ready, future or terminated.
|
|
||||||
|
|
||||||
// We have these cases (a state takes precedence over some other one):
|
|
||||||
// (a) if a thread is running, return immediately state_running
|
|
||||||
// (b) if a thread is ready, puts unconditionally result as state_ready,
|
|
||||||
// and continue iterating (to see if there's a running thread)
|
|
||||||
// (c) if a thread is blocked, and result is not state_ready, result
|
|
||||||
// becomes state_blocked, and continue iterating (to see if there are
|
|
||||||
// ready or running threads)
|
|
||||||
// (d) if a thread is future, and result is not state_ready or
|
|
||||||
// state_blocked, put result as state_future, and remember
|
|
||||||
// when the next thread will start (d1) (see at the end of this
|
|
||||||
// method for the rationale (d2)). Then continue iterating.
|
|
||||||
// (e) else (if all threads are state_terminated) put result as
|
|
||||||
// state_terminated.
|
|
||||||
|
|
||||||
// TODO Is this OK? Must be tested...
|
// TODO Is this OK? Must be tested...
|
||||||
|
|
||||||
|
|
||||||
int thread_starts_at;
|
|
||||||
switch(thread_state)
|
switch(thread_state)
|
||||||
{
|
{
|
||||||
case state_running: // (a)
|
case state_running: // (a)
|
||||||
|
@ -174,23 +111,34 @@ DynamicProcess::get_state() const
|
||||||
result = state_ready;
|
result = state_ready;
|
||||||
continue;
|
continue;
|
||||||
case state_blocked: // (c)
|
case state_blocked: // (c)
|
||||||
result = state_blocked;
|
if((result & state_ready) == 0)
|
||||||
|
result = state_blocked;
|
||||||
continue;
|
continue;
|
||||||
case state_future: // (d)
|
case state_future: // (d)
|
||||||
result = state_future;
|
if((result & (state_ready|state_blocked)) == 0)
|
||||||
thread_starts_at = (*it)->get_arrival_time();
|
{
|
||||||
if(next_thread_starts_at == uninitialized) // (d1)
|
result = state_future;
|
||||||
next_thread_starts_at = thread_starts_at;
|
int thread_starts_at = (*seq)->get_arrival_time();
|
||||||
else
|
if(next_thread_starts_at == uninitialized) // (d1)
|
||||||
next_thread_starts_at = std::min(thread_starts_at, next_thread_starts_at);
|
next_thread_starts_at = thread_starts_at;
|
||||||
|
else
|
||||||
|
next_thread_starts_at = std::min(thread_starts_at, next_thread_starts_at);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
case state_terminated: // (e)
|
||||||
|
// already put into terminated state as the default value
|
||||||
continue;
|
continue;
|
||||||
default: // (e)
|
|
||||||
result = state_terminated;
|
|
||||||
}
|
}
|
||||||
} //~ "for" iterating over threads
|
} //~ "for" iterating over threads
|
||||||
|
|
||||||
// reused hole checking system
|
// (d2) Now check if a "hole" happens: if all other threads are terminated
|
||||||
*/
|
// the next thread to start, e.g. the one with the least arrival_time,
|
||||||
|
// has start time greater than the current process elapsed time, then
|
||||||
|
// pass from state_future to state_terminated:
|
||||||
|
if (result == state_future && next_thread_starts_at > static_cast<int>(get_elapsed_time()))
|
||||||
|
return state_terminated;
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -225,10 +173,9 @@ unsigned int
|
||||||
DynamicProcess::get_elapsed_time() const
|
DynamicProcess::get_elapsed_time() const
|
||||||
{
|
{
|
||||||
unsigned int result = 0;
|
unsigned int result = 0;
|
||||||
for (std::vector<DynamicThread*>::const_iterator it = _dynamic_threads.begin();
|
for (Iseq<ConstThreadIt> seq = const_iseq(_dynamic_threads); seq; ++seq)
|
||||||
it != _dynamic_threads.end(); it++)
|
|
||||||
{
|
{
|
||||||
result += (*it)->get_elapsed_time();
|
result += (*seq)->get_elapsed_time();
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -237,10 +184,9 @@ int
|
||||||
DynamicProcess::get_last_acquisition() const
|
DynamicProcess::get_last_acquisition() const
|
||||||
{
|
{
|
||||||
int result = -1;
|
int result = -1;
|
||||||
for (std::vector<DynamicThread*>::const_iterator it = _dynamic_threads.begin();
|
for (Iseq<ConstThreadIt> seq = const_iseq(_dynamic_threads); seq; ++seq)
|
||||||
it != _dynamic_threads.end(); it++)
|
|
||||||
{
|
{
|
||||||
int acq = (*it)->get_last_acquisition();
|
int acq = (*seq)->get_last_acquisition();
|
||||||
if (result < acq)
|
if (result < acq)
|
||||||
result = acq;
|
result = acq;
|
||||||
}
|
}
|
||||||
|
@ -251,10 +197,9 @@ int
|
||||||
DynamicProcess::get_last_release() const
|
DynamicProcess::get_last_release() const
|
||||||
{
|
{
|
||||||
int result = -1;
|
int result = -1;
|
||||||
for (std::vector<DynamicThread*>::const_iterator it = _dynamic_threads.begin();
|
for (Iseq<ConstThreadIt> seq = const_iseq(_dynamic_threads); seq; ++seq)
|
||||||
it != _dynamic_threads.end(); it++)
|
|
||||||
{
|
{
|
||||||
int acq = (*it)->get_last_release();
|
int acq = (*seq)->get_last_release();
|
||||||
if (result < acq)
|
if (result < acq)
|
||||||
result = acq;
|
result = acq;
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -28,7 +28,7 @@ namespace sgpem
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include "concrete_history.hh"
|
#include "history.hh"
|
||||||
#include "cpu_policy.hh"
|
#include "cpu_policy.hh"
|
||||||
#include "ready_queue.hh"
|
#include "ready_queue.hh"
|
||||||
#include "user_interrupt_exception.hh"
|
#include "user_interrupt_exception.hh"
|
||||||
|
@ -59,18 +59,6 @@ namespace sgpem
|
||||||
{
|
{
|
||||||
friend class Singleton<Scheduler>;
|
friend class Singleton<Scheduler>;
|
||||||
public:
|
public:
|
||||||
/**
|
|
||||||
Returns a pointer to the queue containing all the ready
|
|
||||||
schedulable objects (for the policy to sort it).
|
|
||||||
\return a pointer to the queue containing all the ready
|
|
||||||
schedulable objects (for the policy to sort it).
|
|
||||||
*/
|
|
||||||
ReadyQueue* get_ready_queue();
|
|
||||||
/**
|
|
||||||
Resets the simulation to the initial state.
|
|
||||||
Deprecated.
|
|
||||||
*/
|
|
||||||
// void reset_status();
|
|
||||||
/**
|
/**
|
||||||
Generates a new ReadyQueue representing the status of the processes
|
Generates a new ReadyQueue representing the status of the processes
|
||||||
at the simulation instant next to the current one, and extends the History by
|
at the simulation instant next to the current one, and extends the History by
|
||||||
|
@ -79,19 +67,32 @@ namespace sgpem
|
||||||
|
|
||||||
\return false If the simulation has ended, true otherwise
|
\return false If the simulation has ended, true otherwise
|
||||||
*/
|
*/
|
||||||
bool step_forward(ConcreteHistory& history, CPUPolicy& cpu_policy) throw(UserInterruptException, MalformedPolicyException);
|
bool step_forward(History& history, CPUPolicy& cpu_policy) throw(UserInterruptException, MalformedPolicyException);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns the policy that will be used to generate the simulation at the next instant.
|
\brief Returns the policy that will be used to generate the simulation at the next instant.
|
||||||
\return the policy that will be used to generate the simulation at the next instant.
|
|
||||||
|
\warning This is a callback method: it can only be used in methods of CPUPolicy called
|
||||||
|
by step_forward(). Else, a NULL pointer will be returned.
|
||||||
|
\return A pointer to the active policy, or NULL if not inside step_forward()
|
||||||
*/
|
*/
|
||||||
CPUPolicy* get_policy();
|
CPUPolicy* get_policy();
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Returns a pointer to the queue containing all the ready
|
||||||
|
schedulable objects (for the policy to sort it).
|
||||||
|
|
||||||
|
\warning This is a callback method: it can only be used in methods of CPUPolicy called
|
||||||
|
by step_forward(). Else, a NULL pointer will be returned.
|
||||||
|
\return A pointer to the queue, or NULL if not inside step_forward()
|
||||||
|
*/
|
||||||
|
ReadyQueue* get_ready_queue();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Scheduler(); //private constructor.
|
Scheduler(); //private constructor.
|
||||||
|
|
||||||
ReadyQueue* _ready_queue;
|
ReadyQueue* _ready_queue;
|
||||||
CPUPolicy* _policy;
|
CPUPolicy* _policy;
|
||||||
|
|
||||||
Glib::Mutex _step_mutex;
|
Glib::Mutex _step_mutex;
|
||||||
};
|
};
|
||||||
|
|
|
@ -51,6 +51,18 @@ public:
|
||||||
|
|
||||||
const In& operator->() const
|
const In& operator->() const
|
||||||
{ return Iseq::first; }
|
{ return Iseq::first; }
|
||||||
|
|
||||||
|
bool operator==(const Iseq& i) const
|
||||||
|
{ return Iseq::first == i.first; }
|
||||||
|
|
||||||
|
bool operator!=(const Iseq& i) const
|
||||||
|
{ return Iseq::first != i.first; }
|
||||||
|
|
||||||
|
// bool operator==(const In& i) const
|
||||||
|
// { return Iseq::first == i; }
|
||||||
|
|
||||||
|
// bool operator!=(const In& i) const
|
||||||
|
// { return Iseq::first != i; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -59,7 +71,7 @@ public:
|
||||||
|
|
||||||
template<class Container>
|
template<class Container>
|
||||||
Iseq<typename Container::const_iterator>
|
Iseq<typename Container::const_iterator>
|
||||||
iseq(const Container& c)
|
const_iseq(const Container& c)
|
||||||
{
|
{
|
||||||
return Iseq<typename Container::const_iterator>(c.begin(), c.end());
|
return Iseq<typename Container::const_iterator>(c.begin(), c.end());
|
||||||
}
|
}
|
||||||
|
@ -77,7 +89,7 @@ iseq(Container& c)
|
||||||
|
|
||||||
template<class Container>
|
template<class Container>
|
||||||
Iseq<typename Container::const_reverse_iterator>
|
Iseq<typename Container::const_reverse_iterator>
|
||||||
r_iseq(const Container& c)
|
const_riseq(const Container& c)
|
||||||
{
|
{
|
||||||
return Iseq<typename Container::const_reverse_iterator>(c.rbegin(), c.rend());
|
return Iseq<typename Container::const_reverse_iterator>(c.rbegin(), c.rend());
|
||||||
}
|
}
|
||||||
|
@ -85,7 +97,7 @@ r_iseq(const Container& c)
|
||||||
|
|
||||||
template<class Container>
|
template<class Container>
|
||||||
Iseq<typename Container::reverse_iterator>
|
Iseq<typename Container::reverse_iterator>
|
||||||
r_iseq(Container& c)
|
riseq(Container& c)
|
||||||
{
|
{
|
||||||
return Iseq<typename Container::reverse_iterator>(c.rbegin(), c.rend());
|
return Iseq<typename Container::reverse_iterator>(c.rbegin(), c.rend());
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,12 @@ add subrequest 1 1 1
|
||||||
1
|
1
|
||||||
4
|
4
|
||||||
|
|
||||||
|
add request 1 1
|
||||||
|
2
|
||||||
|
add subrequest 1 1 2
|
||||||
|
1
|
||||||
|
3
|
||||||
|
|
||||||
add request 1 2
|
add request 1 2
|
||||||
0
|
0
|
||||||
add subrequest 1 2 1
|
add subrequest 1 2 1
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
set cpu-policy 2
|
||||||
|
|
||||||
|
configure-cpu-policy
|
||||||
|
0
|
||||||
|
1
|
||||||
|
|
||||||
|
add resource
|
||||||
|
scythe
|
||||||
|
false
|
||||||
|
1
|
||||||
|
0
|
||||||
|
add resource
|
||||||
|
sword
|
||||||
|
false
|
||||||
|
1
|
||||||
|
0
|
||||||
|
|
||||||
|
|
||||||
|
add process
|
||||||
|
Antrophomorphic personification
|
||||||
|
0
|
||||||
|
0
|
||||||
|
|
||||||
|
add thread 1
|
||||||
|
Death
|
||||||
|
4
|
||||||
|
0
|
||||||
|
0
|
||||||
|
add thread 1
|
||||||
|
Susan Sto Helit
|
||||||
|
4
|
||||||
|
0
|
||||||
|
0
|
||||||
|
|
||||||
|
add request 1 1
|
||||||
|
0
|
||||||
|
add subrequest 1 1 1
|
||||||
|
0
|
||||||
|
2
|
||||||
|
|
||||||
|
add request 1 1
|
||||||
|
1
|
||||||
|
add subrequest 1 1 2
|
||||||
|
1
|
||||||
|
2
|
||||||
|
|
||||||
|
add request 1 2
|
||||||
|
0
|
||||||
|
add subrequest 1 2 1
|
||||||
|
1
|
||||||
|
2
|
||||||
|
|
||||||
|
add request 1 2
|
||||||
|
1
|
||||||
|
add subrequest 1 2 2
|
||||||
|
0
|
||||||
|
2
|
||||||
|
|
||||||
|
run
|
|
@ -0,0 +1,88 @@
|
||||||
|
# Shows a problem up to revision 893, fixed(?) in 894.
|
||||||
|
|
||||||
|
# Look out for Mandingo: while it (he?) blocks at
|
||||||
|
# a certain point, he could immediately run,
|
||||||
|
# having higher priority than Peter North. Instead
|
||||||
|
# Peter continues his great fuck with Jenna, although
|
||||||
|
# he should pre-empt, because Rocco comes before
|
||||||
|
# Mandingo in the Jenna allocation queue.
|
||||||
|
|
||||||
|
# We can both assume: a) this is good as it is:
|
||||||
|
# since Rocco requested Jenna before Mandingo, he's
|
||||||
|
# his due right to mutilate her pussy for first; or b)
|
||||||
|
# this is wrong, because it lets a lower priority
|
||||||
|
# thread to run instead of a thread with higher
|
||||||
|
# priority that could use the other Jenna's hole
|
||||||
|
# while it's free (admittedly, Jenna Jameson as a
|
||||||
|
# resource should have at least four or five places,
|
||||||
|
# but for the sake of semplicity of this example
|
||||||
|
# we assumed that mouth, earholes and navel don't
|
||||||
|
# count).
|
||||||
|
|
||||||
|
# TO SEE THIS PROBLEM CLEARLY, look with
|
||||||
|
# attention at the resource queue at instant 2
|
||||||
|
|
||||||
|
# Use round robin with preemption by
|
||||||
|
# priority and a time slice of 1
|
||||||
|
set cpu-policy 2
|
||||||
|
configure-cpu-policy
|
||||||
|
1
|
||||||
|
1
|
||||||
|
|
||||||
|
add resource
|
||||||
|
Jenna Jameson
|
||||||
|
false
|
||||||
|
2
|
||||||
|
0
|
||||||
|
|
||||||
|
add process
|
||||||
|
"Wet Dreams IV"
|
||||||
|
0
|
||||||
|
0
|
||||||
|
|
||||||
|
add thread 1
|
||||||
|
Peter North
|
||||||
|
3
|
||||||
|
0
|
||||||
|
10
|
||||||
|
|
||||||
|
add request 1 1
|
||||||
|
0
|
||||||
|
add subrequest 1 1 1
|
||||||
|
0
|
||||||
|
3
|
||||||
|
|
||||||
|
|
||||||
|
add process
|
||||||
|
"A Night With Jenna"
|
||||||
|
2
|
||||||
|
0
|
||||||
|
|
||||||
|
add thread 2
|
||||||
|
Rocco Siffredi
|
||||||
|
3
|
||||||
|
0
|
||||||
|
0
|
||||||
|
|
||||||
|
add thread 2
|
||||||
|
Mandingo
|
||||||
|
3
|
||||||
|
0
|
||||||
|
5
|
||||||
|
|
||||||
|
add request 2 1
|
||||||
|
0
|
||||||
|
add subrequest 2 1 1
|
||||||
|
0
|
||||||
|
3
|
||||||
|
add subrequest 2 1 1
|
||||||
|
0
|
||||||
|
3
|
||||||
|
|
||||||
|
add request 2 2
|
||||||
|
0
|
||||||
|
add subrequest 2 2 1
|
||||||
|
0
|
||||||
|
3
|
||||||
|
|
||||||
|
run
|
|
@ -0,0 +1,43 @@
|
||||||
|
set cpu-policy 2
|
||||||
|
|
||||||
|
configure-cpu-policy
|
||||||
|
0
|
||||||
|
1
|
||||||
|
|
||||||
|
add resource
|
||||||
|
banana
|
||||||
|
false
|
||||||
|
1
|
||||||
|
0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
add process
|
||||||
|
Unseen University
|
||||||
|
0
|
||||||
|
0
|
||||||
|
|
||||||
|
add thread 1
|
||||||
|
The Librarian
|
||||||
|
4
|
||||||
|
0
|
||||||
|
0
|
||||||
|
add thread 1
|
||||||
|
Rincewind
|
||||||
|
2
|
||||||
|
0
|
||||||
|
0
|
||||||
|
|
||||||
|
add request 1 1
|
||||||
|
0
|
||||||
|
add subrequest 1 1 1
|
||||||
|
0
|
||||||
|
3
|
||||||
|
|
||||||
|
add request 1 2
|
||||||
|
1
|
||||||
|
add subrequest 1 2 1
|
||||||
|
0
|
||||||
|
2
|
||||||
|
|
||||||
|
run
|
|
@ -1471,8 +1471,16 @@ TextSimulation::parse_command(TextSimulation& sim, const ustring& str)
|
||||||
|
|
||||||
Tokens arguments = tokenize(str);
|
Tokens arguments = tokenize(str);
|
||||||
|
|
||||||
|
// Ignore empty lines
|
||||||
if (arguments.size() == 0)
|
if (arguments.size() == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Allow also comments into batch scripts (w/ echo):
|
||||||
|
if(arguments[0].at(0) == '#')
|
||||||
|
{
|
||||||
|
cout << str;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ustring key = arguments[0].uppercase();
|
ustring key = arguments[0].uppercase();
|
||||||
|
|
||||||
|
@ -1698,7 +1706,7 @@ TextSimulation::update(const History& changed_history)
|
||||||
oss << setw(fill1) << r.get_instant();
|
oss << setw(fill1) << r.get_instant();
|
||||||
oss << setw(fill1) << sr.get_length();
|
oss << setw(fill1) << sr.get_length();
|
||||||
oss << setw(fill1) << sr.get_length() - sr.get_remaining_time();
|
oss << setw(fill1) << sr.get_length() - sr.get_remaining_time();
|
||||||
oss << setw(fill1) << sr.get_resource_key();
|
oss << setw(fill1*2) << sr.get_resource_key();
|
||||||
oss << endl;
|
oss << endl;
|
||||||
|
|
||||||
p_stdout(oss.str());
|
p_stdout(oss.str());
|
||||||
|
|
Loading…
Reference in New Issue