1 #ifdef TOKU_INSTR_MYSQL_H 2 // This file can be included only from toku_instumentation.h because 3 // it replaces the defintitions for the case if MySQL PFS is available 4 #error "toku_instr_mysql.h can be included only once" 5 #else // TOKU_INSTR_MYSQL_H 6 #define TOKU_INSTR_MYSQL_H 7 8 #include <memory> 9 10 // As these macros are defined in my_global.h 11 // and they are also defined in command line 12 // undefine them here to avoid compilation errors. 13 #undef __STDC_FORMAT_MACROS 14 #undef __STDC_LIMIT_MACROS 15 #include "mysql/psi/mysql_file.h" // PSI_file 16 #include "mysql/psi/mysql_thread.h" // PSI_mutex 17 #include "mysql/psi/mysql_stage.h" // PSI_stage 18 19 #if (MYSQL_VERSION_ID >= 80000) && ( MYSQL_VERSION_ID <= 100000) 20 #include "mysql/psi/mysql_cond.h" 21 #include "mysql/psi/mysql_mutex.h" 22 #include "mysql/psi/mysql_rwlock.h" 23 #endif // (MYSQL_VERSION_ID >= nn) 24 25 #ifndef HAVE_PSI_MUTEX_INTERFACE 26 #error HAVE_PSI_MUTEX_INTERFACE required 27 #endif 28 #ifndef HAVE_PSI_RWLOCK_INTERFACE 29 #error HAVE_PSI_RWLOCK_INTERFACE required 30 #endif 31 #ifndef HAVE_PSI_THREAD_INTERFACE 32 #error HAVE_PSI_THREAD_INTERFACE required 33 #endif 34 35 // Instrumentation keys 36 37 class toku_instr_key { 38 private: 39 pfs_key_t m_id; 40 41 public: toku_instr_key(toku_instr_object_type type,const char * group,const char * name)42 toku_instr_key(toku_instr_object_type type, 43 const char *group, 44 const char *name) { 45 switch (type) { 46 case toku_instr_object_type::mutex: { 47 PSI_mutex_info mutex_info{&m_id, name, 0}; 48 mysql_mutex_register(group, &mutex_info, 1); 49 } break; 50 case toku_instr_object_type::rwlock: { 51 PSI_rwlock_info rwlock_info{&m_id, name, 0}; 52 mysql_rwlock_register(group, &rwlock_info, 1); 53 } break; 54 case toku_instr_object_type::cond: { 55 PSI_cond_info cond_info{&m_id, name, 0}; 56 mysql_cond_register(group, &cond_info, 1); 57 } break; 58 case toku_instr_object_type::thread: { 59 PSI_thread_info thread_info{&m_id, name, 0}; 60 mysql_thread_register(group, &thread_info, 1); 61 } break; 62 case toku_instr_object_type::file: { 63 PSI_file_info file_info{&m_id, name, 0}; 64 mysql_file_register(group, &file_info, 1); 65 } break; 66 } 67 } 68 toku_instr_key(pfs_key_t key_id)69 explicit toku_instr_key(pfs_key_t key_id) : m_id(key_id) {} 70 id()71 pfs_key_t id() const { return m_id; } 72 }; 73 74 // Thread instrumentation 75 int toku_pthread_create(const toku_instr_key &key, 76 pthread_t *thread, 77 const pthread_attr_t *attr, 78 void *(*start_routine)(void *), 79 void *arg); 80 void toku_instr_register_current_thread(const toku_instr_key &key); 81 void toku_instr_delete_current_thread(); 82 83 // I/O instrumentation 84 85 enum class toku_instr_file_op { 86 file_stream_open = PSI_FILE_STREAM_OPEN, 87 file_create = PSI_FILE_CREATE, 88 file_open = PSI_FILE_OPEN, 89 file_delete = PSI_FILE_DELETE, 90 file_rename = PSI_FILE_RENAME, 91 file_read = PSI_FILE_READ, 92 file_write = PSI_FILE_WRITE, 93 file_sync = PSI_FILE_SYNC, 94 file_stream_close = PSI_FILE_STREAM_CLOSE, 95 file_close = PSI_FILE_CLOSE, 96 file_stat = PSI_FILE_STAT 97 }; 98 99 struct toku_io_instrumentation { 100 struct PSI_file_locker *locker; 101 PSI_file_locker_state state; 102 toku_io_instrumentationtoku_io_instrumentation103 toku_io_instrumentation() : locker(nullptr) {} 104 }; 105 106 void toku_instr_file_open_begin(toku_io_instrumentation &io_instr, 107 const toku_instr_key &key, 108 toku_instr_file_op op, 109 const char *name, 110 const char *src_file, 111 int src_line); 112 void toku_instr_file_stream_open_end(toku_io_instrumentation &io_instr, 113 TOKU_FILE &file); 114 void toku_instr_file_open_end(toku_io_instrumentation &io_instr, int fd); 115 void toku_instr_file_name_close_begin(toku_io_instrumentation &io_instr, 116 const toku_instr_key &key, 117 toku_instr_file_op op, 118 const char *name, 119 const char *src_file, 120 int src_line); 121 void toku_instr_file_stream_close_begin(toku_io_instrumentation &io_instr, 122 toku_instr_file_op op, 123 const TOKU_FILE &file, 124 const char *src_file, 125 int src_line); 126 void toku_instr_file_fd_close_begin(toku_io_instrumentation &io_instr, 127 toku_instr_file_op op, 128 int fd, 129 const char *src_file, 130 int src_line); 131 void toku_instr_file_close_end(const toku_io_instrumentation &io_instr, 132 int result); 133 void toku_instr_file_io_begin(toku_io_instrumentation &io_instr, 134 toku_instr_file_op op, 135 int fd, 136 ssize_t count, 137 const char *src_file, 138 int src_line); 139 void toku_instr_file_name_io_begin(toku_io_instrumentation &io_instr, 140 const toku_instr_key &key, 141 toku_instr_file_op op, 142 const char *name, 143 ssize_t count, 144 const char *src_file, 145 int src_line); 146 void toku_instr_file_stream_io_begin(toku_io_instrumentation &io_instr, 147 toku_instr_file_op op, 148 const TOKU_FILE &file, 149 ssize_t count, 150 const char *src_file, 151 int src_line); 152 void toku_instr_file_io_end(toku_io_instrumentation &io_instr, ssize_t count); 153 154 // Mutex instrumentation 155 156 struct toku_mutex_instrumentation { 157 struct PSI_mutex_locker *locker; 158 PSI_mutex_locker_state state; 159 toku_mutex_instrumentationtoku_mutex_instrumentation160 toku_mutex_instrumentation() : locker(nullptr) {} 161 }; 162 163 void toku_instr_mutex_init(const toku_instr_key &key, toku_mutex_t &mutex); 164 void toku_instr_mutex_destroy(PSI_mutex *&mutex_instr); 165 void toku_instr_mutex_lock_start(toku_mutex_instrumentation &mutex_instr, 166 toku_mutex_t &mutex, 167 const char *src_file, 168 int src_line); 169 void toku_instr_mutex_trylock_start(toku_mutex_instrumentation &mutex_instr, 170 toku_mutex_t &mutex, 171 const char *src_file, 172 int src_line); 173 void toku_instr_mutex_lock_end(toku_mutex_instrumentation &mutex_instr, 174 int pthread_mutex_lock_result); 175 void toku_instr_mutex_unlock(PSI_mutex *mutex_instr); 176 177 // Instrumentation probes 178 179 class toku_instr_probe_pfs { 180 private: 181 std::unique_ptr<toku_mutex_t> mutex; 182 toku_mutex_instrumentation mutex_instr; 183 184 public: 185 explicit toku_instr_probe_pfs(const toku_instr_key &key); 186 187 ~toku_instr_probe_pfs(); 188 start_with_source_location(const char * src_file,int src_line)189 void start_with_source_location(const char *src_file, int src_line) { 190 mutex_instr.locker = nullptr; 191 toku_instr_mutex_lock_start(mutex_instr, *mutex, src_file, src_line); 192 } 193 stop()194 void stop() { toku_instr_mutex_lock_end(mutex_instr, 0); } 195 }; 196 197 typedef toku_instr_probe_pfs toku_instr_probe; 198 199 // Condvar instrumentation 200 201 struct toku_cond_instrumentation { 202 struct PSI_cond_locker *locker; 203 PSI_cond_locker_state state; 204 toku_cond_instrumentationtoku_cond_instrumentation205 toku_cond_instrumentation() : locker(nullptr) {} 206 }; 207 208 enum class toku_instr_cond_op { 209 cond_wait = PSI_COND_WAIT, 210 cond_timedwait = PSI_COND_TIMEDWAIT, 211 }; 212 213 void toku_instr_cond_init(const toku_instr_key &key, toku_cond_t &cond); 214 void toku_instr_cond_destroy(PSI_cond *&cond_instr); 215 void toku_instr_cond_wait_start(toku_cond_instrumentation &cond_instr, 216 toku_instr_cond_op op, 217 toku_cond_t &cond, 218 toku_mutex_t &mutex, 219 const char *src_file, 220 int src_line); 221 void toku_instr_cond_wait_end(toku_cond_instrumentation &cond_instr, 222 int pthread_cond_wait_result); 223 void toku_instr_cond_signal(const toku_cond_t &cond); 224 void toku_instr_cond_broadcast(const toku_cond_t &cond); 225 226 // rwlock instrumentation 227 228 struct toku_rwlock_instrumentation { 229 struct PSI_rwlock_locker *locker; 230 PSI_rwlock_locker_state state; 231 toku_rwlock_instrumentationtoku_rwlock_instrumentation232 toku_rwlock_instrumentation() : locker(nullptr) { } 233 }; 234 235 void toku_instr_rwlock_init(const toku_instr_key &key, 236 toku_pthread_rwlock_t &rwlock); 237 void toku_instr_rwlock_destroy(PSI_rwlock *&rwlock_instr); 238 void toku_instr_rwlock_rdlock_wait_start( 239 toku_rwlock_instrumentation &rwlock_instr, 240 toku_pthread_rwlock_t &rwlock, 241 const char *src_file, 242 int src_line); 243 void toku_instr_rwlock_wrlock_wait_start( 244 toku_rwlock_instrumentation &rwlock_instr, 245 toku_pthread_rwlock_t &rwlock, 246 const char *src_file, 247 int src_line); 248 void toku_instr_rwlock_rdlock_wait_end( 249 toku_rwlock_instrumentation &rwlock_instr, 250 int pthread_rwlock_wait_result); 251 void toku_instr_rwlock_wrlock_wait_end( 252 toku_rwlock_instrumentation &rwlock_instr, 253 int pthread_rwlock_wait_result); 254 void toku_instr_rwlock_unlock(toku_pthread_rwlock_t &rwlock); 255 256 #endif // TOKU_INSTR_MYSQL_H 257