GCC Code Coverage Report


Directory: ./
File: pdserv/src/lib/SessionTaskData.cpp
Date: 2025-08-17 04:10:43
Exec Total Coverage
Lines: 83 100 83.0%
Branches: 74 161 46.0%

Line Branch Exec Source
1 /*****************************************************************************
2 *
3 * Copyright 2010 - 2012 Richard Hacker (lerichi at gmx dot net)
4 * Florian Pose <fp@igh-essen.com>
5 *
6 * This file is part of the pdserv library.
7 *
8 * The pdserv library is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as published
10 * by the Free Software Foundation, either version 3 of the License, or (at
11 * your option) any later version.
12 *
13 * The pdserv library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16 * License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with the pdserv library. If not, see <http://www.gnu.org/licenses/>.
20 *
21 ****************************************************************************/
22
23 #include "../Debug.h"
24 #include "../SessionTask.h"
25 #include "Main.h"
26 #include "SessionTaskData.h"
27 #include "ShmemDataStructures.h"
28 #include "Signal.h"
29
30 ////////////////////////////////////////////////////////////////////////////
31 299 SessionTaskData::SessionTaskData (PdServ::SessionTask *st,
32 const std::vector<Signal*>* signals,
33 299 struct Pdo *txMemBegin, const void *txMemEnd):
34 sessionTask(st),
35
1/2
✓ Branch 6 taken 299 times.
✗ Branch 7 not taken.
299 task(const_cast<Task*>(static_cast<const Task*>(st->task))),
36 signals(signals),
37 598 txMemBegin(txMemBegin), txMemEnd(txMemEnd)
38 {
39 299 signalListId = 0;
40 299 pdoSize = 0;
41
42
1/2
✓ Branch 4 taken 299 times.
✗ Branch 5 not taken.
299 signalPosition.resize(signals->size());
43
44
1/2
✓ Branch 2 taken 299 times.
✗ Branch 3 not taken.
299 init();
45 299 }
46
47 ////////////////////////////////////////////////////////////////////////////
48 592 SessionTaskData::~SessionTaskData ()
49 {
50 296 for (SignalSet::const_iterator it = subscribedSet.begin();
51
1/2
✗ Branch 6 not taken.
✓ Branch 7 taken 296 times.
296 it != subscribedSet.end(); it++) {
52 //log_debug("Auto unsubscribe from %s", (*it)->path.c_str());
53 static_cast<const PdServ::Signal*>(*it)->unsubscribe(sessionTask);
54 }
55 296 }
56
57 ////////////////////////////////////////////////////////////////////////////
58 // When this function exits, pdo
59 // * points to the end of the pdo list,
60 // * is a Data Pdo
61 // and its signalListId is valid
62 299 void SessionTaskData::init()
63 {
64
2/2
✓ Branch 2 taken 148 times.
✓ Branch 3 taken 151 times.
299 const Signal *signals[signalPosition.size()];
65 299 size_t nelem;
66
67 299 pdo = txMemBegin;
68 3 while (true) {
69 while (true) {
70 // Check whether pdo is valid
71
2/4
✓ Branch 2 taken 459 times.
✗ Branch 3 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 459 times.
616 if (pdo < txMemBegin or pdo+1 >= txMemEnd) {
72 pdo = txMemBegin;
73 break;
74 }
75
76
2/2
✓ Branch 2 taken 302 times.
✓ Branch 3 taken 157 times.
459 if (!pdo->next) {
77 // At end of pdo list. Get the signal list and test
78 // whether ith is a data pdo and that the
79 // signalListId matches
80
81
1/2
✓ Branch 8 taken 302 times.
✗ Branch 9 not taken.
302 task->getSignalList(signals, &nelem, &signalListId);
82
83
3/4
✗ Branch 2 not taken.
✓ Branch 3 taken 302 times.
✓ Branch 4 taken 299 times.
✓ Branch 5 taken 3 times.
302 if (pdo->type != Pdo::Data
84
1/2
✓ Branch 3 taken 299 times.
✗ Branch 4 not taken.
299 or pdo->signalListId != signalListId)
85 break;
86
87 // OK. Everything is fine
88 299 seqNo = pdo->seqNo;
89
1/2
✓ Branch 3 taken 299 times.
✗ Branch 4 not taken.
299 loadSignalList(signals, nelem, signalListId);
90
91 log_debug("Session %p sync'ed: pdo=%p seqNo=%u"
92 " signalListId=%u",
93 this, (void *) pdo, seqNo, signalListId);
94
95 598 return;
96 }
97
98 157 pdo = pdo->next;
99 }
100
101 // Sleep for half task sample time in the hope that next time round
102 // there is a valid pdo
103
1/2
✓ Branch 28 taken 3 times.
✗ Branch 29 not taken.
6 task->main->sleep(
104 6 std::max(50U, static_cast<unsigned>(500*task->sampleTime)));
105 299 }
106 }
107
108 ////////////////////////////////////////////////////////////////////////////
109 47 void SessionTaskData::subscribe(const Signal* s)
110 {
111
6/20
✓ Branch 5 taken 47 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 47 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 47 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 47 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 47 times.
✗ Branch 19 not taken.
✗ Branch 21 not taken.
✓ Branch 22 taken 47 times.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
94 if (activeSet.find(s) != activeSet.end()
112
6/16
✓ Branch 0 taken 47 times.
✗ Branch 1 not taken.
✓ Branch 4 taken 47 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 47 times.
✓ Branch 8 taken 47 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 47 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 47 times.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
141 or (subscribedSet.insert(s).second
113
2/4
✓ Branch 16 taken 47 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✓ Branch 19 taken 47 times.
47 and s->task->subscribe(s, this, true)
114
4/20
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 47 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 47 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 47 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 47 times.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
47 and transferredSet.find(s) != transferredSet.end())) {
115 activeSet.insert(s);
116 sessionTask->newSignal(s);
117 return;
118 }
119 }
120
121 ////////////////////////////////////////////////////////////////////////////
122 44 void SessionTaskData::unsubscribe(const Signal* s)
123 {
124
1/2
✓ Branch 2 taken 44 times.
✗ Branch 3 not taken.
44 if (subscribedSet.erase(s)) {
125 44 activeSet.erase(s);
126 44 s->task->subscribe(s, this, false);
127 }
128 44 }
129
130 ////////////////////////////////////////////////////////////////////////////
131 23407 bool SessionTaskData::rxPdo (const struct timespec **time,
132 const PdServ::TaskStatistics **statistics)
133 {
134
2/2
✓ Branch 2 taken 3901 times.
✓ Branch 3 taken 19506 times.
23451 while (pdo->next) {
135 size_t n;
136
137 3901 pdo = pdo->next;
138
2/4
✓ Branch 2 taken 3901 times.
✗ Branch 3 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 3901 times.
3901 if (pdo < txMemBegin or &pdo->data > txMemEnd) {
139 goto out;
140 }
141
142 3901 n = pdo->count;
143
144
3/5
✗ Branch 2 not taken.
✓ Branch 3 taken 3901 times.
✓ Branch 4 taken 44 times.
✓ Branch 5 taken 3857 times.
✗ Branch 6 not taken.
3901 switch (pdo->type) {
145 44 case Pdo::SignalList:
146 {
147
1/2
✗ Branch 4 not taken.
✓ Branch 5 taken 44 times.
44 const Signal *sp[signals->size()];
148
149
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 44 times.
44 if (&pdo->signalIdx + n > txMemEnd) {
150 goto out;
151 }
152
153
2/2
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 44 times.
96 for (size_t i = 0; i < n; ++i) {
154 52 size_t idx = (&pdo->signalIdx)[i];
155
156
1/2
✗ Branch 4 not taken.
✓ Branch 5 taken 52 times.
52 if (idx >= signals->size())
157 goto out;
158
159 52 sp[i] = (*signals)[idx];
160 }
161
1/2
✓ Branch 4 taken 44 times.
✗ Branch 5 not taken.
88 loadSignalList(sp, n, pdo->signalListId);
162 }
163
164 44 break;
165
166 3857 case Pdo::Data:
167
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 3857 times.
3857 if (&pdo->data + pdoSize >= txMemEnd
168
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 3857 times.
3857 or pdo->signalListId != signalListId
169
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 3857 times.
3857 or pdo->seqNo - seqNo != 1) {
170 log_debug("%p + %zu >= %p; %u != %u; %i != 1; %u %u %u",
171 (void *) &pdo->data, pdoSize, (void *) txMemEnd,
172 pdo->signalListId, signalListId,
173 pdo->seqNo - seqNo,
174 &pdo->data + pdoSize >= txMemEnd,
175 pdo->signalListId != signalListId,
176 pdo->seqNo - seqNo != 1
177 );
178 goto out;
179 }
180
181 3857 seqNo = pdo->seqNo;
182 3857 signalBuffer = &pdo->data;
183 3857 *time = &pdo->time;
184 3857 *statistics = &pdo->taskStatistics;
185
186 3857 return true;
187
188 default:
189 goto out;
190 }
191 }
192
193 19506 *time = &pdo->time;
194 19506 *statistics = &pdo->taskStatistics;
195
196 19506 return false;
197
198 out:
199 log_debug("Session %p out of sync.", this);
200 init();
201 return true;
202 }
203
204 ////////////////////////////////////////////////////////////////////////////
205 343 void SessionTaskData::loadSignalList(const Signal * const* sp, size_t n,
206 unsigned int id)
207 {
208 log_debug("Loading %zu signals with id %u", n, id);
209 // cout << __func__ << " n=" << n << " id=" << id;
210
1/2
✓ Branch 7 taken 343 times.
✗ Branch 8 not taken.
343 std::fill(signalPosition.begin(), signalPosition.end(), ~0U);
211 343 transferredSet.clear();
212
213 343 signalListId = id;
214 343 pdoSize = 0;
215
2/2
✓ Branch 0 taken 53 times.
✓ Branch 1 taken 343 times.
396 for (size_t i = 0; i < n; ++i) {
216 53 signalPosition[sp[i]->index] = pdoSize;
217 53 pdoSize += sp[i]->memSize;
218 53 transferredSet.insert(sp[i]);
219
7/20
✓ Branch 6 taken 53 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 53 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 53 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 53 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 53 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 47 times.
✓ Branch 23 taken 6 times.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
106 if (subscribedSet.find(sp[i]) != subscribedSet.end()
220
1/2
✓ Branch 7 taken 52 times.
✗ Branch 8 not taken.
52 and int(signalListId - sp[i]->subscriptionId) >= 0
221
10/16
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 1 times.
✓ Branch 5 taken 52 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 52 times.
✓ Branch 9 taken 47 times.
✓ Branch 10 taken 5 times.
✓ Branch 11 taken 52 times.
✓ Branch 12 taken 1 times.
✓ Branch 14 taken 52 times.
✓ Branch 15 taken 1 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
158 and activeSet.insert(sp[i]).second) {
222 47 sessionTask->newSignal(sp[i]);
223 }
224 // cout << ' ' << sp[i]->index << '(' << pdoSize << ')';
225 }
226 log_debug("pdosize=%zu", pdoSize);
227 // cout << endl;
228 343 }
229
230 ////////////////////////////////////////////////////////////////////////////
231 1179 const char *SessionTaskData::getValue(const PdServ::Signal *s) const
232 {
233 return
234
1/2
✓ Branch 1 taken 1179 times.
✗ Branch 2 not taken.
1179 signalBuffer + signalPosition[static_cast<const Signal*>(s)->index];
235 }
236
237 ////////////////////////////////////////////////////////////////////////////
238 const struct timespec *SessionTaskData::getTaskTime() const
239 {
240 return &pdo->time;
241 }
242
243 ////////////////////////////////////////////////////////////////////////////
244 const PdServ::TaskStatistics* SessionTaskData::getTaskStatistics() const
245 {
246 return &pdo->taskStatistics;
247 }
248