Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
D
dynamic-graph
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Stack Of Tasks
dynamic-graph
Commits
ddab6445
Commit
ddab6445
authored
6 years ago
by
Joseph Mirabel
Committed by
Olivier Stasse
6 years ago
Browse files
Options
Downloads
Patches
Plain Diff
In RealTimeLogger, add thread safety for writting + add doc.
parent
73a016f0
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
include/dynamic-graph/real-time-logger.h
+42
-3
42 additions, 3 deletions
include/dynamic-graph/real-time-logger.h
src/debug/real-time-logger.cpp
+9
-1
9 additions, 1 deletion
src/debug/real-time-logger.cpp
tests/real-time-logger.cpp
+3
-3
3 additions, 3 deletions
tests/real-time-logger.cpp
with
54 additions
and
7 deletions
include/dynamic-graph/real-time-logger.h
+
42
−
3
View file @
ddab6445
...
...
@@ -21,6 +21,7 @@
# include <boost/circular_buffer.hpp>
# include <boost/shared_ptr.hpp>
# include <boost/thread/mutex.hpp>
# include <dynamic-graph/config.hh>
# include <dynamic-graph/debug.h>
...
...
@@ -31,12 +32,20 @@ namespace dynamicgraph
/// \ingroup debug
///
/// \brief Stream for the real-time logger.
///
/// You should inherit from this class in order to redirect the logs where you
/// want.
/// \sa LoggerIOStream
class
LoggerStream
{
public:
virtual
void
write
(
const
char
*
c
)
=
0
;
};
/// Write to an ostream object.
///
/// The easieast is to use the macro \ref dgADD_OSTREAM_TO_RTLOG(ostr) where
/// `ostr` can be `std::cout` or an std::ofstream...
class
LoggerIOStream
:
public
LoggerStream
{
public:
...
...
@@ -48,12 +57,18 @@ namespace dynamicgraph
typedef
boost
::
shared_ptr
<
LoggerStream
>
LoggerStreamPtr_t
;
class
RealTimeLogger
;
/// \cond DEVEL
/// \brief write entries to intenal buffer.
///
/// The entry starts when an instance is created and ends when is is deleted.
/// This class is only used by RealTimeLogger.
class
RTLoggerStream
{
public:
RTLoggerStream
(
RealTimeLogger
*
logger
,
std
::
ostream
&
os
)
:
logger_
(
logger
),
os_
(
os
)
{}
template
<
typename
T
>
inline
RTLoggerStream
&
operator
<<
(
T
t
)
{
os_
<<
t
;
return
*
this
;
}
inline
RTLoggerStream
&
operator
<<
(
std
::
ostream
&
(
*
pf
)(
std
::
ostream
&
))
{
os_
<<
pf
;
return
*
this
;
}
template
<
typename
T
>
inline
RTLoggerStream
&
operator
<<
(
T
t
)
{
if
(
logger_
!=
NULL
)
os_
<<
t
;
return
*
this
;
}
inline
RTLoggerStream
&
operator
<<
(
std
::
ostream
&
(
*
pf
)(
std
::
ostream
&
))
{
if
(
logger_
!=
NULL
)
os_
<<
pf
;
return
*
this
;
}
~
RTLoggerStream
();
private
:
...
...
@@ -61,10 +76,30 @@ namespace dynamicgraph
RealTimeLogger
*
logger_
;
std
::
ostream
&
os_
;
};
/// \endcond DEVEL
/// \ingroup debug
///
/// \brief Main class of the real-time logger.
///
/// It is intended to be used like this:
/// \code
/// #define ENABLE_RT_LOG
/// #include <dynamic-graph/real-time-logger.h>
///
/// // Somewhere in the main function of your executable
/// int main (int argc, char** argv) {
/// dgADD_OSTREAM_TO_RTLOG (std::cout);
/// }
///
/// // Somewhere in your library
/// dgRTLOG() << "your message. Prefer to use \n than std::endl."
/// \endcode
///
/// \note Thread safety. This class expects to have:
/// - only one reader: the one who take the log entries and write them somewhere.
/// - one writer at a time. Writing to the logs is **never** a blocking
/// operation. If the resource is busy, the log entry is discarded.
class
DYNAMIC_GRAPH_DLLAPI
RealTimeLogger
{
public:
...
...
@@ -88,7 +123,7 @@ namespace dynamicgraph
/// The message is considered finished when the object is destroyed.
RTLoggerStream
front
();
inline
void
frontReady
()
{
backIdx_
=
(
backIdx_
+
1
)
%
buffer_
.
size
();
}
inline
void
frontReady
()
{
backIdx_
=
(
backIdx_
+
1
)
%
buffer_
.
size
();
wmutex
.
unlock
();
}
inline
bool
empty
()
const
{
...
...
@@ -126,6 +161,10 @@ namespace dynamicgraph
std
::
size_t
backIdx_
;
std
::
ostream
oss_
;
/// The writer mutex.
boost
::
mutex
wmutex
;
std
::
size_t
nbDiscarded_
;
struct
thread
;
static
RealTimeLogger
*
instance_
;
...
...
This diff is collapsed.
Click to expand it.
src/debug/real-time-logger.cpp
+
9
−
1
View file @
ddab6445
...
...
@@ -27,6 +27,7 @@ namespace dynamicgraph
RealTimeLogger
::
RealTimeLogger
(
const
std
::
size_t
&
bufferSize
)
:
buffer_
(
bufferSize
,
NULL
)
,
oss_
(
NULL
)
,
nbDiscarded_
(
0
)
{
for
(
std
::
size_t
i
=
0
;
i
<
buffer_
.
size
();
++
i
)
buffer_
[
i
]
=
new
Data
;
...
...
@@ -54,8 +55,15 @@ namespace dynamicgraph
RTLoggerStream
RealTimeLogger
::
front
()
{
// If no output or if buffer is full, discard message.
if
(
outputs_
.
empty
()
||
full
())
{
oss_
.
rdbuf
(
NULL
);
nbDiscarded_
++
;
return
RTLoggerStream
(
NULL
,
oss_
);
}
bool
alone
=
wmutex
.
try_lock
();
// If someone is writting, discard message.
if
(
!
alone
)
{
nbDiscarded_
++
;
return
RTLoggerStream
(
NULL
,
oss_
);
}
Data
*
data
=
buffer_
[
backIdx_
];
...
...
This diff is collapsed.
Click to expand it.
tests/real-time-logger.cpp
+
3
−
3
View file @
ddab6445
...
...
@@ -46,7 +46,7 @@ BOOST_AUTO_TEST_CASE (monothread)
int
spinNb
=
0
;
while
(
rtl
.
spinOnce
())
{
spinNb
++
;
}
BOOST_CHECK
(
spinNb
==
9
);
BOOST_CHECK
_EQUAL
(
spinNb
,
9
);
rtl
.
front
()
<<
"This msg should be short."
<<
'\n'
;
rtl
.
spinOnce
();
...
...
@@ -58,10 +58,10 @@ BOOST_AUTO_TEST_CASE (multithread)
dgADD_OSTREAM_TO_RTLOG
(
std
::
cout
);
for
(
std
::
size_t
i
=
0
;
i
<
rtl
.
getBufferSize
()
-
1
;
++
i
)
rtl
.
front
()
<<
"Call number "
<<
i
<<
'\n'
;
dgRTLOG
()
<<
"Call number "
<<
i
<<
'\n'
;
for
(
std
::
size_t
i
=
0
;
i
<
12
;
++
i
)
{
boost
::
this_thread
::
sleep
(
boost
::
posix_time
::
milliseconds
(
20
));
rtl
.
front
()
<<
"Call number "
<<
i
<<
std
::
endl
;
dgRTLOG
()
<<
"Call number "
<<
i
<<
std
::
endl
;
BOOST_CHECK
(
!
rtl
.
full
());
}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment