tlds
Transactional Operations for Linked Data Structures
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
profiling.hpp
Go to the documentation of this file.
1 /**
2  * Copyright (C) 2011
3  * University of Rochester Department of Computer Science
4  * and
5  * Lehigh University Department of Computer Science and Engineering
6  *
7  * License: Modified BSD
8  * Please see the file LICENSE.RSTM for licensing information
9  */
10 
11 #ifndef PROFILING_HPP__
12 #define PROFILING_HPP__
13 
14 /**
15  * This code handles the profiling mechanism. It consists of three parts:
16  *
17  * - The code for requesting that a bunch of profiles are collected
18  *
19  * - The code for calling a policy after the profiles are collected, and using
20  * that result to change the algorithm
21  *
22  * - The code that is called on every commit/abort by any transaction, to
23  * determine when a request should be initiated
24  */
25 
26 #include <cstdlib>
27 #include <stm/config.h> // profiletrigger stuff
28 #include <stm/txthread.hpp>
29 #include "./policies/policies.hpp"
30 
31 namespace stm
32 {
33  /*** After profiles are collected, select and install a new algorithm */
34  void profile_oncomplete(TxThread* tx);
35 
36  /**
37  * custom begin method that blocks the starting thread, in order to get
38  * rendezvous correct during mode switching and GRL irrevocability
39  * (implemented in irrevocability.cpp because it uses some static functions
40  * declared there)
41  */
42  bool begin_blocker(TxThread* tx) TM_FASTCALL;
43 
44  /**
45  * This is the code for deciding whether to adapt or not. It's a little bit
46  * messy because we want to limit what gets inlined.
47  */
48 
49  /**
50  * part 1: the thing that never gets inlined, and only gets called if we are
51  * definitely going to adapt
52  */
53 
54  void trigger_common(TxThread* tx) TM_FASTCALL NOINLINE;
55 
56  /**
57  * A simple trigger: request collection of profiles after 16 consecutive
58  * aborts, or on a begin-time wait of >=2048
59  */
61  {
62  /**
63  * Part 2: the thing that gets inlined into commit for STMs that have
64  * long blocking at begin time (TML, CGL, Serial, MCS, Ticket), and gets
65  * called on every commit
66  */
67  TM_INLINE
68  static void onCommitLock(TxThread* tx)
69  {
70  // if we don't have a function for changing algs, then we should just
71  // return
72  if (!pols[curr_policy.POL_ID].decider)
73  return;
74  // return if we didn't wait long enough
75  if (tx->begin_wait <= (unsigned)curr_policy.waitThresh)
76  return;
77  // ok, we're going to adapt. Call the common adapt code
78  trigger_common(tx);
79  }
80 
81  /**
82  * This trigger does nothing when an STM transaction commits
83  */
84  static void onCommitSTM(TxThread*) { }
85 
86  /**
87  * Part 3: the thing that gets inlined into stm abort, and gets called
88  * on every abort
89  */
90  TM_INLINE
91  static void onAbort(TxThread* tx)
92  {
93  // if we don't have a function for changing algs, then we should just
94  // return
95  if (!pols[curr_policy.POL_ID].decider)
96  return;
97  // return if we didn't abort enough
98  if (tx->consec_aborts <= (unsigned)curr_policy.abortThresh)
99  return;
100  // ok, we're going to adapt. Call the common adapt code
101  curr_policy.abort_switch = true;
102  trigger_common(tx);
103  }
104  };
105 
106  /**
107  * This trigger does nothing, and is only around as a baseline
108  */
110  {
111  static void onCommitLock(TxThread*) { }
112  static void onCommitSTM(TxThread*) { }
113  static void onAbort(TxThread*) { }
114  };
115 
116  /**
117  * This is the trigger we are currently favoring: request collection of
118  * profiles on 16 consecutive aborts, or when thread 2's commit count
119  * matches an exponentially decaying pattern.
120  */
122  {
123  /**
124  * Track the next time to run a trigger. "time" means the next number
125  * of commits in thread2 that necessitates a trigger.
126  */
127  static unsigned next;
128 
129  /*** Instead of looking at delays, we just count commits */
130  static void onCommitLock(TxThread* tx) { onCommitSTM(tx); }
131 
132  /*** Count commits to decide if we should request a new profile */
133  static void onCommitSTM(TxThread* tx)
134  {
135  // if we don't have a function for changing algs, then we should just
136  // return
137  if (!pols[curr_policy.POL_ID].decider)
138  return;
139  // return if this policy doesn't allow commit-time probing
141  return;
142  // return if not thread#2
143  if (tx->id != 2)
144  return;
145  // return if not a trigger commit number
146  unsigned c = tx->num_ro + tx->num_commits;
147  if (c != next)
148  return;
149  // update the trigger commit number
150  if (next < 65536)
151  next = next * 16;
152  else if (next < 524288)
153  next += 65536;
154  else
155  next += 524288;
156 
157  // record that this is a non-abort trigger, and call the adapt code
158  //
159  // NB: this write could be racy if another thread is aborting at
160  // same time. In that case, both threads are trying to request
161  // collection of profiles, so it really doesn't matter.
162  curr_policy.abort_switch = false;
163  // ok, we're going to adapt. Call the common adapt code
164  trigger_common(tx);
165  }
166 
167  /**
168  * Part 3: the thing that gets inlined into stm abort, and gets called
169  * on every abort. It's the same as in AbortWaitTrigger
170  */
172  };
173 
174 #ifdef STM_PROFILETMTRIGGER_ALL
175  typedef CommitTrigger Trigger;
176 #elif defined(STM_PROFILETMTRIGGER_PATHOLOGY)
177  typedef AbortWaitTrigger Trigger;
178 #elif defined(STM_PROFILETMTRIGGER_NONE)
179  typedef EmptyTrigger Trigger;
180 #endif
181 
182 } // namespace stm
183 
184 #endif // PROFILING_HPP__
#define NOINLINE
Definition: platform.hpp:48
static void onAbort(TxThread *tx)
Definition: profiling.hpp:171
uint32_t begin_wait
Definition: txthread.hpp:87
bool abort_switch
Definition: policies.hpp:78
Definition: stm_fraser.c:61
uint32_t id
Definition: txthread.hpp:50
int abortThresh
Definition: policies.hpp:82
void profile_oncomplete(TxThread *tx)
Definition: profiling.cpp:113
static TM_INLINE void onAbort(TxThread *tx)
Definition: profiling.hpp:91
pol_t pols[POL_MAX]
Definition: policies.cpp:107
uint32_t POL_ID
Definition: policies.hpp:69
Definition: profiling.hpp:121
uint32_t num_ro
Definition: txthread.hpp:56
Definition: profiling.hpp:60
void trigger_common(TxThread *tx)
Definition: profiling.cpp:144
bool isCommitProfile
Definition: policies.hpp:52
bool begin_blocker(TxThread *tx)
Definition: irrevocability.cpp:213
#define TM_INLINE
Definition: platform.hpp:77
static void onAbort(TxThread *)
Definition: profiling.hpp:113
stm_tx * tx
Definition: stmskip.cc:245
static void onCommitLock(TxThread *)
Definition: profiling.hpp:111
behavior_t curr_policy
Definition: policies.cpp:108
static void onCommitLock(TxThread *tx)
Definition: profiling.hpp:130
static TM_INLINE void onCommitLock(TxThread *tx)
Definition: profiling.hpp:68
uint32_t num_commits
Definition: txthread.hpp:53
uint32_t consec_aborts
Definition: txthread.hpp:71
static void onCommitSTM(TxThread *)
Definition: profiling.hpp:84
int waitThresh
Definition: policies.hpp:83
static unsigned next
Definition: profiling.hpp:127
Definition: txthread.hpp:47
static void onCommitSTM(TxThread *)
Definition: profiling.hpp:112
Definition: profiling.hpp:109
static void onCommitSTM(TxThread *tx)
Definition: profiling.hpp:133
#define TM_FASTCALL
Definition: platform.hpp:85