Static Value-Flow Analysis
Public Types | Public Member Functions | Static Public Member Functions | Private Member Functions | Private Attributes | Static Private Attributes | List of all members
SVF::ThreadAPI Class Reference

#include <ThreadAPI.h>

Public Types

enum  TD_TYPE {
  TD_DUMMY = 0 , TD_FORK , TD_JOIN , TD_DETACH ,
  TD_ACQUIRE , TD_TRY_ACQUIRE , TD_RELEASE , TD_EXIT ,
  TD_CANCEL , TD_COND_WAIT , TD_COND_SIGNAL , TD_COND_BROADCAST ,
  TD_MUTEX_INI , TD_MUTEX_DESTROY , TD_CONDVAR_INI , TD_CONDVAR_DESTROY ,
  TD_BAR_INIT , TD_BAR_WAIT , HARE_PAR_FOR
}
 
typedef Map< std::string, TD_TYPETDAPIMap
 

Public Member Functions

const SVFVargetForkedThread (const CallICFGNode *inst) const
 Return arguments/attributes of pthread_create / hare_parallel_for. More...
 
const SVFVargetForkedFun (const CallICFGNode *inst) const
 
const SVFVargetActualParmAtForkSite (const CallICFGNode *inst) const
 
const SVFVargetFormalParmOfForkedFun (const SVFFunction *F) const
 Return the formal parm of forked function (the first arg in pthread) More...
 
bool isTDFork (const CallICFGNode *inst) const
 Return true if this call create a new thread. More...
 
bool isTDJoin (const CallICFGNode *inst) const
 Return true if this call wait for a worker thread. More...
 
const SVFVargetJoinedThread (const CallICFGNode *inst) const
 Return arguments/attributes of pthread_join. More...
 
const SVFVargetRetParmAtJoinedSite (const CallICFGNode *inst) const
 
bool isTDExit (const CallICFGNode *inst) const
 Return true if this call exits/terminate a thread. More...
 
bool isTDAcquire (const CallICFGNode *inst) const
 Return true if this call acquire a lock. More...
 
bool isTDRelease (const CallICFGNode *inst) const
 Return true if this call release a lock. More...
 
const SVFVargetLockVal (const ICFGNode *inst) const
 Return lock value. More...
 
bool isTDBarWait (const CallICFGNode *inst) const
 Return true if this call waits for a barrier. More...
 
void performAPIStat (SVFModule *m)
 
void statInit (Map< std::string, u32_t > &tdAPIStatMap)
 

Static Public Member Functions

static ThreadAPIgetThreadAPI ()
 Return a static reference. More...
 
static void destroy ()
 

Private Member Functions

 ThreadAPI ()
 Constructor. More...
 
void init ()
 Initialize the map. More...
 
TD_TYPE getType (const SVFFunction *F) const
 Get the function type if it is a threadAPI function. More...
 

Private Attributes

TDAPIMap tdAPIMap
 API map, from a string to threadAPI type. More...
 

Static Private Attributes

static ThreadAPItdAPI = nullptr
 Static reference. More...
 

Detailed Description

Definition at line 46 of file ThreadAPI.h.

Member Typedef Documentation

◆ TDAPIMap

Definition at line 73 of file ThreadAPI.h.

Member Enumeration Documentation

◆ TD_TYPE

Enumerator
TD_DUMMY 
TD_FORK 

dummy type

TD_JOIN 

create a new thread

TD_DETACH 

wait for a thread to join

TD_ACQUIRE 

detach a thread directly instead wait for it to join

TD_TRY_ACQUIRE 

acquire a lock

TD_RELEASE 

try to acquire a lock

TD_EXIT 

release a lock

TD_CANCEL 

exit/kill a thread

TD_COND_WAIT 

cancel a thread by another

TD_COND_SIGNAL 

wait a condition

TD_COND_BROADCAST 

signal a condition

TD_MUTEX_INI 

broadcast a condition

