00001
00002
00003
00004
00005
00006 #ifndef _tredmill_INTERNAL_H
00007 #define _tredmill_INTERNAL_H
00008
00009
00010
00011 #include "tm.h"
00012 #include <limits.h>
00013 #include <sys/time.h>
00014 #include <setjmp.h>
00015
00016 #include "tredmill/list.h"
00017 #include "tredmill/config.h"
00018 #include "tredmill/color.h"
00019 #include "tredmill/debug.h"
00020 #include "tredmill/node.h"
00021 #include "tredmill/block.h"
00022 #include "tredmill/type.h"
00023 #include "tredmill/stats.h"
00024 #include "tredmill/barrier.h"
00025
00026 #include "util/bitset.h"
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 enum tm_phase {
00041
00042 tm_ALLOC,
00043
00044 tm_UNMARK,
00045
00046 tm_ROOT,
00047
00048 tm_SCAN,
00049
00050 tm_SWEEP,
00051
00052 tm_phase_END
00053 };
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 typedef struct tm_root {
00069
00070 const char *name;
00071
00072 const void *l;
00073
00074 const void *h;
00075 } tm_root;
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092 struct tm_data {
00093
00094 int inited, initing;
00095
00096
00097 enum tm_phase phase, next_phase;
00098
00099
00100 size_t n_phase_transitions[tm_phase_END + 1][tm_phase_END + 1];
00101
00102
00103 size_t n_color_transitions[tm_TOTAL + 1][tm_TOTAL + 1];
00104
00105
00106 int parceling;
00107 int allocating;
00108 int marking;
00109 int scanning;
00110 int sweeping;
00111 int unmarking;
00112
00113
00114 int trigger_full_gc;
00115
00116
00117 size_t n[tm__LAST3];
00118
00119
00120 size_t alloc_by_phase[tm_phase_END];
00121
00122
00123 size_t alloc_n[tm__LAST3];
00124
00125
00126
00127 tm_type types;
00128
00129 int type_id;
00130
00131
00132 tm_type type_reserve[50], *type_free;
00133 #ifndef tm_type_hash_LEN
00134 #define tm_type_hash_LEN 101
00135 #endif
00136
00137 tm_type *type_hash[tm_type_hash_LEN];
00138
00139
00140
00141
00142 int block_id;
00143
00144
00145 tm_block *block_first;
00146
00147 tm_block *block_last;
00148
00149
00150 tm_list free_blocks;
00151
00152 int free_blocks_n;
00153
00154
00155
00156
00157 tm_type *bt;
00158
00159 tm_block *bb;
00160
00161
00162
00163
00164 void * os_alloc_last;
00165
00166 size_t os_alloc_last_size;
00167
00168 void * os_alloc_expected;
00169
00170
00171 #define tm_BITMAP_SIZE (tm_address_range_k / (tm_page_SIZE / 1024) / bitset_ELEM_BSIZE)
00172
00173
00174 void *ptr_range[2];
00175
00176
00177 bitset_t page_in_use[tm_BITMAP_SIZE];
00178
00179
00180 bitset_t block_header[tm_BITMAP_SIZE];
00181
00182
00183 bitset_t block_large[tm_BITMAP_SIZE];
00184
00185
00186 tm_node_iterator node_color_iter[tm_TOTAL];
00187
00188
00189
00190
00191 tm_node *scan_node;
00192
00193 void *scan_ptr;
00194
00195 size_t *scan_size;
00196
00197
00198
00199
00200 tm_root roots[16];
00201
00202 short nroots;
00203
00204
00205 tm_root aroots[16];
00206
00207 short naroots;
00208
00209
00210 short root_datai, root_newi;
00211
00212
00213 short stack_grows;
00214
00215
00216 void **stack_ptrp;
00217
00218
00219 short rooti;
00220
00221 const char *rp;
00222
00223
00224 unsigned long data_mutations;
00225
00226 unsigned long stack_mutations;
00227
00228
00229
00230
00231 tm_time_stat ts_os_alloc;
00232
00233 tm_time_stat ts_os_free;
00234
00235 tm_time_stat ts_alloc;
00236
00237 tm_time_stat ts_free;
00238
00239 tm_time_stat ts_gc;
00240
00241 tm_time_stat ts_gc_inner;
00242
00243 tm_time_stat ts_barrier;
00244
00245 tm_time_stat ts_barrier_root;
00246
00247 tm_time_stat ts_barrier_pure;
00248
00249 tm_time_stat ts_barrier_black;
00250
00251 tm_time_stat ts_phase[tm_phase_END];
00252
00253
00254
00255
00256 size_t alloc_id;
00257
00258
00259 size_t alloc_pass;
00260
00261
00262 size_t alloc_since_sweep;
00263
00264
00265 size_t alloc_request_size;
00266
00267 tm_type *alloc_request_type;
00268
00269
00270 int msg_ignored;
00271
00272 char msg_enable_table[256];
00273
00274
00275
00276
00277 size_t blocks_allocated_since_gc;
00278
00279 size_t blocks_in_use_after_gc;
00280
00281 size_t nodes_allocated_since_gc;
00282
00283 size_t nodes_in_use_after_gc;
00284
00285 size_t bytes_allocated_since_gc;
00286
00287 size_t bytes_in_use_after_gc;
00288
00289
00290 int mmap_fd;
00291
00292
00293 jmp_buf jb;
00294 };
00295
00296
00297
00298 extern struct tm_data tm;
00299
00300
00301 #define tm_ptr_l tm.ptr_range[0]
00302
00303 #define tm_ptr_h tm.ptr_range[1]
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314 static __inline
00315 void tm_node_iterator_init(tm_node_iterator *ni)
00316 {
00317 ni->type = (void *) &tm.types;
00318 ni->node_next = (void *) &ni->type->color_list[ni->color];
00319 ni->node = 0;
00320 ni->scan_node = 0;
00321 ni->scan_ptr = 0;
00322 ni->scan_end = 0;
00323 ni->scan_size = 0;
00324 }
00325
00326
00327 static __inline
00328 tm_node * tm_node_iterator_next(tm_node_iterator *ni)
00329 {
00330 size_t i = 0;
00331
00332 while ( i ++ < tm.n[ni->color] ) {
00333
00334
00335
00336 if ( (void *) ni->type == (void *) &tm.types ) {
00337 ni->type = (void*) tm_list_next(ni->type);
00338
00339
00340
00341
00342
00343 if ( (void *) ni->type == (void *) &tm.types ) {
00344 tm_abort();
00345 return 0;
00346 }
00347
00348 next_type:
00349
00350 ni->node_next = (void *) &ni->type->color_list[ni->color];
00351
00352 tm_assert(tm_list_color(ni->node_next) == ni->color);
00353
00354
00355 ni->node_next = (void *) tm_list_next(ni->node_next);
00356 }
00357
00358
00359 if ( ! ni->node_next || (void *) ni->node_next == (void *) &ni->type->color_list[ni->color] ) {
00360 ni->type = (void*) tm_list_next(ni->type);
00361 goto next_type;
00362 }
00363
00364 if ( tm_node_color(ni->node_next) != ni->color ) {
00365 fprintf(stderr, " tm_node_iterator %p: node_color_iter[%s] derailed at node_next %p color %s, t#%d\n",
00366 ni,
00367 tm_color_name[ni->color],
00368 ni->node_next,
00369 tm_color_name[tm_node_color(ni->node_next)],
00370 ni->type->id
00371 );
00372
00373 ni->type = (void*) tm_list_next(ni->type);
00374 goto next_type;
00375 }
00376 else {
00377
00378 ni->node = ni->node_next;
00379
00380
00381 ni->node_next = (void*) tm_list_next(ni->node_next);
00382
00383 return ni->node;
00384 }
00385 }
00386
00387 return 0;
00388 }
00389
00390
00391 #define tm_node_LOOP_INIT(C) \
00392 tm_node_iterator_init(&tm.node_color_iter[C])
00393
00394
00395 #define tm_node_LOOP(C) { \
00396 tm_node *n; \
00397 tm_type *t = 0; \
00398 while ( (n = tm_node_iterator_next(&tm.node_color_iter[C])) ) { \
00399 t = tm.node_color_iter[C].type; \
00400 {
00401
00402
00403 #define tm_node_LOOP_BREAK(C) break
00404
00405
00406 #define tm_node_LOOP_END(C) \
00407 } \
00408 } \
00409 }
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420 void _tm_phase_init(int p);
00421
00422
00423 void tm_node_set_color(tm_node *n, tm_block *b, tm_color c);
00424
00425 void _tm_set_stack_ptr(void* ptr);
00426
00427
00428 void __tm_clear_some_stack_words();
00429 #define _tm_clear_some_stack_words() \
00430 setjmp(tm.jb); \
00431 __tm_clear_some_stack_words()
00432
00433
00434 void *_tm_alloc_inner(size_t size);
00435 void *_tm_alloc_desc_inner(tm_adesc *desc);
00436 void *_tm_realloc_inner(void *ptr, size_t size);
00437 void _tm_free_inner(void *ptr);
00438 void _tm_gc_full_inner();
00439
00440
00441
00442
00443
00444
00445 #include "tredmill/os.h"
00446 #include "tredmill/root.h"
00447 #include "tredmill/page.h"
00448 #include "tredmill/ptr.h"
00449 #include "tredmill/mark.h"
00450
00451
00452
00453
00454 #include <stdio.h>
00455 #include <assert.h>
00456 #include <stdlib.h>
00457 #include <stdarg.h>
00458 #include <unistd.h>
00459 #include <string.h>
00460
00461 #endif