|
28 | 28 | #include "runtime/globals.hpp"
|
29 | 29 | #include "runtime/os.hpp"
|
30 | 30 |
|
31 |
| -PretouchTask::PretouchTask(const char* task_name, char* start_address, char* end_address, size_t page_size) : |
| 31 | +PretouchTask::PretouchTask(const char* task_name, |
| 32 | + char* start_address, |
| 33 | + char* end_address, |
| 34 | + size_t page_size, |
| 35 | + size_t chunk_size) : |
32 | 36 | AbstractGangTask(task_name),
|
33 | 37 | _cur_addr(start_address),
|
34 | 38 | _start_addr(start_address),
|
35 | 39 | _end_addr(end_address),
|
36 |
| - _page_size(0) { |
37 |
| -#ifdef LINUX |
38 |
| - _page_size = UseTransparentHugePages ? (size_t)os::vm_page_size(): page_size; |
39 |
| -#else |
40 |
| - _page_size = page_size; |
41 |
| -#endif |
| 40 | + _page_size(page_size), |
| 41 | + _chunk_size(chunk_size) { |
| 42 | + |
| 43 | + assert(chunk_size >= page_size, |
| 44 | + "Chunk size " SIZE_FORMAT " is smaller than page size " SIZE_FORMAT, |
| 45 | + chunk_size, page_size); |
42 | 46 | }
|
43 | 47 |
|
44 | 48 | size_t PretouchTask::chunk_size() {
|
45 | 49 | return PreTouchParallelChunkSize;
|
46 | 50 | }
|
47 | 51 |
|
48 | 52 | void PretouchTask::work(uint worker_id) {
|
49 |
| - size_t const actual_chunk_size = MAX2(chunk_size(), _page_size); |
50 |
| - |
51 | 53 | while (true) {
|
52 |
| - char* touch_addr = Atomic::fetch_and_add(&_cur_addr, actual_chunk_size); |
| 54 | + char* touch_addr = Atomic::fetch_and_add(&_cur_addr, _chunk_size); |
53 | 55 | if (touch_addr < _start_addr || touch_addr >= _end_addr) {
|
54 | 56 | break;
|
55 | 57 | }
|
56 | 58 |
|
57 |
| - char* end_addr = touch_addr + MIN2(actual_chunk_size, pointer_delta(_end_addr, touch_addr, sizeof(char))); |
| 59 | + char* end_addr = touch_addr + MIN2(_chunk_size, pointer_delta(_end_addr, touch_addr, sizeof(char))); |
58 | 60 |
|
59 | 61 | os::pretouch_memory(touch_addr, end_addr, _page_size);
|
60 | 62 | }
|
61 | 63 | }
|
62 | 64 |
|
63 | 65 | void PretouchTask::pretouch(const char* task_name, char* start_address, char* end_address,
|
64 | 66 | size_t page_size, WorkGang* pretouch_gang) {
|
65 |
| - PretouchTask task(task_name, start_address, end_address, page_size); |
| 67 | + |
| 68 | +#ifdef LINUX |
| 69 | + // When using THP we need to always pre-touch using small pages as the OS will |
| 70 | + // initially always use small pages. |
| 71 | + page_size = UseTransparentHugePages ? (size_t)os::vm_page_size() : page_size; |
| 72 | +#endif |
| 73 | + size_t chunk_size = MAX2(PretouchTask::chunk_size(), page_size); |
| 74 | + |
| 75 | + PretouchTask task(task_name, start_address, end_address, page_size, chunk_size); |
66 | 76 | size_t total_bytes = pointer_delta(end_address, start_address, sizeof(char));
|
67 | 77 |
|
| 78 | + if (total_bytes == 0) { |
| 79 | + return; |
| 80 | + } |
| 81 | + |
68 | 82 | if (pretouch_gang != NULL) {
|
69 |
| - size_t num_chunks = MAX2((size_t)1, total_bytes / MAX2(PretouchTask::chunk_size(), page_size)); |
| 83 | + size_t num_chunks = (total_bytes + chunk_size - 1) / chunk_size; |
70 | 84 |
|
71 |
| - uint num_workers = MIN2((uint)num_chunks, pretouch_gang->total_workers()); |
| 85 | + uint num_workers = (uint)MIN2(num_chunks, (size_t)pretouch_gang->total_workers()); |
72 | 86 | log_debug(gc, heap)("Running %s with %u workers for " SIZE_FORMAT " work units pre-touching " SIZE_FORMAT "B.",
|
73 | 87 | task.name(), num_workers, num_chunks, total_bytes);
|
74 | 88 |
|
|
0 commit comments