iCub-main
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 {
34 private:
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 
51 public:
52  ThreadTable2();
53  ~ThreadTable2();
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 
110 yarp::dev::CanMessage *ThreadTable2::get(int n)
111 {
112  if (n<0 || n>=_replied)
113  return 0;
114 
115  return &_replies[n];
116 }
117 
118 yarp::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 
126 bool 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 
const int 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.
ACE_thread_t & handle()
Definition: ThreadTable2.h:99
bool timeout()
Definition: ThreadTable2.h:154
void synch()
Definition: ThreadTable2.h:66
yarp::dev::CanMessage * getByJoint(int j, const unsigned char *destInv)
Definition: ThreadTable2.h:118
bool push(const yarp::dev::CanMessage &m)
Definition: ThreadTable2.h:126
void init(yarp::dev::ICanBufferFactory *i)
void setPending(int pend)
Definition: ThreadTable2.h:168
bool timedOut()
Definition: ThreadTable2.h:82
bool pending()
Definition: ThreadTable2.h:73
yarp::dev::CanMessage * get(int n)
Definition: ThreadTable2.h:110
int n
fprintf(fid,'\n')