src/hotspot/os/windows/os_windows.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File open Sdiff src/hotspot/os/windows

src/hotspot/os/windows/os_windows.cpp

Print this page




4044 }
4045 
4046 // Mark the polling page as unreadable
4047 void os::make_polling_page_unreadable(void) {
4048   DWORD old_status;
4049   if (!VirtualProtect((char *)_polling_page, os::vm_page_size(),
4050                       PAGE_NOACCESS, &old_status)) {
4051     fatal("Could not disable polling page");
4052   }
4053 }
4054 
4055 // Mark the polling page as readable
4056 void os::make_polling_page_readable(void) {
4057   DWORD old_status;
4058   if (!VirtualProtect((char *)_polling_page, os::vm_page_size(),
4059                       PAGE_READONLY, &old_status)) {
4060     fatal("Could not enable polling page");
4061   }
4062 }
4063 



































































4064 
4065 int os::stat(const char *path, struct stat *sbuf) {
4066   char pathbuf[MAX_PATH];
4067   if (strlen(path) > MAX_PATH - 1) {
4068     errno = ENAMETOOLONG;
4069     return -1;
4070   }
4071   os::native_path(strcpy(pathbuf, path));
4072   int ret = ::stat(pathbuf, sbuf);
4073   if (sbuf != NULL && UseUTCFileTimestamp) {
4074     // Fix for 6539723.  st_mtime returned from stat() is dependent on
4075     // the system timezone and so can return different values for the
4076     // same file if/when daylight savings time changes.  This adjustment
4077     // makes sure the same timestamp is returned regardless of the TZ.
4078     //
4079     // See:
4080     // http://msdn.microsoft.com/library/
4081     //   default.asp?url=/library/en-us/sysinfo/base/
4082     //   time_zone_information_str.asp
4083     // and
4084     // http://msdn.microsoft.com/library/default.asp?url=
4085     //   /library/en-us/sysinfo/base/settimezoneinformation.asp
4086     //
4087     // NOTE: there is a insidious bug here:  If the timezone is changed
4088     // after the call to stat() but before 'GetTimeZoneInformation()', then
4089     // the adjustment we do here will be wrong and we'll return the wrong
4090     // value (which will likely end up creating an invalid class data
4091     // archive).  Absent a better API for this, or some time zone locking
4092     // mechanism, we'll have to live with this risk.
4093     TIME_ZONE_INFORMATION tz;
4094     DWORD tzid = GetTimeZoneInformation(&tz);
4095     int daylightBias =
4096       (tzid == TIME_ZONE_ID_DAYLIGHT) ?  tz.DaylightBias : tz.StandardBias;
4097     sbuf->st_mtime += (tz.Bias + daylightBias) * 60;
4098   }




































4099   return ret;
4100 }
4101 
4102 
4103 #define FT2INT64(ft) \
4104   ((jlong)((jlong)(ft).dwHighDateTime << 32 | (julong)(ft).dwLowDateTime))
4105 
4106 
4107 // current_thread_cpu_time(bool) and thread_cpu_time(Thread*, bool)
4108 // are used by JVM M&M and JVMTI to get user+sys or user CPU time
4109 // of a thread.
4110 //
4111 // current_thread_cpu_time() and thread_cpu_time(Thread*) returns
4112 // the fast estimate available on the platform.
4113 
4114 // current_thread_cpu_time() is not optimized for Windows yet
4115 jlong os::current_thread_cpu_time() {
4116   // return user + sys since the cost is the same
4117   return os::thread_cpu_time(Thread::current(), true /* user+sys */);
4118 }


