00001
00002
00003
00004 #include "internal.h"
00005
00006
00007
00008 #ifndef tm_USE_times
00009
00010 #define tm_USE_times 0
00011 #endif
00012
00013 #if tm_USE_times
00014
00015 #include <sys/times.h>
00016
00017 #else
00018
00019 #include <sys/time.h>
00020 #include <unistd.h>
00021
00022 static __inline double tv_2_double(struct timeval *t)
00023 {
00024 return (double) t->tv_sec + (double) t->tv_usec / 1000000.0;
00025 }
00026 #endif
00027
00028
00029
00030
00031
00032 static
00033 void _tm_print_utilization(const char *name, tm_type *t, size_t *n, int nn, size_t *sum)
00034 {
00035 int j;
00036
00037 tm_msg(name);
00038
00039
00040 if ( nn > tm_NU ) {
00041 switch ( tm.phase ) {
00042 case tm_ALLOC:
00043 case tm_UNMARK:
00044 case tm_ROOT:
00045 case tm_SCAN:
00046 n[tm_NU] = n[tm_ECRU] + n[tm_GREY] + n[tm_BLACK];
00047 break;
00048
00049 case tm_SWEEP:
00050 n[tm_NU] = n[tm_GREY] + n[tm_BLACK];
00051 break;
00052
00053 default:
00054 tm_abort();
00055 }
00056 if ( sum && sum != n )
00057 sum[tm_NU] += n[tm_NU];
00058 }
00059
00060
00061
00062 if ( sum != n ) {
00063 if ( nn > tm_b ) {
00064 n[tm_b] = t ? n[tm_NU] * t->size : 0;
00065 if ( sum )
00066 sum[tm_b] += n[tm_b];
00067 }
00068
00069
00070 if ( nn > tm_b_NU ) {
00071 n[tm_b_NU] = n[tm_NU] ? n[tm_b] / n[tm_NU] : 0;
00072 if ( sum )
00073 sum[tm_b_NU] = sum[tm_NU] ? sum[tm_b] / sum[tm_NU] : 0;
00074 }
00075
00076 }
00077
00078
00079 for ( j = 0; j < nn; j ++ ) {
00080 if ( sum && sum != n && j <= tm_B ) {
00081 sum[j] += n[j];
00082 }
00083 tm_msg1("%c%-4lu ", tm_color_name[j][0], (unsigned long) n[j]);
00084 }
00085
00086 tm_msg1("\n");
00087 }
00088
00089
00090
00091
00092
00093 void tm_print_stats()
00094 {
00095 tm_type *t;
00096 size_t sum[tm__LAST3];
00097
00098 memset(sum, 0, sizeof(sum));
00099
00100 tm_msg_enable("X", 1);
00101
00102 tm_msg("X { t#%d : blk_in_use %lu[~%lu], blk_free %lu[~%lu]\n",
00103 tm.type_id,
00104 tm.n[tm_B],
00105 tm.n[tm_B] * tm_block_SIZE,
00106 tm.free_blocks_n,
00107 tm.free_blocks_n * tm_block_SIZE
00108 );
00109
00110 tm_list_LOOP(&tm.types, t);
00111 {
00112 tm_msg("X t#%d S%-6lu\n", t->id, (unsigned long) t->size, (unsigned) t->n[tm_B]);
00113 _tm_print_utilization("X ", t, t->n, sizeof(t->n)/sizeof(t->n[0]), sum);
00114 }
00115 tm_list_LOOP_END;
00116
00117
00118 sum[tm_B_OS] = tm.n[tm_B_OS];
00119 sum[tm_b_OS] = tm.n[tm_b_OS];
00120 sum[tm_B_OS_M] = tm.n[tm_B_OS_M];
00121 sum[tm_b_OS_M] = tm.n[tm_b_OS_M];
00122
00123 _tm_print_utilization("X S ", 0, sum, sizeof(sum)/sizeof(sum[0]), sum);
00124
00125 tm_msg("X }\n");
00126
00127 tm_msg_enable("X", 0);
00128
00129 tm_print_time_stats();
00130
00131 tm_print_color_transition_stats();
00132
00133 tm_print_phase_transition_stats();
00134
00135
00136 }
00137
00138
00139
00140
00141
00142 void tm_print_color_transition_stats()
00143 {
00144 int i, j;
00145
00146
00147
00148 tm_msg_enable("C", 1);
00149 tm_msg("C { color transitions \n");
00150
00151 tm_msg("C %-10s ", "from\\to");
00152 for ( i = 0; i <= tm_TOTAL; ++ i ) {
00153 tm_msg1("%-10s ", tm_color_name[i]);
00154 }
00155 tm_msg1("\n");
00156
00157
00158 for ( i = 0; i <= tm_TOTAL; ++ i ) {
00159 tm_msg("C %-10s ", tm_color_name[i]);
00160 for ( j = 0; j <= tm_TOTAL; ++ j ) {
00161 tm_msg1("%-10lu ", (unsigned long) tm.n_color_transitions[i][j]);
00162 }
00163 tm_msg1("\n");
00164 }
00165
00166 tm_msg("C }\n");
00167 tm_msg_enable("C", 0);
00168 }
00169
00170
00171
00172
00173
00174
00175 void tm_print_phase_transition_stats()
00176 {
00177 int i, j;
00178
00179
00180
00181 tm_msg_enable("P", 1);
00182 tm_msg("P { phase transitions \n");
00183
00184 tm_msg("P %-10s ", "from\\to");
00185 for ( i = 0; i <= tm_phase_END; ++ i ) {
00186 tm_msg1("%-10s ", tm_phase_name[i]);
00187 }
00188 tm_msg1("\n");
00189
00190
00191 for ( i = 0; i <= tm_phase_END; ++ i ) {
00192 tm_msg("P %-10s ", tm_phase_name[i]);
00193 for ( j = 0; j <= tm_phase_END; ++ j ) {
00194 tm_msg1("%-10lu ", (unsigned long) tm.n_phase_transitions[i][j]);
00195 }
00196 tm_msg1("\n");
00197 }
00198
00199 tm_msg("P }\n");
00200 tm_msg_enable("P", 0);
00201 }
00202
00203
00204
00205
00206
00207
00208 void tm_print_block_stats()
00209 {
00210 tm_type *t;
00211
00212 tm_block *b;
00213
00214 tm_msg_enable("X", 1);
00215
00216 tm_msg("X { b tb%lu[%lu] block_id %d\n",
00217 tm.n[tm_B],
00218 tm.n[tm_B] * tm_block_SIZE,
00219 tm.block_id
00220 );
00221
00222 tm_list_LOOP(&tm.types, t);
00223 {
00224 tm_msg("X t#%d @%p s%lu \n", t->id, (void*) t, (unsigned long) t->size);
00225
00226 tm_list_LOOP(&t->blocks, b);
00227 {
00228 int j;
00229
00230 _tm_block_validate(b);
00231
00232 tm_msg("X b#%d @%p s%lu ", (int) b->id, (void*) b, (unsigned long) b->size);
00233
00234 for ( j = 0; j < sizeof(b->n)/sizeof(b->n[0]); j ++ ) {
00235 tm_msg1("%c%-4lu ", tm_color_name[j][0], (unsigned long) b->n[j]);
00236 }
00237
00238
00239 tm_msg1("T/b%3d%% ",
00240 (int) ((b->n[tm_TOTAL] * 100) / b->n[tm_CAPACITY])
00241 );
00242
00243
00244 tm_msg1("(T-W)/b%3d%% ",
00245 (int) (((b->n[tm_TOTAL] - b->n[tm_WHITE]) * 100) / b->n[tm_CAPACITY])
00246 );
00247
00248 tm_msg1("\n");
00249 }
00250 tm_list_LOOP_END;
00251 }
00252 tm_list_LOOP_END;
00253
00254 tm_msg("X }\n");
00255
00256 tm_msg_enable("X", 0);
00257 }
00258
00259
00260
00261
00262
00263 void tm_time_stat_print_(tm_time_stat *ts, int flags, size_t *alloc_count_p);
00264
00265
00266
00267
00268
00269 void tm_time_stat_begin(tm_time_stat *ts)
00270 {
00271 #if tm_USE_times
00272 struct tms t0;
00273 times(&t0);
00274 ts->t0 = (double) t0.tms_utime / (double) CLOCKS_PER_SEC;
00275 ts->t01 = (double) t0.tms_stime / (double) CLOCKS_PER_SEC;
00276 #else
00277 struct timeval t0;
00278 gettimeofday(&t0, 0);
00279 ts->t0 = tv_2_double(&t0);
00280 #endif
00281 }
00282
00283
00284
00285
00286
00287 void tm_time_stat_end(tm_time_stat *ts)
00288 {
00289 #if tm_USE_times
00290 {
00291 struct tms t1;
00292 times(&t1);
00293 ts->t1 = (double) t1.tms_utime / (double) CLOCKS_PER_SEC;
00294 ts->t11 = (double) t1.tms_stime / (double) CLOCKS_PER_SEC;
00295 }
00296 #else
00297 {
00298 struct timeval t1;
00299 gettimeofday(&t1, 0);
00300 ts->t1 = tv_2_double(&t1);
00301 }
00302 #endif
00303
00304 ++ ts->count;
00305
00306
00307 ts->td = ts->t1 - ts->t0;
00308 #if tm_USE_times
00309 ts->td += ts->t11 - ts->t01;
00310 #endif
00311
00312
00313 ts->ts += ts->td;
00314
00315
00316 ts->ta = ts->ts / (double) ts->count;
00317
00318
00319 if ( (ts->tw_changed = ts->tw < ts->td) ) {
00320 ts->tw = ts->td;
00321 }
00322
00323 #if 0
00324
00325 tm_time_stat_print_(ts, ts->tw_changed ? 1 : 0, 0);
00326 #endif
00327 }
00328
00329
00330
00331
00332 void tm_time_stat_print_(tm_time_stat *ts, int flags, size_t *alloc_count_p)
00333 {
00334 #define tv_fmt "%.7f"
00335 #define tv_fmt_s "%8.4f"
00336 #define tv_fmt_args(V) (double) (V)
00337
00338 tm_msg("T %-12s "
00339 ,
00340 ts->name);
00341
00342 if ( ! (flags & (2|4)) ) {
00343 tm_msg1(
00344 " dt " tv_fmt
00345 ,
00346 tv_fmt_args(ts->td)
00347 );
00348 }
00349
00350 tm_msg1(
00351 " st " tv_fmt_s
00352 ,
00353 tv_fmt_args(ts->ts)
00354 );
00355
00356 if ( flags & 1 ) {
00357 tm_msg1(
00358 " wt " tv_fmt
00359 ,
00360 tv_fmt_args(ts->tw)
00361 );
00362 }
00363
00364 if ( flags & 2 ) {
00365 tm_msg1(
00366 " c %8lu"
00367 ,
00368 (unsigned long) ts->count
00369 );
00370 }
00371
00372 if ( flags & 4 ) {
00373 tm_msg1(
00374 " at %.7f"
00375 ,
00376 (double) ts->ta
00377 );
00378 }
00379
00380 if ( alloc_count_p ) {
00381 tm_msg1(
00382 " A %8lu"
00383 ,
00384 (unsigned long) *alloc_count_p
00385 );
00386 }
00387
00388 tm_msg1("\n");
00389 }
00390
00391
00392
00393
00394
00395 void tm_print_time_stats()
00396 {
00397 int i;
00398
00399 tm_msg_enable("T", 1);
00400
00401 tm_msg("T {\n");
00402
00403 tm_time_stat_print_(&tm.ts_os_alloc, ~0, 0);
00404 tm_time_stat_print_(&tm.ts_os_free, ~0, 0);
00405 tm_time_stat_print_(&tm.ts_alloc, ~0, 0);
00406 tm_time_stat_print_(&tm.ts_free, ~0, 0);
00407 tm_time_stat_print_(&tm.ts_gc, ~0, 0);
00408 tm_time_stat_print_(&tm.ts_barrier, ~0, 0);
00409 tm_time_stat_print_(&tm.ts_barrier_pure, ~0, 0);
00410 tm_time_stat_print_(&tm.ts_barrier_root, ~0, 0);
00411 tm_time_stat_print_(&tm.ts_barrier_black, ~0, 0);
00412
00413 for ( i = 0;
00414 i < (sizeof(tm.ts_phase) / sizeof(tm.ts_phase[0]));
00415 ++ i ) {
00416 tm_time_stat_print_(&tm.ts_phase[i], ~0, &tm.alloc_by_phase[i]);
00417 }
00418
00419 tm_msg("T }\n");
00420
00421 tm_msg_enable("T", 0);
00422 }
00423
00424