TD_MUTEX_DESTROY 

initial a mutex variable

TD_CONDVAR_INI 

initial a mutex variable

TD_CONDVAR_DESTROY 

initial a mutex variable

TD_BAR_INIT 

initial a mutex variable

TD_BAR_WAIT 

Barrier init.

HARE_PAR_FOR 

Barrier wait.

Definition at line 50 of file ThreadAPI.h.

51  {
52  TD_DUMMY = 0,
53  TD_FORK,
54  TD_JOIN,
55  TD_DETACH,
56  TD_ACQUIRE,
58  TD_RELEASE,
59  TD_EXIT,
60  TD_CANCEL,
61  TD_COND_WAIT,
64  TD_MUTEX_INI,
68  TD_BAR_INIT,
69  TD_BAR_WAIT,
71  };
@ TD_COND_SIGNAL
wait a condition
Definition: ThreadAPI.h:62
@ TD_DETACH
wait for a thread to join
Definition: ThreadAPI.h:55
@ TD_CONDVAR_INI
initial a mutex variable
Definition: ThreadAPI.h:66
@ HARE_PAR_FOR
Barrier wait.
Definition: ThreadAPI.h:70
@ TD_BAR_INIT
initial a mutex variable
Definition: ThreadAPI.h:68
@ TD_ACQUIRE
detach a thread directly instead wait for it to join
Definition: ThreadAPI.h:56
@ TD_MUTEX_DESTROY
initial a mutex variable
Definition: ThreadAPI.h:65
@ TD_FORK
dummy type
Definition: ThreadAPI.h:53
@ TD_CONDVAR_DESTROY
initial a mutex variable
Definition: ThreadAPI.h:67
@ TD_JOIN
create a new thread
Definition: ThreadAPI.h:54
@ TD_BAR_WAIT
Barrier init.
Definition: ThreadAPI.h:69
@ TD_COND_BROADCAST
signal a condition
Definition: ThreadAPI.h:63
@ TD_COND_WAIT
cancel a thread by another
Definition: ThreadAPI.h:61
@ TD_TRY_ACQUIRE
acquire a lock
Definition: ThreadAPI.h:57
@ TD_MUTEX_INI
broadcast a condition
Definition: ThreadAPI.h:64
@ TD_RELEASE
try to acquire a lock
Definition: ThreadAPI.h:58
@ TD_EXIT
release a lock
Definition: ThreadAPI.h:59
@ TD_CANCEL
exit/kill a thread
Definition: ThreadAPI.h:60

Constructor & Destructor Documentation

◆ ThreadAPI()

SVF::ThreadAPI::ThreadAPI ( )
inlineprivate

Constructor.

Definition at line 80 of file ThreadAPI.h.

81  {
82  init();
83  }
void init()
Initialize the map.
Definition: ThreadAPI.cpp:103

Member Function Documentation

◆ destroy()

static void SVF::ThreadAPI::destroy ( )
inlinestatic

Definition at line 114 of file ThreadAPI.h.

115  {
116  if(tdAPI != nullptr)
117  {
118  delete tdAPI;
119  tdAPI = nullptr;
120  }
121  }
static ThreadAPI * tdAPI
Static reference.
Definition: ThreadAPI.h:89

◆ getActualParmAtForkSite()

const SVFVar * ThreadAPI::getActualParmAtForkSite ( const CallICFGNode inst) const

Return the forth argument of the call, Note that, it is the sole argument of start routine ( a void* pointer )

Definition at line 178 of file ThreadAPI.cpp.

179 {
180  assert(isTDFork(inst) && "not a thread fork function!");
181  return inst->getArgument(3);
182 }
const SVFVar * getArgument(u32_t ArgNo) const
Parameter operations.
Definition: ICFGNode.h:500
bool isTDFork(const CallICFGNode *inst) const
Return true if this call create a new thread.
Definition: ThreadAPI.cpp:133

◆ getForkedFun()

