%% Task Scheduling in an Operating System

% Copyright 2008-2011 The MathWorks, Inc.

%% Description
% This example shows how to use dependent tasks to model and prioritize 
% the time-critical and non-time-critical parts of a process.
%
% Task tokens with two priority levels are generated by the two token
% generators on the left side of the model. The tokens are ordered in
% ascending priority in the Priority-Based Task Queue just before the CPU.
% The tokens are then passed to the CPU for task execution.
%
% A task dependent on the completion of the high-priority task is modeled
% using the combination of the Entity Departure Event to Function-Call
% Event block and the Event-Based Entity Generator block. This allows the
% time-critical part of a process to be performed by a high-priority task.
% The remaining non-time-critical part is performed by a low-priority task,
% which is scheduled as a dependent task. The dependent task tokens are
% processed through the same task queue as the independent tasks.

modelname = 'sedemo_rtos_dependent_tasks';
open_system(modelname);
set_param([modelname '/Task Queue Length'],'OpenScopeAtSimStart', 'off' );
set_param([modelname '/Plots and  function-call for  dependent tasks/Signal Scope'],'OpenScopeAtSimStart', 'off' );
set_param([modelname '/Plots and  function-call for  dependent tasks/Low Priority Token Count'],'OpenScopeAtSimStart', 'off' );
set_param([modelname '/Plots and  function-call for  dependent tasks/Dependent Token Count'],'OpenScopeAtSimStart', 'off' );

%% Results and Displays
% The simulation results can be seen on the following scopes:
%
% *  Priority value of the task being executed in the CPU. This plot
%    indicates when a high-priority task (priority 1) preempts a
%    low-priority task (priority 2) and when a low-priority task preempts a
%    dependent task (priority 3).

sim(modelname);

%%
%
% *  Length of the Priority-Based Task Queue. The queue length increases at
%    times when the high-priority task is completed because the completion
%    causes generation of a new dependent task.
%

des.scope.CallbackSupport('CloseFig',[modelname '/Priority Scope']);
set_param([modelname '/Priority Scope'],'OpenScopeAtSimStart', 'off' );
set_param([modelname '/Task Queue Length'],'OpenScopeAtSimStart', 'on' );
sim(modelname);

%%
%
% *  Number of low-priority tasks completed.
%
des.scope.CallbackSupport('CloseFig',[modelname '/Task Queue Length']);
set_param([modelname '/Task Queue Length'],'OpenScopeAtSimStart', 'off' );
set_param([modelname '/Plots and  function-call for  dependent tasks/Low Priority Token Count'],'OpenScopeAtSimStart', 'on' );
sim(modelname);

%%
% *  Number of high-priority tasks completed.
%
des.scope.CallbackSupport('CloseFig',[modelname '/Plots and  function-call for  dependent tasks/Low Priority Token Count']);
set_param([modelname '/Plots and  function-call for  dependent tasks/Low Priority Token Count'],'OpenScopeAtSimStart', 'off' );
set_param([modelname '/Plots and  function-call for  dependent tasks/Signal Scope'],'OpenScopeAtSimStart', 'on' );
sim(modelname);

%%
% *  Number of dependent tasks completed. This equals the number of
%    high-priority tasks completed because the dependent task tokens are
%    generated upon the completion of a high-priority task.
des.scope.CallbackSupport('CloseFig',[modelname '/Plots and  function-call for  dependent tasks/Signal Scope']);
set_param([modelname '/Plots and  function-call for  dependent tasks/Signal Scope'],'OpenScopeAtSimStart', 'off' );
set_param([modelname '/Plots and  function-call for  dependent tasks/Dependent Token Count'],'OpenScopeAtSimStart', 'on' );

sim(modelname);

%% Related Examples
% * <matlab:showdemo('sedemo_rtos_application'); Task Preemption in an Operating System>
% * <matlab:showdemo('sedemo_rtos_two_priorities'); Task Prioritization in an Operating System>


%% 
%cleanup
bdclose(modelname);
clear modelname;
displayEndOfDemoMessage(mfilename)
