Skip to content

Commit dd17be6

Browse files
committed
Fix process priority (non-clocked blocks only)
* Add option setPriority to toggle changing the priority of the simulation process * Reset the priority of the simulation process at end of simulation * Add missing start attribute of dummyState * Only print last error in case of a failing change of the priority of the simulation process * Rebuild ITI_MDD.dll See #44
1 parent 488ee8f commit dd17be6

File tree

6 files changed

+116
-19
lines changed

6 files changed

+116
-19
lines changed

Blocks/OperatingSystem.mo

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,31 +5,29 @@ package OperatingSystem
55
block SynchronizeRealtime "A pseudo realtime synchronization"
66
extends Modelica_DeviceDrivers.Utilities.Icons.BaseIcon;
77
parameter Integer resolution(min = 1) = 1 "resolution of the timer";
8+
parameter Boolean setPriority = true "true, if process priority is to be set, otherwise false";
89
parameter
910
Modelica_DeviceDrivers.Blocks.OperatingSystem.Types.ProcessPriority
10-
priority = "Normal" "Priority of the simulation process";
11+
priority = "Normal" "Priority of the simulation process" annotation(Dialog(enable=setPriority));
1112
output Real calculationTime "Time needed for calculation";
1213
output Real availableTime
1314
"Time available for calculation (integrator step size)";
15+
Modelica_DeviceDrivers.OperatingSystem.ProcessPriority procPrio = Modelica_DeviceDrivers.OperatingSystem.ProcessPriority(
16+
if
17+
(priority == "Idle") then -2 else
18+
if
19+
(priority == "Below normal") then -1 else
20+
if
21+
(priority == "Normal") then 0 else
22+
if
23+
(priority == "High priority") then 1 else
24+
if
25+
(priority == "Realtime") then 2 else
26+
0) if setPriority;
1427
protected
15-
Real dummyState
28+
Real dummyState(start = 0)
1629
"dummy state to be integrated, to force synchronization in every integration step";
1730
equation
18-
when (initial()) then
19-
Modelica_DeviceDrivers.OperatingSystem.setProcessPriority(
20-
if
21-
(priority == "Idle") then -2 else
22-
if
23-
(priority == "Below normal") then -1 else
24-
if
25-
(priority == "Normal") then 0 else
26-
if
27-
(priority == "High priority") then 1 else
28-
if
29-
(priority == "Realtime") then 2 else
30-
0);
31-
end when;
32-
3331
(calculationTime,availableTime) = Modelica_DeviceDrivers.OperatingSystem.realtimeSynchronize(time,resolution);
3432
der(dummyState) =calculationTime;
3533
annotation (preferredView="info",
@@ -39,7 +37,7 @@ package OperatingSystem
3937
"../Resources/Images/Icons/clock.png"),
4038
Text(
4139
extent={{-100,-100},{100,-140}},
42-
textString="%priority"), Text(extent={{-150,142},{150,102}},
40+
textString=DynamicSelect("", if setPriority then "%priority" else "")), Text(extent={{-150,142},{150,102}},
4341
textString="%name")}),
4442
Documentation(info="<html>
4543
<p>Synchronizes the simulation time of the simulation process with the operating system real-time clock. Different priority levels are supported:</p>

OperatingSystem/ProcessPriority.mo

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
within Modelica_DeviceDrivers.OperatingSystem;
2+
class ProcessPriority "An object for process priority."
3+
extends ExternalObject;
4+
function constructor "Creates a ProcessPriority instance with a given process priority."
5+
input Integer priority "Simulation process priority (-2(lowest)..2(realtime))";
6+
output ProcessPriority procPrio;
7+
external "C" procPrio = MDD_ProcessPriorityConstructor(priority)
8+
annotation(IncludeDirectory="modelica://Modelica_DeviceDrivers/Resources/Include",
9+
Include = "#include \"MDDRealtimeSynchronize.h\" ",
10+
Library = "rt",
11+
__iti_dll = "ITI_MDD.dll");
12+
end constructor;
13+
14+
function destructor
15+
input ProcessPriority procPrio;
16+
external "C" MDD_ProcessPriorityDestructor(procPrio)
17+
annotation(IncludeDirectory="modelica://Modelica_DeviceDrivers/Resources/Include",
18+
Include = "#include \"MDDRealtimeSynchronize.h\" ",
19+
Library = "rt",
20+
__iti_dll = "ITI_MDD.dll");
21+
end destructor;
22+
end ProcessPriority;

OperatingSystem/package.order

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
beep
22
clock
3+
ProcessPriority
34
randomReal
45
realtimeSynchronize
56
setProcessPriority

Resources/Include/MDDRealtimeSynchronize.h

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,85 @@ DllExport void MDD_setPriority(int priority)
6161
break;
6262
}
6363