const SVFVar * ThreadAPI::getForkedFun ( const CallICFGNode inst) const

Return the third argument of the call, Note that, it could be function type or a void* pointer

Definition at line 170 of file ThreadAPI.cpp.

171 {
172  assert(isTDFork(inst) && "not a thread fork function!");
173  return inst->getArgument(2);
174 }

◆ getForkedThread()

const SVFVar * ThreadAPI::getForkedThread ( const CallICFGNode inst) const

Return arguments/attributes of pthread_create / hare_parallel_for.

Return the first argument of the call, Note that, it is the pthread_t pointer

Definition at line 164 of file ThreadAPI.cpp.

165 {
166  assert(isTDFork(inst) && "not a thread fork function!");
167  return inst->getArgument(0);
168 }

◆ getFormalParmOfForkedFun()

const SVFVar * ThreadAPI::getFormalParmOfForkedFun ( const SVFFunction F) const

Return the formal parm of forked function (the first arg in pthread)

Definition at line 184 of file ThreadAPI.cpp.

185 {
186  assert(PAG::getPAG()->hasFunArgsList(F) && "forked function has no args list!");
187  const SVFIR::SVFVarList& funArgList = PAG::getPAG()->getFunArgsList(F);
188  // in pthread, forked functions are of type void *()(void *args)
189  assert(funArgList.size() == 1 && "num of pthread forked function args is not 1!");
190  return funArgList[0];
191 }
#define F(f)
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition: SVFIR.h:115
std::vector< const SVFVar * > SVFVarList
Definition: SVFIR.h:59
const SVFVarList & getFunArgsList(const SVFFunction *func) const
Get function arguments list.
Definition: SVFIR.h:275

◆ getJoinedThread()

const SVFVar * ThreadAPI::getJoinedThread ( const CallICFGNode inst) const

Return arguments/attributes of pthread_join.

Return the first argument of the call, Note that, it is the pthread_t pointer

Definition at line 207 of file ThreadAPI.cpp.

208 {
209  assert(isTDJoin(cs) && "not a thread join function!");
210  const SVFVar* join = cs->getArgument(0);
211  for(const SVFStmt* stmt : join->getInEdges())
212  {
213  if(SVFUtil::isa<LoadStmt>(stmt))
214  return stmt->getSrcNode();
215  }
216  if(SVFUtil::isa<SVFArgument>(join->getValue()))
217  return join;
218 
219  assert(false && "the value of the first argument at join is not a load instruction?");
220  return nullptr;
221 }
const GEdgeSetTy & getInEdges() const
Definition: GenericGraph.h:434
const SVFValue * getValue() const
Get/has methods of the components.
Definition: SVFVariables.h:83
bool isTDJoin(const CallICFGNode *inst) const
Return true if this call wait for a worker thread.
Definition: ThreadAPI.cpp:138

◆ getLockVal()

const SVFVar * ThreadAPI::getLockVal ( const ICFGNode inst) const

Return lock value.

First argument of pthread_mutex_lock/pthread_mutex_unlock

Definition at line 199 of file ThreadAPI.cpp.

200 {
201  const CallICFGNode* call = SVFUtil::dyn_cast<CallICFGNode>(cs);
202  assert(call && "not a call ICFGNode?");
203  assert((isTDAcquire(call) || isTDRelease(call)) && "not a lock acquire or release function");
204  return call->getArgument(0);
205 }
bool isTDRelease(const CallICFGNode *inst) const
Return true if this call release a lock.
Definition: ThreadAPI.cpp:153
bool isTDAcquire(const CallICFGNode *inst) const
Return true if this call acquire a lock.
Definition: ThreadAPI.cpp:148

◆ getRetParmAtJoinedSite()

const SVFVar * ThreadAPI::getRetParmAtJoinedSite ( const CallICFGNode inst) const

Return the send argument of the call, Note that, it is the pthread_t pointer

Definition at line 193 of file ThreadAPI.cpp.