4191 //    just return the value of the global, avoiding the slow query.
4192 //
4193 // c) Sample a better answer using exponential decay to smooth the
4194 //    value.  This is basically the algorithm used by UNIX kernels.
4195 //
4196 // Note that sampling thread starvation could affect both (b) and (c).
4197 int os::loadavg(double loadavg[], int nelem) {
4198   return -1;
4199 }
4200 
4201 
4202 // DontYieldALot=false by default: dutifully perform all yields as requested by JVM_Yield()
4203 bool os::dont_yield() {
4204   return DontYieldALot;
4205 }
4206 
4207 // This method is a slightly reworked copy of JDK's sysOpen
4208 // from src/windows/hpi/src/sys_api_md.c
4209 
4210 int os::open(const char *path, int oflag, int mode) {
4211   char pathbuf[MAX_PATH];
4212 
4213   if (strlen(path) > MAX_PATH - 1) {
4214     errno = ENAMETOOLONG;














4215     return -1;
4216   }
4217   os::native_path(strcpy(pathbuf, path));
4218   return ::open(pathbuf, oflag | O_BINARY | O_NOINHERIT, mode);






4219 }
4220 
4221 FILE* os::open(int fd, const char* mode) {
4222   return ::_fdopen(fd, mode);
4223 }
4224 
4225 // Is a (classpath) directory empty?
4226 bool os::dir_is_empty(const char* path) {
4227   WIN32_FIND_DATA fd;
4228   HANDLE f = FindFirstFile(path, &fd);
4229   if (f == INVALID_HANDLE_VALUE) {
4230     return true;
4231   }
4232   FindClose(f);
4233   return false;
4234 }
4235 
4236 // create binary file, rewriting existing file if required
4237 int os::create_binary_file(const char* path, bool rewrite_existing) {
4238   int oflags = _O_CREAT | _O_WRONLY | _O_BINARY;




4044 }
4045 
4046 // Mark the polling page as unreadable
4047 void os::make_polling_page_unreadable(void) {
4048   DWORD old_status;
4049   if (!VirtualProtect((char *)_polling_page, os::vm_page_size(),
4050                       PAGE_NOACCESS, &old_status)) {
4051     fatal("Could not disable polling page");
4052   }
4053 }
4054 
4055 // Mark the polling page as readable
4056 void os::make_polling_page_readable(void) {
4057   DWORD old_status;
4058   if (!VirtualProtect((char *)_polling_page, os::vm_page_size(),
4059                       PAGE_READONLY, &old_status)) {
4060     fatal("Could not enable polling page");
4061   }
4062 }
4063 
4064 // combine the high and low DWORD into a ULONGLONG
4065 static ULONGLONG make_double_word(DWORD high_word, DWORD low_word) {
4066   ULONGLONG value = high_word;
4067   value <<= sizeof(high_word) * 8;
4068   value |= low_word;
4069   return value;
4070 }
4071 
4072 // Transfers data from WIN32_FILE_ATTRIBUTE_DATA structure to struct stat
4073 static void file_attribute_data_to_stat(struct stat* sbuf, WIN32_FILE_ATTRIBUTE_DATA file_data) {
4074   ::memset((void*)sbuf, 0, sizeof(struct stat));
4075   sbuf->st_size = (_off_t)make_double_word(file_data.nFileSizeHigh, file_data.nFileSizeLow);
4076   sbuf->st_mtime = make_double_word(file_data.ftLastWriteTime.dwHighDateTime,
4077                                   file_data.ftLastWriteTime.dwLowDateTime);
4078   sbuf->st_ctime = make_double_word(file_data.ftCreationTime.dwHighDateTime,
4079                                   file_data.ftCreationTime.dwLowDateTime);
4080   sbuf->st_atime = make_double_word(file_data.ftLastAccessTime.dwHighDateTime,
4081                                   file_data.ftLastAccessTime.dwLowDateTime);
4082   if ((file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {
4083     sbuf->st_mode |= S_IFDIR;
4084   } else {
4085     sbuf->st_mode |= S_IFREG;
4086   }
4087 }
4088 
4089 // The following function is adapted from java.base/windows/native/libjava/canonicalize_md.c
4090 // Creates an UNC path from a single byte path. Return buffer is
4091 // allocated in C heap and needs to be freed by the caller.
4092 // Returns NULL on error.
4093 static wchar_t* create_unc_path(const char* path, errno_t &err) {
4094   wchar_t* wpath = NULL;
4095   size_t converted_chars = 0;
4096   size_t path_len = strlen(path) + 1; // includes the terminating NULL
4097   if (path[0] == '\\' && path[1] == '\\') {
4098     if (path[2] == '?' && path[3] == '\\'){
4099       // if it already has a \\?\ don't do the prefix
4100       wpath = (wchar_t*)os::malloc(path_len * sizeof(wchar_t), mtInternal);
4101       if (wpath != NULL) {
4102         err = ::mbstowcs_s(&converted_chars, wpath, path_len, path, path_len);
4103       } else {
4104         err = ENOMEM;
4105       }
4106     } else {
4107       // only UNC pathname includes double slashes here
4108       wpath = (wchar_t*)os::malloc((path_len + 7) * sizeof(wchar_t), mtInternal);
4109       if (wpath != NULL) {
4110         ::wcscpy(wpath, L"\\\\?\\UNC\0");
4111         err = ::mbstowcs_s(&converted_chars, &wpath[7], path_len, path, path_len);
4112       } else {
4113         err = ENOMEM;
4114       }
4115     }
4116   } else {
4117     wpath = (wchar_t*)os::malloc((path_len + 4) * sizeof(wchar_t), mtInternal);
4118     if (wpath != NULL) {
4119       ::wcscpy(wpath, L"\\\\?\\\0");
4120       err = ::mbstowcs_s(&converted_chars, &wpath[4], path_len, path, path_len);
4121     } else {
4122       err = ENOMEM;
4123     }
4124   }
4125   return wpath;
4126 }
4127 
4128 static void destroy_unc_path(wchar_t* wpath) {
4129   os::free(wpath);
4130 }
4131 
4132 int os::stat(const char *path, struct stat *sbuf) {
4133   char* pathbuf = (char*)os::strdup(path, mtInternal);
4134   if (pathbuf == NULL) {
4135     errno = ENOMEM;
4136     return -1;




























4137   }
4138   os::native_path(pathbuf);
4139   int ret;
4140   WIN32_FILE_ATTRIBUTE_DATA file_data;
4141   // Not using stat() to avoid the problem described in JDK-6539723
4142   if (strlen(path) < MAX_PATH) {
4143     BOOL bret = ::GetFileAttributesExA(pathbuf, GetFileExInfoStandard, &file_data);
4144     if (!bret) {
4145       errno = ::GetLastError();
4146       ret = -1;
4147     }
4148     else {
4149       file_attribute_data_to_stat(sbuf, file_data);
4150       ret = 0;
4151     }
4152   } else {
4153     errno_t err = ERROR_SUCCESS;
4154     wchar_t* wpath = create_unc_path(pathbuf, err);
4155     if (err != ERROR_SUCCESS) {
4156       if (wpath != NULL) {
4157         destroy_unc_path(wpath);
4158       }
4159       os::free(pathbuf);
4160       errno = err;
4161       return -1;
4162     }
4163     BOOL bret = ::GetFileAttributesExW(wpath, GetFileExInfoStandard, &file_data);
4164     if (!bret) {
4165       errno = ::GetLastError();
4166       ret = -1;
4167     } else {
4168       file_attribute_data_to_stat(sbuf, file_data);
4169       ret = 0;
4170     }
4171     destroy_unc_path(wpath);
4172   }
4173   os::free(pathbuf);
4174   return ret;
4175 }
4176 
4177 
4178 #define FT2INT64(ft) \
4179   ((jlong)((jlong)(ft).dwHighDateTime << 32 | (julong)(ft).dwLowDateTime))
4180 
4181 
4182 // current_thread_cpu_time(bool) and thread_cpu_time(Thread*, bool)
4183 // are used by JVM M&M and JVMTI to get user+sys or user CPU time
4184 // of a thread.
4185 //
4186 // current_thread_cpu_time() and thread_cpu_time(Thread*) returns
4187 // the fast estimate available on the platform.
4188 
4189 // current_thread_cpu_time() is not optimized for Windows yet
4190 jlong os::current_thread_cpu_time() {
4191   // return user + sys since the cost is the same
4192   return os::thread_cpu_time(Thread::current(), true /* user+sys */);
4193 }


4266 //    just return the value of the global, avoiding the slow query.
4267 //
4268 // c) Sample a better answer using exponential decay to smooth the
4269 //    value.  This is basically the algorithm used by UNIX kernels.
4270 //
4271 // Note that sampling thread starvation could affect both (b) and (c).
4272 int os::loadavg(double loadavg[], int nelem) {
4273   return -1;
4274 }
4275 
4276 
4277 // DontYieldALot=false by default: dutifully perform all yields as requested by JVM_Yield()
4278 bool os::dont_yield() {
4279   return DontYieldALot;
4280 }
4281 
4282 // This method is a slightly reworked copy of JDK's sysOpen
4283 // from src/windows/hpi/src/sys_api_md.c
4284 
4285 int os::open(const char *path, int oflag, int mode) {
4286   char* pathbuf = (char*)os::strdup(path, mtInternal);
4287   if (pathbuf == NULL) {
4288     errno = ENOMEM;
4289     return -1;
4290   }
4291   os::native_path(pathbuf);
4292   int ret;
4293   if (strlen(path) < MAX_PATH) {
4294     ret = ::open(pathbuf, oflag | O_BINARY | O_NOINHERIT, mode);
4295   } else {
4296     errno_t err = ERROR_SUCCESS;
4297     wchar_t* wpath = create_unc_path(pathbuf, err);
4298     if (err != ERROR_SUCCESS) {
4299       if (wpath != NULL) {
4300         destroy_unc_path(wpath);
4301       }
4302       os::free(pathbuf);
4303       errno = err;
4304       return -1;
4305     }
4306     ret = ::_wopen(wpath, oflag | O_BINARY | O_NOINHERIT, mode);
4307     if (ret == -1) {
4308       errno = ::GetLastError();
4309     }
4310     destroy_unc_path(wpath);
4311   }
4312   os::free(pathbuf);
4313   return ret;
4314 }
4315 
4316 FILE* os::open(int fd, const char* mode) {
4317   return ::_fdopen(fd, mode);
4318 }
4319 
4320 // Is a (classpath) directory empty?
4321 bool os::dir_is_empty(const char* path) {
4322   WIN32_FIND_DATA fd;
4323   HANDLE f = FindFirstFile(path, &fd);
4324   if (f == INVALID_HANDLE_VALUE) {
4325     return true;
4326   }
4327   FindClose(f);
4328   return false;
4329 }
4330 
4331 // create binary file, rewriting existing file if required
4332 int os::create_binary_file(const char* path, bool rewrite_existing) {
4333   int oflags = _O_CREAT | _O_WRONLY | _O_BINARY;


src/hotspot/os/windows/os_windows.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File