Mercurial > hg > truffle
comparison src/os/posix/vm/os_posix.cpp @ 7433:730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
Summary: Mapping of aligned memory needs to be MT safe. Also reviewed by: vitalyd@gmail.com
Reviewed-by: dholmes, coleenp, zgu
author | brutisso |
---|---|
date | Mon, 17 Dec 2012 08:49:20 +0100 |
parents | b9a9ed0f8eeb |
children | 754c24457b20 |
comparison
equal
deleted
inserted
replaced
7432:0b3d19153cc6 | 7433:730cc4ddd550 |
---|---|
91 void os::wait_for_keypress_at_exit(void) { | 91 void os::wait_for_keypress_at_exit(void) { |
92 // don't do anything on posix platforms | 92 // don't do anything on posix platforms |
93 return; | 93 return; |
94 } | 94 } |
95 | 95 |
96 // Multiple threads can race in this code, and can remap over each other with MAP_FIXED, | |
97 // so on posix, unmap the section at the start and at the end of the chunk that we mapped | |
98 // rather than unmapping and remapping the whole chunk to get requested alignment. | |
99 char* os::reserve_memory_aligned(size_t size, size_t alignment) { | |
100 assert((alignment & (os::vm_allocation_granularity() - 1)) == 0, | |
101 "Alignment must be a multiple of allocation granularity (page size)"); | |
102 assert((size & (alignment -1)) == 0, "size must be 'alignment' aligned"); | |
103 | |
104 size_t extra_size = size + alignment; | |
105 assert(extra_size >= size, "overflow, size is too large to allow alignment"); | |
106 | |
107 char* extra_base = os::reserve_memory(extra_size, NULL, alignment); | |
108 | |
109 if (extra_base == NULL) { | |
110 return NULL; | |
111 } | |
112 | |
113 // Do manual alignment | |
114 char* aligned_base = (char*) align_size_up((uintptr_t) extra_base, alignment); | |
115 | |
116 // [ | | ] | |
117 // ^ extra_base | |
118 // ^ extra_base + begin_offset == aligned_base | |
119 // extra_base + begin_offset + size ^ | |
120 // extra_base + extra_size ^ | |
121 // |<>| == begin_offset | |
122 // end_offset == |<>| | |
123 size_t begin_offset = aligned_base - extra_base; | |
124 size_t end_offset = (extra_base + extra_size) - (aligned_base + size); | |
125 | |
126 if (begin_offset > 0) { | |
127 os::release_memory(extra_base, begin_offset); | |
128 } | |
129 | |
130 if (end_offset > 0) { | |
131 os::release_memory(extra_base + begin_offset + size, end_offset); | |
132 } | |
133 | |
134 return aligned_base; | |
135 } | |
136 | |
96 void os::Posix::print_load_average(outputStream* st) { | 137 void os::Posix::print_load_average(outputStream* st) { |
97 st->print("load average:"); | 138 st->print("load average:"); |
98 double loadavg[3]; | 139 double loadavg[3]; |
99 os::loadavg(loadavg, 3); | 140 os::loadavg(loadavg, 3); |
100 st->print("%0.02f %0.02f %0.02f", loadavg[0], loadavg[1], loadavg[2]); | 141 st->print("%0.02f %0.02f %0.02f", loadavg[0], loadavg[1], loadavg[2]); |