194 {
195  assert(isTDJoin(inst) && "not a thread join function!");
196  return inst->getArgument(1);
197 }

◆ getThreadAPI()

static ThreadAPI* SVF::ThreadAPI::getThreadAPI ( )
inlinestatic

Return a static reference.

Definition at line 105 of file ThreadAPI.h.

106  {
107  if(tdAPI == nullptr)
108  {
109  tdAPI = new ThreadAPI();
110  }
111  return tdAPI;
112  }
ThreadAPI()
Constructor.
Definition: ThreadAPI.h:80

◆ getType()

TD_TYPE SVF::ThreadAPI::getType ( const SVFFunction F) const
inlineprivate

Get the function type if it is a threadAPI function.

Definition at line 92 of file ThreadAPI.h.

93  {
94  if(F)
95  {
96  TDAPIMap::const_iterator it= tdAPIMap.find(F->getName());
97  if(it != tdAPIMap.end())
98  return it->second;
99  }
100  return TD_DUMMY;
101  }
TDAPIMap tdAPIMap
API map, from a string to threadAPI type.
Definition: ThreadAPI.h:77

◆ init()

void ThreadAPI::init ( )
private

Initialize the map.

initialize the map

Definition at line 103 of file ThreadAPI.cpp.

104 {
105  set<TD_TYPE> t_seen;
106  TD_TYPE prev_t= TD_DUMMY;
107  t_seen.insert(TD_DUMMY);
108  for(const ei_pair *p= ei_pairs; p->n; ++p)
109  {
110  if(p->t != prev_t)
111  {
112  //This will detect if you move an entry to another block
113  // but forget to change the type.
114  if(t_seen.count(p->t))
115  {
116  fputs(p->n, stderr);
117  putc('\n', stderr);
118  assert(!"ei_pairs not grouped by type");
119  }
120  t_seen.insert(p->t);
121  prev_t= p->t;
122  }
123  if(tdAPIMap.count(p->n))
124  {
125  fputs(p->n, stderr);
126  putc('\n', stderr);
127  assert(!"duplicate name in ei_pairs");
128  }
129  tdAPIMap[p->n]= p->t;
130  }
131 }
static const ei_pair ei_pairs[]
Definition: ThreadAPI.cpp:61
cJSON * p
Definition: cJSON.cpp:2559

◆ isTDAcquire()

bool ThreadAPI::isTDAcquire ( const CallICFGNode inst) const

Return true if this call acquire a lock.

Definition at line 148 of file ThreadAPI.cpp.

149 {
150  return getType(inst->getCalledFunction()) == TD_ACQUIRE;
151 }
const SVFFunction * getCalledFunction() const
Definition: ICFGNode.h:518
TD_TYPE getType(const SVFFunction *F) const
Get the function type if it is a threadAPI function.
Definition: ThreadAPI.h:92

◆ isTDBarWait()

bool ThreadAPI::isTDBarWait ( const CallICFGNode inst) const

Return true if this call waits for a barrier.

Definition at line 158 of file ThreadAPI.cpp.

159 {
160  return getType(inst->getCalledFunction()) == TD_BAR_WAIT;
161 }

◆ isTDExit()

bool ThreadAPI::isTDExit ( const CallICFGNode inst) const

Return true if this call exits/terminate a thread.

Definition at line 143 of file ThreadAPI.cpp.

144 {
145  return getType(inst->getCalledFunction()) == TD_EXIT;
146 }

◆ isTDFork()

bool ThreadAPI::isTDFork ( const CallICFGNode inst) const

Return true if this call create a new thread.

Definition at line 133 of file ThreadAPI.cpp.

134 {
135  return getType(inst->getCalledFunction()) == TD_FORK;
136 }

◆ isTDJoin()

bool ThreadAPI::isTDJoin ( const CallICFGNode inst) const

Return true if this call wait for a worker thread.

Definition at line 138 of file ThreadAPI.cpp.

