GCC Code Coverage Report


Directory: ./
File: pdserv/src/lib/SessionTaskData.cpp
Date: 2023-11-12 04:06:57
Exec Total Coverage
Lines: 80 100 80.0%
Branches: 71 161 44.1%

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