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




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











































4063 
4064 int os::stat(const char *path, struct stat *sbuf) {
4065   char pathbuf[MAX_PATH];
4066   if (strlen(path) > MAX_PATH - 1) {
4067     errno = ENAMETOOLONG;

4068     return -1;
4069   }
4070   os::native_path(strcpy(pathbuf, path));
4071   int ret = ::stat(pathbuf, sbuf);


























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

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


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




















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




4043 }
4044 
4045 // Mark the polling page as unreadable
4046 void os::make_polling_page_unreadable(void) {
4047   DWORD old_status;
4048   if (!VirtualProtect((char *)_polling_page, os::vm_page_size(),
4049                       PAGE_NOACCESS, &old_status)) {
4050     fatal("Could not disable polling page");
4051   }
4052 }
4053 
4054 // Mark the polling page as readable
4055 void os::make_polling_page_readable(void) {
4056   DWORD old_status;
4057   if (!VirtualProtect((char *)_polling_page, os::vm_page_size(),
4058                       PAGE_READONLY, &old_status)) {
4059     fatal("Could not enable polling page");
4060   }
4061 }
4062 
4063 // combine the high and low DWORD into a ULONGLONG
4064 static ULONGLONG eval_find_data(DWORD high_word, DWORD low_word) {
4065   ULONGLONG value = high_word;
4066   value <<= sizeof(high_word) * 8;
4067   value |= low_word;
4068   return value;
4069 }
4070 
4071 // setup the struct stat using the data from WIN32_FIND_DATAW structure
4072 static void setup_stat(struct stat* sbuf, WIN32_FIND_DATAW find_data) {
4073   sbuf->st_size = (_off_t)eval_find_data(find_data.nFileSizeHigh, find_data.nFileSizeLow);
4074   sbuf->st_mtime = eval_find_data(find_data.ftLastWriteTime.dwHighDateTime,
4075                                   find_data.ftLastWriteTime.dwLowDateTime);
4076   sbuf->st_ctime = eval_find_data(find_data.ftCreationTime.dwHighDateTime,
4077                                   find_data.ftCreationTime.dwLowDateTime);
4078   sbuf->st_atime = eval_find_data(find_data.ftLastAccessTime.dwHighDateTime,
4079                                   find_data.ftLastAccessTime.dwLowDateTime);
4080   if (find_data.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY) {
4081     sbuf->st_mode |= S_IFDIR;
4082   }
4083   if (find_data.dwFileAttributes == FILE_ATTRIBUTE_NORMAL) {
4084     sbuf->st_mode |= S_IFREG;
4085   }
4086 }
4087 
4088 // The following function is adapted from java.base/windows/native/libjava/canonicalize_md.c
4089 // copy \\?\ or \\?\UNC\ to the front of path
4090 static void prefixed_path(WCHAR* wpath, size_t pathlen) {
4091   if (wpath[0] == L'\\' && wpath[1] == L'\\') {
4092     /* if it already has a \\?\ don't do the prefix */
4093     if (!(wpath[2] == L'?' && wpath[3] == L'\\')) {
4094       /* only UNC pathname includes double slashes here */
4095       ::wmemmove(wpath + 7, wpath + 1, pathlen - 1);
4096       ::wmemcpy_s(wpath, pathlen, L"\\\\?\\UNC", 7);
4097       wpath[pathlen + 6] = L'\0';
4098     }
4099   }
4100   else {
4101     ::wmemmove(wpath + 4, wpath, pathlen);
4102     ::wmemcpy_s(wpath, pathlen, L"\\\\?\\", 4);
4103     wpath[pathlen + 4] = L'\0';
4104   }
4105 }
4106 
4107 int os::stat(const char *path, struct stat *sbuf) {
4108   size_t path_len = strlen(path) + 1;
4109   char* pathbuf = (char*)os::malloc(path_len * sizeof(char), mtInternal);
4110   if (pathbuf == NULL) {
4111     errno = ENOMEM;
4112     return -1;
4113   }
4114   os::native_path(strcpy(pathbuf, path));
4115   int ret;
4116   if (strlen(path) < MAX_PATH) {
4117     ret = ::stat(pathbuf, sbuf);
4118   } else {
4119     WCHAR* wpathbuf = (WCHAR*)os::malloc((path_len + 10) * sizeof (WCHAR), mtInternal);
4120     if (wpathbuf == NULL) {
4121       os::free(pathbuf);
4122       errno = ENOMEM;
4123       return -1;
4124     }
4125     size_t converted_chars = 0;
4126     ::mbstowcs_s(&converted_chars, wpathbuf, path_len + 10, pathbuf, strlen(path));
4127     prefixed_path(wpathbuf, strlen(path));
4128     WIN32_FIND_DATAW find_data;
4129     HANDLE h_find;
4130     h_find = ::FindFirstFileW(wpathbuf, &find_data);
4131     if (h_find == INVALID_HANDLE_VALUE) {
4132       errno = ::GetLastError();
4133       os::free(wpathbuf);
4134       ret = -1;
4135     } else {
4136       setup_stat(sbuf, find_data);
4137       ret = 0;
4138       ::FindClose(h_find);
4139     }
4140     os::free(wpathbuf);
4141   }
4142   if (sbuf != NULL && UseUTCFileTimestamp) {
4143     // Fix for 6539723.  st_mtime returned from stat() is dependent on
4144     // the system timezone and so can return different values for the
4145     // same file if/when daylight savings time changes.  This adjustment
4146     // makes sure the same timestamp is returned regardless of the TZ.
4147     //
4148     // See:
4149     // http://msdn.microsoft.com/library/
4150     //   default.asp?url=/library/en-us/sysinfo/base/
4151     //   time_zone_information_str.asp
4152     // and
4153     // http://msdn.microsoft.com/library/default.asp?url=
4154     //   /library/en-us/sysinfo/base/settimezoneinformation.asp
4155     //
4156     // NOTE: there is a insidious bug here:  If the timezone is changed
4157     // after the call to stat() but before 'GetTimeZoneInformation()', then
4158     // the adjustment we do here will be wrong and we'll return the wrong
4159     // value (which will likely end up creating an invalid class data
4160     // archive).  Absent a better API for this, or some time zone locking
4161     // mechanism, we'll have to live with this risk.
4162     TIME_ZONE_INFORMATION tz;
4163     DWORD tzid = GetTimeZoneInformation(&tz);
4164     int daylightBias =
4165       (tzid == TIME_ZONE_ID_DAYLIGHT) ? tz.DaylightBias : tz.StandardBias;
4166     sbuf->st_mtime += (tz.Bias + daylightBias) * 60;
4167   }
4168   os::free(pathbuf);
4169   return ret;
4170 }
4171 
4172 
4173 #define FT2INT64(ft) \
4174   ((jlong)((jlong)(ft).dwHighDateTime << 32 | (julong)(ft).dwLowDateTime))
4175 
4176 
4177 // current_thread_cpu_time(bool) and thread_cpu_time(Thread*, bool)
4178 // are used by JVM M&M and JVMTI to get user+sys or user CPU time
4179 // of a thread.
4180 //
4181 // current_thread_cpu_time() and thread_cpu_time(Thread*) returns
4182 // the fast estimate available on the platform.
4183 
4184 // current_thread_cpu_time() is not optimized for Windows yet
4185 jlong os::current_thread_cpu_time() {
4186   // return user + sys since the cost is the same
4187   return os::thread_cpu_time(Thread::current(), true /* user+sys */);
4188 }


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