139 {
140  return getType(inst->getCalledFunction()) == TD_JOIN;
141 }

◆ isTDRelease()

bool ThreadAPI::isTDRelease ( const CallICFGNode inst) const

Return true if this call release a lock.

Definition at line 153 of file ThreadAPI.cpp.

154 {
155  return getType(inst->getCalledFunction()) == TD_RELEASE;
156 }

◆ performAPIStat()

void ThreadAPI::performAPIStat ( SVFModule m)

Definition at line 266 of file ThreadAPI.cpp.

267 {
268 
269  Map<std::string, u32_t> tdAPIStatMap;
270 
271  statInit(tdAPIStatMap);
272 
273  PTACallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph();
274  for (const auto& item: *svfirCallGraph)
275  {
276  for (SVFFunction::const_iterator bit = (item.second)->getFunction()->begin(), ebit = (item.second)->getFunction()->end(); bit != ebit; ++bit)
277  {
278  const SVFBasicBlock* bb = *bit;
279  for (const auto& svfInst: bb->getICFGNodeList())
280  {
281  if (!SVFUtil::isCallSite(svfInst))
282  continue;
283 
284  const SVFFunction* fun = SVFUtil::cast<CallICFGNode>(svfInst)->getCalledFunction();
285  TD_TYPE type = getType(fun);
286  switch (type)
287  {
288  case TD_FORK:
289  {
290  tdAPIStatMap["pthread_create"]++;
291  break;
292  }
293  case TD_JOIN:
294  {
295  tdAPIStatMap["pthread_join"]++;
296  break;
297  }
298  case TD_ACQUIRE:
299  {
300  tdAPIStatMap["pthread_mutex_lock"]++;
301  break;
302  }
303  case TD_TRY_ACQUIRE:
304  {
305  tdAPIStatMap["pthread_mutex_trylock"]++;
306  break;
307  }
308  case TD_RELEASE:
309  {
310  tdAPIStatMap["pthread_mutex_unlock"]++;
311  break;
312  }
313  case TD_CANCEL:
314  {
315  tdAPIStatMap["pthread_cancel"]++;
316  break;
317  }
318  case TD_EXIT:
319  {
320  tdAPIStatMap["pthread_exit"]++;
321  break;
322  }
323  case TD_DETACH:
324  {
325  tdAPIStatMap["pthread_detach"]++;
326  break;
327  }
328  case TD_COND_WAIT:
329  {
330  tdAPIStatMap["pthread_cond_wait"]++;
331  break;
332  }
333  case TD_COND_SIGNAL:
334  {
335  tdAPIStatMap["pthread_cond_signal"]++;
336  break;
337  }
338  case TD_COND_BROADCAST:
339  {
340  tdAPIStatMap["pthread_cond_broadcast"]++;
341  break;
342  }
343  case TD_CONDVAR_INI:
344  {
345  tdAPIStatMap["pthread_cond_init"]++;
346  break;
347  }
348  case TD_CONDVAR_DESTROY:
349  {
350  tdAPIStatMap["pthread_cond_destroy"]++;
351  break;
352  }
353  case TD_MUTEX_INI:
354  {
355  tdAPIStatMap["pthread_mutex_init"]++;
356  break;
357  }
358  case TD_MUTEX_DESTROY:
359  {
360  tdAPIStatMap["pthread_mutex_destroy"]++;
361  break;
362  }
363  case TD_BAR_INIT:
364  {
365  tdAPIStatMap["pthread_barrier_init"]++;
366  break;
367  }
368  case TD_BAR_WAIT:
369  {
370  tdAPIStatMap["pthread_barrier_wait"]++;
371  break;
372  }
373  case HARE_PAR_FOR:
374  {
375  tdAPIStatMap["hare_parallel_for"]++;
376  break;
377  }
378  case TD_DUMMY:
379  {
380  break;
381  }
382  }
383  }
384  }
385 
386  }
387 
388  std::string name(module->getModuleIdentifier());
389  std::vector<std::string> fullNames = SVFUtil::split(name,'/');
390  if (fullNames.size() > 1)
391  {
392  name = fullNames[fullNames.size() - 1];
393  }
394  SVFUtil::outs() << "################ (program : " << name
395  << ")###############\n";
396  SVFUtil::outs().flags(std::ios::left);
397  unsigned field_width = 20;
398  for (Map<std::string, u32_t>::iterator it = tdAPIStatMap.begin(), eit =
399  tdAPIStatMap.end(); it != eit; ++it)
400  {
401  std::string apiName = it->first;
402  // format out put with width 20 space
403  SVFUtil::outs() << std::setw(field_width) << apiName << " : " << it->second
404  << "\n";
405  }
406  SVFUtil::outs() << "#######################################################"
407  << std::endl;
408 
409 }
newitem type
Definition: cJSON.cpp:2739
const char *const name
Definition: cJSON.h:264
cJSON * item
Definition: cJSON.h:222
const char *const string
Definition: cJSON.h:172
const std::vector< const ICFGNode * > & getICFGNodeList() const
Definition: SVFValue.h:569
std::vector< const SVFBasicBlock * >::const_iterator const_iterator
Definition: SVFValue.h:305
PTACallGraph * getCallGraph()
Definition: SVFIR.h:192
void statInit(Map< std::string, u32_t > &tdAPIStatMap)
Definition: ThreadAPI.cpp:226
bool isCallSite(const SVFValue *val)
Whether an instruction is a call or invoke instruction.
Definition: SVFUtil.h:175
std::vector< std::string > split(const std::string &s, char separator)
Split into two substrings around the first occurrence of a separator string.
Definition: SVFUtil.h:203
std::ostream & outs()
Overwrite llvm::outs()
Definition: SVFUtil.h:50
std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > Map
Definition: GeneralType.h:101