64-
ModelicaFormatMessage("LastError: %d\n",GetLastError());
64+
{
65+
DWORD dw = GetLastError();
66+
if (dw) {
67+
ModelicaFormatMessage("LastError: %d\n", dw);
68+
}
69+
}
6570
}
6671

72+
typedef struct {
73+
DWORD prio;
74+
} ProcPrio;
75+
76+
DllExport void* MDD_ProcessPriorityConstructor(int priority) {
77+
ProcPrio* prio = (ProcPrio*) malloc(sizeof(ProcPrio));
78+
if (prio) {
79+
prio->prio = GetPriorityClass(GetCurrentProcess());
80+
}
81+
MDD_setPriority(priority);
82+
return (void*) prio;
83+
}
84+
85+
DllExport void MDD_ProcessPriorityDestructor(void* prioObj) {
86+
ProcPrio* prio = (ProcPrio*) prioObj;
87+
if (prio) {
88+
switch (prio->prio) {
89+
case IDLE_PRIORITY_CLASS:
90+
ModelicaFormatMessage("setting...\n");
91+
if (SetPriorityClass(GetCurrentProcess(), IDLE_PRIORITY_CLASS)) {
92+
ModelicaFormatMessage("ProcessPriority set to idle.\n");
93+
}
94+
break;
95+
96+
case BELOW_NORMAL_PRIORITY_CLASS:
97+
ModelicaFormatMessage("setting...\n");
98+
if (SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS)) {
99+
ModelicaFormatMessage("ProcessPriority set to below normal.\n");
100+
}
101+
break;
102+
103+
case NORMAL_PRIORITY_CLASS:
104+
ModelicaFormatMessage("setting...\n");
105+
if (SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS)) {
106+
ModelicaFormatMessage("ProcessPriority set to normal.\n");
107+
}
108+
break;
109+
110+
case HIGH_PRIORITY_CLASS:
111+
ModelicaFormatMessage("setting...\n");
112+
if (SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS)) {
113+
ModelicaFormatMessage("ProcessPriority set to high.\n");
114+
}
115+
break;
116+
117+
case REALTIME_PRIORITY_CLASS:
118+
ModelicaFormatMessage("setting...\n");
119+
if (SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS)) {
120+
ModelicaFormatMessage("ProcessPriority set to realtime.\n");
121+
}
122+
break;
123+
124+
default:
125+
ModelicaFormatMessage("setting...\n");
126+
if (SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS)) {
127+
ModelicaFormatMessage("ProcessPriority set to normal.\n");
128+
}
129+
break;
130+
}
131+
132+
{
133+
DWORD dw = GetLastError();
134+
if (dw) {
135+
ModelicaFormatMessage("LastError: %d\n", dw);
136+
}
137+
}
138+
139+
free(prio);
140+
}
141+
}
142+
67143
/** Request time from a monotonic increasing real-time clock.
68144
*
69145
* @param[in] resolution windows specific clock resolution. TODO remove resolution since ignored in (new) implementation

Resources/Library/win32/ITI_MDD.dll

1 KB
Binary file not shown.

Resources/Library/win64/ITI_MDD.dll

512 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)