#define expression(p_condition)                                                      \
  (                                                                                  \
  {                                                                                  \
    static int exec_count = 0;                                                       \
    bool condition = p_condition;                                                    \
    std::cout                                                                        \
    << "line("            << __LINE__                                        << ") " \
    << "exec_count("      << ++exec_count                                    << ") " \
    << "condition_value(" << std::boolalpha << condition << std::noboolalpha << ") " \
    << "condition_code("  << #p_condition                                    << ") " \
    << std::endl;                                                                    \
    condition;                                                                       \
  }                                                                                  \
  )
 
#define if(p_condition) if(expression(p_condition))
#define while(p_condition) while(expression(p_condition))
 
... du code mono-thread (avec des if et des while) à inspecter ...
 
#undef if
#undef while
 
// Malheureusement, je n'ai pas de solution pour la boucle for ; hormis convertir les boucles for en boucle while...
 
// petit hack a 2 balles :
#define FOR( init, cond, inc ) \
    for( (init) ; expression(cond) ;( inc ))
 
  {
    int i=0;
    FOR( (i=0) , (i!=42) , (i++) ) {
        std::cout<<i<<std::endl;
      }
  }
 
Le hack ci-dessus ne vaut rien car il demande trop de modif inutiles !
Celui-ci est meilleur :
soit une boucle for comme ceci : for(init; cond; incr)
il suffit de la changer en : for(init; expression(cond); incr)
inspector.hpp
#ifndef INSPECTOR_HPP
#define INSPECTOR_HPP
 
#include <pthread.h>
#include <iostream>
 
class ScopedMutex
{
  public:
 
  ScopedMutex(pthread_mutex_t & p_mutex);
  ~ScopedMutex();
 
  private:
 
  ScopedMutex(const ScopedMutex &);
  ScopedMutex & operator=(const ScopedMutex &);
 
  pthread_mutex_t & m_mutex;
};
 
int register_exec_count_ts(const char * p_exec_count_location, int & p_exec_count);
void reset_exec_count_ts(const char * p_exec_count_location = 0);
pthread_mutex_t & get_mutex();
int register_exec_count(const char * p_exec_count_location, int & p_exec_count);
void reset_exec_count(const char * p_exec_count_location = 0);
std::ostream & print(std::ostream & p_ostream, const char * p_location, int p_exec_count, bool p_condition_value);
 
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
 
#define LOCATION __FILE__ ":" TOSTRING(__LINE__) ":"
 
#define PRINT(p_exec_count, p_condition_value) print(std::cout, LOCATION, (p_exec_count), (p_condition_value))
 
#define EXPRESSION(p_condition)                                     \
  (                                                                 \
  {                                                                 \
    static int exec_count = 0;                                      \
    bool condition = (p_condition);                                 \
    {                                                               \
      ScopedMutex scoped_mutex(get_mutex());                        \
      {                                                             \
        static int tmp = register_exec_count(LOCATION, exec_count); \
        tmp = tmp;                                                  \
      }                                                             \
      PRINT(++exec_count, condition) << #p_condition << std::endl;  \
    }                                                               \
    condition;                                                      \
  }                                                                 \
  )
 
#endif
inspector.cpp
#include "inspector.hpp"
#include <map>
 
static pthread_mutex_t               mutex                = PTHREAD_MUTEX_INITIALIZER ;
static std::map<const char *, int *> exec_count_container                             ;
 
ScopedMutex::ScopedMutex
(
  pthread_mutex_t & p_mutex
):
m_mutex(p_mutex)
{
  pthread_mutex_lock(&m_mutex);
}
 
ScopedMutex::~ScopedMutex()
{
  pthread_mutex_unlock(&m_mutex);
}
 
int register_exec_count_ts
(
  const char * p_exec_count_location,
  int &        p_exec_count
)
{
  ScopedMutex scoped_mutex(mutex);
  return(register_exec_count(p_exec_count_location, p_exec_count));
}
 
void reset_exec_count_ts
(
  const char * p_exec_count_location
)
{
  ScopedMutex scoped_mutex(mutex);
  reset_exec_count(p_exec_count_location);
}
 
pthread_mutex_t & get_mutex()
{
  return(mutex);
}
 
int register_exec_count
(
  const char * p_exec_count_location,
  int &        p_exec_count
)
{
  exec_count_container.insert(std::pair<const char *, int *>(p_exec_count_location, &p_exec_count));
  return(0);
}
 
void reset_exec_count
(
  const char * p_exec_count_location
)
{
  if (!p_exec_count_location)
  {
    for (std::map<const char *, int *>::const_iterator it = exec_count_container.begin();
         it != exec_count_container.end();
         ++it)
    {
      *(it->second) = 0;
    }
  }
  else
  {
    std::map<const char *, int *>::const_iterator it = exec_count_container.find(p_exec_count_location);
    if (it != exec_count_container.end())
    {
      *(it->second) = 0;
    }
  }
}
 
std::ostream & print
(
  std::ostream & p_ostream,
  const char *   p_location,
  int            p_exec_count,
  bool           p_condition_value
)
{
  if (0 < p_exec_count)
  {
    p_ostream
        << p_location                                              << "@"
        << p_exec_count                                            << "@"
        << std::boolalpha << p_condition_value << std::noboolalpha << "@";
  }
  else
  {
    p_ostream
        << p_location << "@"
        << "N/A"      << "@"
        << "N/A"      << "@";
  }
  return(p_ostream);
}
 
#define if(p_condition) if(EXPRESSION(p_condition))
#define while(p_condition) while(EXPRESSION(p_condition))
 
void foo()
{
  if (0 == 0) ;
 
  EXPRESSION(1 != 1);
}
 
int main()
{
  foo();
  foo();
 
  reset_exec_count_ts();
 
  foo();
 
  PRINT(0, false) << "end of program" << std::endl;
 
  return(0);
}
 
#undef if
#undef while
./inspector | column -t -s @
inspector.cpp:109:  1    true   0 == 0
inspector.cpp:111:  1    false  1 != 1
inspector.cpp:109:  2    true   0 == 0
inspector.cpp:111:  2    false  1 != 1
inspector.cpp:109:  1    true   0 == 0
inspector.cpp:111:  1    false  1 != 1
inspector.cpp:123:  N/A  N/A    end of program
mutex.txt · Last modified: 2022/04/16 12:23 (external edit)
 
Except where otherwise noted, content on this wiki is licensed under the following license: CC Attribution-Share Alike 3.0 Unported
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki