iCub-main
Loading...
Searching...
No Matches
ThreadTable2.h
Go to the documentation of this file.
1// -*- mode:C++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*-
2
3/*
4 * Copyright (C) 2008 The RobotCub Consortium
5 * Author: Lorenzo Natale
6 * website: www.robotcub.org
7 * Permission is granted to copy, distribute, and/or modify this program
8 * under the terms of the GNU General Public License, version 2 or any
9 * later version published by the Free Software Foundation.
10 *
11 * A copy of the license can be found at
12 * http://www.robotcub.org/icub/license/gpl.txt
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
17 * Public License for more details
18*/
19
20#ifndef __THREADTABLE2__
21#define __THREADTABLE2__
22
23#include <mutex>
24#include <condition_variable>
25#include <ace/config.h>
26#include <ace/Thread.h>
27#include <yarp/dev/CanBusInterface.h>
28
29#include "canControlConstants.h"
30#include "canControlUtils.h"
31
33{
34private:
35 int _pending;
36 int _timedOut;
37 yarp::dev::CanBuffer _replies;
38 yarp::dev::ICanBufferFactory *ic;
39 std::mutex mtx_synch;
40 std::condition_variable cv_synch;
41 int _replied;
42 ACE_thread_t _handle;
43 std::mutex _mutex;
44
45 inline void lock()
46 { _mutex.lock(); }
47
48 inline void unlock()
49 { _mutex.unlock(); }
50
51public:
54
55 void clear();
56
57 // initialize, need factory to create internal buffer of
58 // messages which will store replies
59 void init(yarp::dev::ICanBufferFactory *i);
60
61 // set number of pending requests, reset
62 inline void setPending(int pend);
63
64 // wait on semaphore, usually thread sleeps here after
65 // has issued a list of requests to the can
66 void synch()
67 {
68 std::unique_lock<std::mutex> lck(mtx_synch);
69 cv_synch.wait(lck);
70 }
71
72 // true if there are pending requests
73 bool pending()
74 {
75 lock();
76 bool ret=(_pending != 0) ? true:false;
77 unlock();
78 return ret;
79 }
80
81 // true if at least one time out occurred
82 inline bool timedOut()
83 {
84 lock();
85 bool ret=(_timedOut!=0)?true:false;
86 unlock();
87 return ret;
88 }
89
90 // notify that one of the requests timed out
91 // if no other requests are pending the waiting thread
92 // is released
93 inline bool timeout();
94
95 // push a reply, thread safe
96 // wake up wating thread when all messages are received
97 inline bool push(const yarp::dev::CanMessage &m);
98
99 ACE_thread_t &handle()
100 { return _handle; }
101
102
103 //get can message from joint number
104 inline yarp::dev::CanMessage *getByJoint(int j, const unsigned char *destInv);
105
106 //get n-nth message in the list of replies
107 inline yarp::dev::CanMessage *get(int n);
108};
109
110yarp::dev::CanMessage *ThreadTable2::get(int n)
111{
112 if (n<0 || n>=_replied)
113 return 0;
114
115 return &_replies[n];
116}
117
118yarp::dev::CanMessage *ThreadTable2::getByJoint(int j, const unsigned char *destInv)
119{
120 for(int k=0;k<_replied;k++)
121 if (getJoint(_replies[k], destInv)==j)
122 return &_replies[k];
123 return 0;
124}
125
126bool ThreadTable2::push(const yarp::dev::CanMessage &m)
127{
128 lock();
129 if (_replied>=BUF_SIZE)
130 {
131 unlock();
132 //the message buffer is full -- this means that too many messages
133 //have been requested. Check the following calls:
134 // t->setPending(r._writeMessages);
135 // t->synch();
136 // the buffer should be large enough to match the worst case
137 // i.e. the largest value of _writeMessages
138 // Increase BUF_SIZE accordingly.
139 fprintf(stderr, "Warning: buffer full in ThreadTable2, increase value of BUF_SIZE\n");
140 return false;
141 }
142
143 _replies[_replied]=m;
144
145 _replied++;
146 _pending--;
147 if (_pending==0)
148 cv_synch.notify_one();
149
150 unlock();
151 return true;
152}
153
155{
156 lock();
157 _replied++;
158 _pending--;
159 _timedOut++;
160 if (_pending==0)
161 {
162 cv_synch.notify_one();
163 }
164 unlock();
165 return true;
166}
167
169{
170 lock();
171 _pending=pend;
172 _replied=0;
173 _timedOut=0;
174 unlock();
175}
176
177#endif
178
179
#define BUF_SIZE
int getJoint(const yarp::dev::CanMessage &m, const unsigned char *invM)
Extract the joint number to which a RECEIVED message is referring to.
yarp::dev::CanMessage * getByJoint(int j, const unsigned char *destInv)
bool push(const yarp::dev::CanMessage &m)
void init(yarp::dev::ICanBufferFactory *i)
void setPending(int pend)
ACE_thread_t & handle()
bool timedOut()
yarp::dev::CanMessage * get(int n)
int n
fprintf(fid,'\n')