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]);