ntdll: Move Nt system time functions to the Unix library.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
613446d018
commit
a4ce2f652d
|
@ -38,9 +38,6 @@
|
|||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
# include <mach/mach_time.h>
|
||||
#endif
|
||||
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
|
@ -103,33 +100,6 @@ static inline BOOL IsLeapYear(int Year)
|
|||
return Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0);
|
||||
}
|
||||
|
||||
/* return a monotonic time counter, in Win32 ticks */
|
||||
static inline ULONGLONG monotonic_counter(void)
|
||||
{
|
||||
struct timeval now;
|
||||
|
||||
#ifdef __APPLE__
|
||||
static mach_timebase_info_data_t timebase;
|
||||
|
||||
if (!timebase.denom) mach_timebase_info( &timebase );
|
||||
#ifdef HAVE_MACH_CONTINUOUS_TIME
|
||||
if (&mach_continuous_time != NULL)
|
||||
return mach_continuous_time() * timebase.numer / timebase.denom / 100;
|
||||
#endif
|
||||
return mach_absolute_time() * timebase.numer / timebase.denom / 100;
|
||||
#elif defined(HAVE_CLOCK_GETTIME)
|
||||
struct timespec ts;
|
||||
#ifdef CLOCK_MONOTONIC_RAW
|
||||
if (!clock_gettime( CLOCK_MONOTONIC_RAW, &ts ))
|
||||
return ts.tv_sec * (ULONGLONG)TICKSPERSEC + ts.tv_nsec / 100;
|
||||
#endif
|
||||
if (!clock_gettime( CLOCK_MONOTONIC, &ts ))
|
||||
return ts.tv_sec * (ULONGLONG)TICKSPERSEC + ts.tv_nsec / 100;
|
||||
#endif
|
||||
|
||||
gettimeofday( &now, 0 );
|
||||
return now.tv_sec * (ULONGLONG)TICKSPERSEC + now.tv_usec * 10 + TICKS_1601_TO_1970 - server_start_time;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* RtlTimeToTimeFields [NTDLL.@]
|
||||
|
@ -471,38 +441,7 @@ void WINAPI RtlTimeToElapsedTimeFields( const LARGE_INTEGER *Time, PTIME_FIELDS
|
|||
*/
|
||||
NTSTATUS WINAPI NtQuerySystemTime( LARGE_INTEGER *time )
|
||||
{
|
||||
#ifdef HAVE_CLOCK_GETTIME
|
||||
struct timespec ts;
|
||||
static clockid_t clock_id = CLOCK_MONOTONIC; /* placeholder */
|
||||
|
||||
if (clock_id == CLOCK_MONOTONIC)
|
||||
{
|
||||
#ifdef CLOCK_REALTIME_COARSE
|
||||
struct timespec res;
|
||||
|
||||
/* Use CLOCK_REALTIME_COARSE if it has 1 ms or better resolution */
|
||||
if (!clock_getres( CLOCK_REALTIME_COARSE, &res ) && res.tv_sec == 0 && res.tv_nsec <= 1000000)
|
||||
clock_id = CLOCK_REALTIME_COARSE;
|
||||
else
|
||||
#endif /* CLOCK_REALTIME_COARSE */
|
||||
clock_id = CLOCK_REALTIME;
|
||||
}
|
||||
|
||||
if (!clock_gettime( clock_id, &ts ))
|
||||
{
|
||||
time->QuadPart = ts.tv_sec * (ULONGLONG)TICKSPERSEC + TICKS_1601_TO_1970;
|
||||
time->QuadPart += (ts.tv_nsec + 50) / 100;
|
||||
}
|
||||
else
|
||||
#endif /* HAVE_CLOCK_GETTIME */
|
||||
{
|
||||
struct timeval now;
|
||||
|
||||
gettimeofday( &now, 0 );
|
||||
time->QuadPart = now.tv_sec * (ULONGLONG)TICKSPERSEC + TICKS_1601_TO_1970;
|
||||
time->QuadPart += now.tv_usec * 10;
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
return unix_funcs->NtQuerySystemTime( time );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -543,18 +482,18 @@ LONGLONG WINAPI RtlGetSystemTimePrecise( void )
|
|||
*/
|
||||
NTSTATUS WINAPI NtQueryPerformanceCounter( LARGE_INTEGER *counter, LARGE_INTEGER *frequency )
|
||||
{
|
||||
NTSTATUS status;
|
||||
|
||||
__TRY
|
||||
{
|
||||
counter->QuadPart = monotonic_counter();
|
||||
if (frequency) frequency->QuadPart = TICKSPERSEC;
|
||||
status = unix_funcs->NtQueryPerformanceCounter( counter, frequency );
|
||||
}
|
||||
__EXCEPT_PAGE_FAULT
|
||||
{
|
||||
return STATUS_ACCESS_VIOLATION;
|
||||
}
|
||||
__ENDTRY
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
return status;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -562,7 +501,7 @@ NTSTATUS WINAPI NtQueryPerformanceCounter( LARGE_INTEGER *counter, LARGE_INTEGER
|
|||
*/
|
||||
BOOL WINAPI DECLSPEC_HOTPATCH RtlQueryPerformanceCounter( LARGE_INTEGER *counter )
|
||||
{
|
||||
counter->QuadPart = monotonic_counter();
|
||||
unix_funcs->NtQueryPerformanceCounter( counter, NULL );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -1070,58 +1009,10 @@ NTSTATUS WINAPI RtlSetTimeZoneInformation( const RTL_TIME_ZONE_INFORMATION *tzin
|
|||
/***********************************************************************
|
||||
* NtSetSystemTime [NTDLL.@]
|
||||
* ZwSetSystemTime [NTDLL.@]
|
||||
*
|
||||
* Set the system time.
|
||||
*
|
||||
* PARAMS
|
||||
* NewTime [I] The time to set.
|
||||
* OldTime [O] Optional destination for the previous system time.
|
||||
*
|
||||
* RETURNS
|
||||
* Success: STATUS_SUCCESS.
|
||||
* Failure: An NTSTATUS error code indicating the problem.
|
||||
*/
|
||||
NTSTATUS WINAPI NtSetSystemTime(const LARGE_INTEGER *NewTime, LARGE_INTEGER *OldTime)
|
||||
NTSTATUS WINAPI NtSetSystemTime(const LARGE_INTEGER *new, LARGE_INTEGER *old )
|
||||
{
|
||||
struct timeval tv;
|
||||
time_t tm_t;
|
||||
DWORD sec, oldsec;
|
||||
LARGE_INTEGER tm;
|
||||
|
||||
/* Return the old time if necessary */
|
||||
if (!OldTime) OldTime = &tm;
|
||||
|
||||
NtQuerySystemTime( OldTime );
|
||||
if (!RtlTimeToSecondsSince1970( OldTime, &oldsec )) return STATUS_INVALID_PARAMETER;
|
||||
if (!RtlTimeToSecondsSince1970( NewTime, &sec )) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
/* fake success if time didn't change */
|
||||
if (oldsec == sec)
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
/* set the new time */
|
||||
tv.tv_sec = sec;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
#ifdef HAVE_SETTIMEOFDAY
|
||||
tm_t = sec;
|
||||
if (!settimeofday(&tv, NULL)) /* 0 is OK, -1 is error */
|
||||
{
|
||||
TRACE("OS time changed to %s\n", ctime(&tm_t));
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
ERR("Cannot set time to %s, time adjustment %ld: %s\n",
|
||||
ctime(&tm_t), (long)(sec-oldsec), strerror(errno));
|
||||
if (errno == EPERM)
|
||||
return STATUS_PRIVILEGE_NOT_HELD;
|
||||
else
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
#else
|
||||
tm_t = sec;
|
||||
FIXME("setting time to %s not implemented for missing settimeofday\n",
|
||||
ctime(&tm_t));
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
#endif
|
||||
return unix_funcs->NtSetSystemTime( new, old );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
|
|
@ -1018,8 +1018,10 @@ static struct unix_funcs unix_funcs =
|
|||
NtPulseEvent,
|
||||
NtQueryEvent,
|
||||
NtQueryMutant,
|
||||
NtQueryPerformanceCounter,
|
||||
NtQuerySection,
|
||||
NtQuerySemaphore,
|
||||
NtQuerySystemTime,
|
||||
NtQueryTimer,
|
||||
NtQueryVirtualMemory,
|
||||
NtQueueApcThread,
|
||||
|
@ -1034,6 +1036,7 @@ static struct unix_funcs unix_funcs =
|
|||
NtSetContextThread,
|
||||
NtSetEvent,
|
||||
NtSetLdtEntries,
|
||||
NtSetSystemTime,
|
||||
NtSetTimer,
|
||||
NtSignalAndWaitForSingleObject,
|
||||
NtSuspendThread,
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
# include <mach/mach.h>
|
||||
# include <mach/task.h>
|
||||
# include <mach/semaphore.h>
|
||||
# include <mach/mach_time.h>
|
||||
#endif
|
||||
|
||||
#include "ntstatus.h"
|
||||
|
@ -66,6 +67,7 @@
|
|||
#define NONAMELESSUNION
|
||||
#include "windef.h"
|
||||
#include "winternl.h"
|
||||
#include "ddk/wdm.h"
|
||||
#include "wine/server.h"
|
||||
#include "wine/debug.h"
|
||||
#include "unix_private.h"
|
||||
|
@ -73,6 +75,8 @@
|
|||
WINE_DEFAULT_DEBUG_CHANNEL(sync);
|
||||
|
||||
#define TICKSPERSEC 10000000
|
||||
#define SECS_1601_TO_1970 ((369 * 365 + 89) * (ULONGLONG)86400)
|
||||
#define TICKS_1601_TO_1970 (SECS_1601_TO_1970 * TICKSPERSEC)
|
||||
|
||||
HANDLE keyed_event = 0;
|
||||
|
||||
|
@ -87,6 +91,34 @@ static RTL_CRITICAL_SECTION_DEBUG addr_section_debug =
|
|||
};
|
||||
static RTL_CRITICAL_SECTION addr_section = { &addr_section_debug, -1, 0, 0, 0, 0 };
|
||||
|
||||
|
||||
/* return a monotonic time counter, in Win32 ticks */
|
||||
static inline ULONGLONG monotonic_counter(void)
|
||||
{
|
||||
struct timeval now;
|
||||
#ifdef __APPLE__
|
||||
static mach_timebase_info_data_t timebase;
|
||||
|
||||
if (!timebase.denom) mach_timebase_info( &timebase );
|
||||
#ifdef HAVE_MACH_CONTINUOUS_TIME
|
||||
if (&mach_continuous_time != NULL)
|
||||
return mach_continuous_time() * timebase.numer / timebase.denom / 100;
|
||||
#endif
|
||||
return mach_absolute_time() * timebase.numer / timebase.denom / 100;
|
||||
#elif defined(HAVE_CLOCK_GETTIME)
|
||||
struct timespec ts;
|
||||
#ifdef CLOCK_MONOTONIC_RAW
|
||||
if (!clock_gettime( CLOCK_MONOTONIC_RAW, &ts ))
|
||||
return ts.tv_sec * (ULONGLONG)TICKSPERSEC + ts.tv_nsec / 100;
|
||||
#endif
|
||||
if (!clock_gettime( CLOCK_MONOTONIC, &ts ))
|
||||
return ts.tv_sec * (ULONGLONG)TICKSPERSEC + ts.tv_nsec / 100;
|
||||
#endif
|
||||
gettimeofday( &now, 0 );
|
||||
return now.tv_sec * (ULONGLONG)TICKSPERSEC + now.tv_usec * 10 + TICKS_1601_TO_1970 - server_start_time;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __linux__
|
||||
|
||||
#define FUTEX_WAIT 0
|
||||
|
@ -906,6 +938,84 @@ NTSTATUS WINAPI NtDelayExecution( BOOLEAN alertable, const LARGE_INTEGER *timeou
|
|||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* NtQueryPerformanceCounter (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI NtQueryPerformanceCounter( LARGE_INTEGER *counter, LARGE_INTEGER *frequency )
|
||||
{
|
||||
counter->QuadPart = monotonic_counter();
|
||||
if (frequency) frequency->QuadPart = TICKSPERSEC;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* NtQuerySystemTime (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI NtQuerySystemTime( LARGE_INTEGER *time )
|
||||
{
|
||||
#ifdef HAVE_CLOCK_GETTIME
|
||||
struct timespec ts;
|
||||
static clockid_t clock_id = CLOCK_MONOTONIC; /* placeholder */
|
||||
|
||||
if (clock_id == CLOCK_MONOTONIC)
|
||||
{
|
||||
#ifdef CLOCK_REALTIME_COARSE
|
||||
struct timespec res;
|
||||
|
||||
/* Use CLOCK_REALTIME_COARSE if it has 1 ms or better resolution */
|
||||
if (!clock_getres( CLOCK_REALTIME_COARSE, &res ) && res.tv_sec == 0 && res.tv_nsec <= 1000000)
|
||||
clock_id = CLOCK_REALTIME_COARSE;
|
||||
else
|
||||
#endif /* CLOCK_REALTIME_COARSE */
|
||||
clock_id = CLOCK_REALTIME;
|
||||
}
|
||||
|
||||
if (!clock_gettime( clock_id, &ts ))
|
||||
{
|
||||
time->QuadPart = ts.tv_sec * (ULONGLONG)TICKSPERSEC + TICKS_1601_TO_1970;
|
||||
time->QuadPart += (ts.tv_nsec + 50) / 100;
|
||||
}
|
||||
else
|
||||
#endif /* HAVE_CLOCK_GETTIME */
|
||||
{
|
||||
struct timeval now;
|
||||
|
||||
gettimeofday( &now, 0 );
|
||||
time->QuadPart = now.tv_sec * (ULONGLONG)TICKSPERSEC + TICKS_1601_TO_1970;
|
||||
time->QuadPart += now.tv_usec * 10;
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* NtSetSystemTime (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI NtSetSystemTime( const LARGE_INTEGER *new, LARGE_INTEGER *old )
|
||||
{
|
||||
LARGE_INTEGER now;
|
||||
LONGLONG diff;
|
||||
|
||||
NtQuerySystemTime( &now );
|
||||
if (old) *old = now;
|
||||
diff = new->QuadPart - now.QuadPart;
|
||||
if (diff > -TICKSPERSEC / 2 && diff < TICKSPERSEC / 2) return STATUS_SUCCESS;
|
||||
ERR( "not allowed: difference %d ms\n", (int)(diff / 10000) );
|
||||
return STATUS_PRIVILEGE_NOT_HELD;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* NtGetTickCount (NTDLL.@)
|
||||
*/
|
||||
ULONG WINAPI NtGetTickCount(void)
|
||||
{
|
||||
/* note: we ignore TickCountMultiplier */
|
||||
return user_shared_data->u.TickCount.LowPart;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* NtCreateKeyedEvent (NTDLL.@)
|
||||
*/
|
||||
|
|
|
@ -121,6 +121,7 @@ extern timeout_t server_start_time DECLSPEC_HIDDEN;
|
|||
extern sigset_t server_block_set DECLSPEC_HIDDEN;
|
||||
extern SIZE_T signal_stack_size DECLSPEC_HIDDEN;
|
||||
extern SIZE_T signal_stack_mask DECLSPEC_HIDDEN;
|
||||
extern struct _KUSER_SHARED_DATA *user_shared_data DECLSPEC_HIDDEN;
|
||||
|
||||
extern unsigned int server_call_unlocked( void *req_ptr ) DECLSPEC_HIDDEN;
|
||||
extern void server_enter_uninterrupted_section( RTL_CRITICAL_SECTION *cs, sigset_t *sigset ) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -161,7 +161,7 @@ static void *user_space_limit = (void *)0x7fff0000;
|
|||
static void *working_set_limit = (void *)0x7fff0000;
|
||||
#endif
|
||||
|
||||
static struct _KUSER_SHARED_DATA *user_shared_data = (void *)0x7ffe0000;
|
||||
struct _KUSER_SHARED_DATA *user_shared_data = (void *)0x7ffe0000;
|
||||
|
||||
SIZE_T signal_stack_size = 0;
|
||||
SIZE_T signal_stack_mask = 0;
|
||||
|
|
|
@ -28,7 +28,7 @@ struct ldt_copy;
|
|||
struct msghdr;
|
||||
|
||||
/* increment this when you change the function table */
|
||||
#define NTDLL_UNIXLIB_VERSION 37
|
||||
#define NTDLL_UNIXLIB_VERSION 38
|
||||
|
||||
struct unix_funcs
|
||||
{
|
||||
|
@ -96,10 +96,12 @@ struct unix_funcs
|
|||
void *info, ULONG len, ULONG *ret_len );
|
||||
NTSTATUS (WINAPI *NtQueryMutant)( HANDLE handle, MUTANT_INFORMATION_CLASS class,
|
||||
void *info, ULONG len, ULONG *ret_len );
|
||||
NTSTATUS (WINAPI *NtQueryPerformanceCounter)( LARGE_INTEGER *counter, LARGE_INTEGER *frequency );
|
||||
NTSTATUS (WINAPI *NtQuerySection)( HANDLE handle, SECTION_INFORMATION_CLASS class,
|
||||
void *ptr, SIZE_T size, SIZE_T *ret_size );
|
||||
NTSTATUS (WINAPI *NtQuerySemaphore)( HANDLE handle, SEMAPHORE_INFORMATION_CLASS class,
|
||||
void *info, ULONG len, ULONG *ret_len );
|
||||
NTSTATUS (WINAPI *NtQuerySystemTime)( LARGE_INTEGER *time );
|
||||
NTSTATUS (WINAPI *NtQueryTimer)( HANDLE handle, TIMER_INFORMATION_CLASS class,
|
||||
void *info, ULONG len, ULONG *ret_len );
|
||||
NTSTATUS (WINAPI *NtQueryVirtualMemory)( HANDLE process, LPCVOID addr,
|
||||
|
@ -120,6 +122,7 @@ struct unix_funcs
|
|||
NTSTATUS (WINAPI *NtSetContextThread)( HANDLE handle, const CONTEXT *context );
|
||||
NTSTATUS (WINAPI *NtSetEvent)( HANDLE handle, LONG *prev_state );
|
||||
NTSTATUS (WINAPI *NtSetLdtEntries)( ULONG sel1, LDT_ENTRY entry1, ULONG sel2, LDT_ENTRY entry2 );
|
||||
NTSTATUS (WINAPI *NtSetSystemTime)( const LARGE_INTEGER *new, LARGE_INTEGER *old );
|
||||
NTSTATUS (WINAPI *NtSetTimer)( HANDLE handle, const LARGE_INTEGER *when,
|
||||
PTIMER_APC_ROUTINE callback, void *arg,
|
||||
BOOLEAN resume, ULONG period, BOOLEAN *state );
|
||||
|
|
Loading…
Reference in New Issue