GCC Code Coverage Report


Directory: ./
File: pdserv/src/lib/SessionTaskData.cpp
Date: 2024-12-15 04:08:34
Exec Total Coverage
Lines: 83 100 83.0%
Branches: 74 161 46.0%

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 299 SessionTaskData::SessionTaskData (PdServ::SessionTask *st,
34 const std::vector<Signal*>* signals,
35 299 struct Pdo *txMemBegin, const void *txMemEnd):
36 sessionTask(st),
37
1/2
✓ Branch 6 taken 299 times.
✗ Branch 7 not taken.
299 task(const_cast<Task*>(static_cast<const Task*>(st->task))),
38 signals(signals),
39 598 txMemBegin(txMemBegin), txMemEnd(txMemEnd)
40 {
41 299 signalListId = 0;
42 299 pdoSize = 0;
43
44
1/2
✓ Branch 4 taken 299 times.
✗ Branch 5 not taken.
299 signalPosition.resize(signals->size());
45
46
1/2
✓ Branch 2 taken 299 times.
✗ Branch 3 not taken.
299 init();
47 299 }
48
49 ////////////////////////////////////////////////////////////////////////////
50 592 SessionTaskData::~SessionTaskData ()
51 {
52 296 for (SignalSet::const_iterator it = subscribedSet.begin();
53
1/2
✗ Branch 6 not taken.
✓ Branch 7 taken 296 times.
296 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 296 }
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 299 void SessionTaskData::init()
65 {
66
2/2
✓ Branch 2 taken 148 times.
✓ Branch 3 taken 151 times.
299 const Signal *signals[signalPosition.size()];
67 299 size_t nelem;
68
69 299 pdo = txMemBegin;
70 3 while (true) {
71 while (true) {
72 // Check whether pdo is valid
73
2/4
✓ Branch 2 taken 458 times.
✗ Branch 3 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 458 times.
614 if (pdo < txMemBegin or pdo+1 >= txMemEnd) {
74 pdo = txMemBegin;
75 break;
76 }
77
78
2/2
✓ Branch 2 taken 302 times.
✓ Branch 3 taken 156 times.
458 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 302 times.
✗ Branch 9 not taken.
302 task->getSignalList(signals, &nelem, &signalListId);
84
85
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
86
1/2
✓ Branch 3 taken 299 times.
✗ Branch 4 not taken.
299 or pdo->signalListId != signalListId)
87 break;
88
89 // OK. Everything is fine
90 299 seqNo = pdo->seqNo;
91
1/2
✓ Branch 3 taken 299 times.
✗ Branch 4 not taken.
299 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 598 return;
97 }
98
99 156 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
1/2
✓ Branch 28 taken 3 times.
✗ Branch 29 not taken.
6 task->main->sleep(
105 6 std::max(50U, static_cast<unsigned>(500*task->sampleTime)));
106 299 }
107 }
108
109 ////////////////////////////////////////////////////////////////////////////
110 47 void SessionTaskData::subscribe(const Signal* s)
111 {
112
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()
113
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
114
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)
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 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())) {
116 activeSet.insert(s);
117 sessionTask->newSignal(s);
118 return;
119 }
120 }
121
122 ////////////////////////////////////////////////////////////////////////////
123 44 void SessionTaskData::unsubscribe(const Signal* s)
124 {
125
1/2
✓ Branch 2 taken 44 times.
✗ Branch 3 not taken.
44 if (subscribedSet.erase(s)) {
126 44 activeSet.erase(s);
127 44 s->task->subscribe(s, this, false);
128 }
129 44 }
130
131 ////////////////////////////////////////////////////////////////////////////
132 23221 bool SessionTaskData::rxPdo (const struct timespec **time,
133 const PdServ::TaskStatistics **statistics)
134 {
135
2/2
✓ Branch 2 taken 3907 times.
✓ Branch 3 taken 19314 times.
23267 while (pdo->next) {
136 size_t n;
137
138 3907 pdo = pdo->next;
139
2/4
✓ Branch 2 taken 3907 times.
✗ Branch 3 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 3907 times.
3907 if (pdo < txMemBegin or &pdo->data > txMemEnd) {
140 goto out;
141 }
142
143 3907 n = pdo->count;
144
145
3/5
✗ Branch 2 not taken.
✓ Branch 3 taken 3907 times.
✓ Branch 4 taken 46 times.
✓ Branch 5 taken 3861 times.
✗ Branch 6 not taken.
3907 switch (pdo->type) {
146 46 case Pdo::SignalList:
147 {
148
1/2
✗ Branch 4 not taken.
✓ Branch 5 taken 46 times.
46 const Signal *sp[signals->size()];
149
150
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 46 times.
46 if (&pdo->signalIdx + n > txMemEnd) {
151 goto out;
152 }
153
154
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 46 times.
100 for (size_t i = 0; i < n; ++i) {
155 54 size_t idx = (&pdo->signalIdx)[i];
156
157
1/2
✗ Branch 4 not taken.
✓ Branch 5 taken 54 times.
54 if (idx >= signals->size())
158 goto out;
159
160 54 sp[i] = (*signals)[idx];
161 }
162
1/2
✓ Branch 4 taken 46 times.
✗ Branch 5 not taken.
92 loadSignalList(sp, n, pdo->signalListId);
163 }
164
165 46 break;
166
167 3861 case Pdo::Data:
168
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 3861 times.
3861 if (&pdo->data + pdoSize >= txMemEnd
169
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 3861 times.
3861 or pdo->signalListId != signalListId
170
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 3861 times.
3861 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 3861 seqNo = pdo->seqNo;
183 3861 signalBuffer = &pdo->data;
184 3861 *time = &pdo->time;
185 3861 *statistics = &pdo->taskStatistics;
186
187 3861 return true;
188
189 default:
190 goto out;
191 }
192 }
193
194 19314 *time = &pdo->time;
195 19314 *statistics = &pdo->taskStatistics;
196
197 19314 return false;
198
199 out:
200 log_debug("Session %p out of sync.", this);
201 init();
202 return true;
203 }
204
205 ////////////////////////////////////////////////////////////////////////////
206 345 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 345 times.
✗ Branch 8 not taken.
345 std::fill(signalPosition.begin(), signalPosition.end(), ~0U);
212 345 transferredSet.clear();
213
214 345 signalListId = id;
215 345 pdoSize = 0;
216
2/2
✓ Branch 0 taken 55 times.
✓ Branch 1 taken 345 times.
400 for (size_t i = 0; i < n; ++i) {
217 55 signalPosition[sp[i]->index] = pdoSize;
218 55 pdoSize += sp[i]->memSize;
219 55 transferredSet.insert(sp[i]);
220
7/20
✓ Branch 6 taken 55 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 55 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 55 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 55 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 55 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 47 times.
✓ Branch 23 taken 8 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.
110 if (subscribedSet.find(sp[i]) != subscribedSet.end()
221
1/2
✓ Branch 7 taken 54 times.
✗ Branch 8 not taken.
54 and int(signalListId - sp[i]->subscriptionId) >= 0
222
10/16
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 1 times.
✓ Branch 5 taken 54 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 54 times.
✓ Branch 9 taken 47 times.
✓ Branch 10 taken 7 times.
✓ Branch 11 taken 54 times.
✓ Branch 12 taken 1 times.
✓ Branch 14 taken 54 times.
✓ Branch 15 taken 1 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
164 and activeSet.insert(sp[i]).second) {
223 47 sessionTask->newSignal(sp[i]);
224 }
225 // cout << ' ' << sp[i]->index << '(' << pdoSize << ')';
226 }
227 log_debug("pdosize=%zu", pdoSize);
228 // cout << endl;
229 345 }
230
231 ////////////////////////////////////////////////////////////////////////////
232 1181 const char *SessionTaskData::getValue(const PdServ::Signal *s) const
233 {
234 return
235
1/2
✓ Branch 1 taken 1181 times.
✗ Branch 2 not taken.
1181 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