◆ statInit()

void ThreadAPI::statInit ( Map< std::string, u32_t > &  tdAPIStatMap)

Definition at line 226 of file ThreadAPI.cpp.

227 {
228 
229  tdAPIStatMap["pthread_create"] = 0;
230 
231  tdAPIStatMap["pthread_join"] = 0;
232 
233  tdAPIStatMap["pthread_mutex_lock"] = 0;
234 
235  tdAPIStatMap["pthread_mutex_trylock"] = 0;
236 
237  tdAPIStatMap["pthread_mutex_unlock"] = 0;
238 
239  tdAPIStatMap["pthread_cancel"] = 0;
240 
241  tdAPIStatMap["pthread_exit"] = 0;
242 
243  tdAPIStatMap["pthread_detach"] = 0;
244 
245  tdAPIStatMap["pthread_cond_wait"] = 0;
246 
247  tdAPIStatMap["pthread_cond_signal"] = 0;
248 
249  tdAPIStatMap["pthread_cond_broadcast"] = 0;
250 
251  tdAPIStatMap["pthread_cond_init"] = 0;
252 
253  tdAPIStatMap["pthread_cond_destroy"] = 0;
254 
255  tdAPIStatMap["pthread_mutex_init"] = 0;
256 
257  tdAPIStatMap["pthread_mutex_destroy"] = 0;
258 
259  tdAPIStatMap["pthread_barrier_init"] = 0;
260 
261  tdAPIStatMap["pthread_barrier_wait"] = 0;
262 
263  tdAPIStatMap["hare_parallel_for"] = 0;
264 }

Member Data Documentation

◆ tdAPI

ThreadAPI * ThreadAPI::tdAPI = nullptr
staticprivate

Static reference.

Definition at line 89 of file ThreadAPI.h.

◆ tdAPIMap

TDAPIMap SVF::ThreadAPI::tdAPIMap
private

API map, from a string to threadAPI type.

Definition at line 77 of file ThreadAPI.h.


The documentation for this class was generated from the following files: