Added support for critical sections.

svn path=/trunk/; revision=672
This commit is contained in:
Boudewijn Dekker 1999-09-27 20:58:46 +00:00
parent 15e29ff254
commit ddc9e680c9
7 changed files with 555 additions and 494 deletions

View file

@ -1,4 +1,4 @@
# $Id: makefile,v 1.24 1999/08/29 13:44:56 dwelch Exp $
# $Id: makefile,v 1.25 1999/09/27 20:58:44 ariadne Exp $
#
# ReactOS Operating System
#
@ -22,7 +22,7 @@ endif
all: $(DLLTARGET)
SYNCH_OBJECTS = synch/critical.o synch/event.o synch/wait.o
SYNCH_OBJECTS = synch/critical.o synch/event.o synch/wait.o synch/intrlck.o synch/timer.o
MISC_OBJECTS = misc/error.o misc/atom.o misc/handle.o misc/env.o misc/dllmain.o \
misc/console.o misc/time.o misc/stubs.o
@ -32,7 +32,7 @@ FILE_OBJECTS = file/file.o file/curdir.o file/lfile.o file/dir.o \
file/create.o file/find.o file/copy.o file/pipe.o \
file/move.o file/lock.o file/rw.o file/delete.o
MEM_OBJECTS = mem/virtual.o mem/heap.o mem/utils.o
MEM_OBJECTS = mem/virtual.o mem/heap.o mem/utils.o mem/section.o
NLS_OBJECTS = nls/codepage.o nls/cpmisc.o nls/cptable.o\
nls/cp37.o nls/cp437.o nls/cp500.o nls/cp737.o nls/cp775.o nls/cp850.o nls/cp852.o nls/cp855.o nls/cp857.o\

View file

@ -27,9 +27,9 @@ HANDLE CreationFileMappingA(HANDLE hFile,
ANSI_STRING AnsiName;
UNICODE_STRING UnicodeName;
MaximumSize.LowPart = dwMaximumSizeLow;
MaximumSize.HighPart = dwMaximumSizeHigh;
RtlInitAnsiString(&AnsiString, lpName);
MaximumSize.u.LowPart = dwMaximumSizeLow;
MaximumSize.u.HighPart = dwMaximumSizeHigh;
RtlInitAnsiString(&AnsiName, (LPSTR)lpName);
RtlAnsiStringToUnicodeString(&UnicodeName, &AnsiName, TRUE);
InitializeObjectAttributes(&ObjectAttributes,
&UnicodeName,
@ -43,11 +43,13 @@ HANDLE CreationFileMappingA(HANDLE hFile,
flProtect,
0,
hFile);
if (!NT_SUCCESS(Status))
{
return(SectionHandle);
}
return(NULL);
if (!NT_SUCCESS(Status))
{
SetLastError(RtlNtStatusToDosError(Status));
return NULL;
}
return SectionHandle;
}
HANDLE CreationFileMappingW(HANDLE hFile,
@ -63,9 +65,9 @@ HANDLE CreationFileMappingW(HANDLE hFile,
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING UnicodeName;
MaximumSize.LowPart = dwMaximumSizeLow;
MaximumSize.HighPart = dwMaximumSizeHigh;
RtlInitUnicodeString(&UnicodeString, lpName);
MaximumSize.u.LowPart = dwMaximumSizeLow;
MaximumSize.u.HighPart = dwMaximumSizeHigh;
RtlInitUnicodeString(&UnicodeName, lpName);
InitializeObjectAttributes(&ObjectAttributes,
&UnicodeName,
0,
@ -78,11 +80,13 @@ HANDLE CreationFileMappingW(HANDLE hFile,
flProtect,
0,
hFile);
if (!NT_SUCCESS(Status))
{
return(SectionHandle);
}
return(NULL);
if (!NT_SUCCESS(Status))
{
SetLastError(RtlNtStatusToDosError(Status));
return NULL;
}
return SectionHandle;
}
LPVOID MapViewOfFileEx(HANDLE hFileMappingObject,
@ -94,10 +98,166 @@ LPVOID MapViewOfFileEx(HANDLE hFileMappingObject,
{
NTSTATUS Status;
LARGE_INTEGER SectionOffset;
ULONG ViewSize;
ULONG Protect;
LPVOID BaseAddress;
SectionOffset.u.LowPart = dwFileOffsetLow;
SectionOffset.u.HighPart = dwFileOffsetHigh;
if ( ( dwDesiredAccess & FILE_MAP_WRITE ) == FILE_MAP_WRITE )
Protect = PAGE_READWRITE;
else if ( ( dwDesiredAccess & FILE_MAP_READ ) == FILE_MAP_READ )
Protect = PAGE_READONLY;
else if ( ( dwDesiredAccess & FILE_MAP_ALL_ACCESS ) == FILE_MAP_ALL_ACCESS )
Protect = PAGE_READWRITE;
else if ( ( dwDesiredAccess & FILE_MAP_COPY ) == FILE_MAP_COPY )
Protect = PAGE_WRITECOPY;
else
Protect = PAGE_READWRITE;
Status = ZwMapViewOfSection(hFileMappingObject,
NtCurrentProcess(),
&lpBaseAddress,
0,
dwNumberOfBytesToMap,
NtCurrentProcess(),
&BaseAddress,
0,
dwNumberOfBytesToMap,
&SectionOffset,
&ViewSize,
ViewShare,
0,
Protect);
if (!NT_SUCCESS(Status))
{
SetLastError(RtlNtStatusToDosError(Status));
return NULL;
}
return BaseAddress;
}
LPVOID
STDCALL
MapViewOfFile (
HANDLE hFileMappingObject,
DWORD dwDesiredAccess,
DWORD dwFileOffsetHigh,
DWORD dwFileOffsetLow,
DWORD dwNumberOfBytesToMap
)
{
return MapViewOfFileEx(hFileMappingObject,dwDesiredAccess,
dwFileOffsetHigh, dwFileOffsetLow, dwNumberOfBytesToMap,NULL);
}
WINBOOL
STDCALL
UnmapViewOfFile (
LPVOID lpBaseAddress
)
{
NTSTATUS Status;
Status = NtUnmapViewOfSection(NtCurrentProcess(),lpBaseAddress);
if (!NT_SUCCESS(Status))
{
SetLastError(RtlNtStatusToDosError(Status));
return FALSE;
}
return TRUE;
}
HANDLE OpenFileMappingA(
DWORD dwDesiredAccess,
WINBOOL bInheritHandle,
LPCSTR lpName
)
{
NTSTATUS Status;
HANDLE SectionHandle;
OBJECT_ATTRIBUTES ObjectAttributes;
ANSI_STRING AnsiName;
UNICODE_STRING UnicodeName;
ULONG Attributes = 0;
if ( bInheritHandle )
Attributes = OBJ_INHERIT;
RtlInitAnsiString(&AnsiName, lpName);
RtlAnsiStringToUnicodeString(&UnicodeName, &AnsiName, TRUE);
InitializeObjectAttributes(&ObjectAttributes,
&UnicodeName,
Attributes,
NULL,
NULL);
Status = ZwOpenSection(&SectionHandle,
SECTION_ALL_ACCESS,
&ObjectAttributes
);
if (!NT_SUCCESS(Status))
{
SetLastError(RtlNtStatusToDosError(Status));
return NULL;
}
return SectionHandle;
}
HANDLE OpenFileMappingW(
DWORD dwDesiredAccess,
WINBOOL bInheritHandle,
LPCWSTR lpName
)
{
NTSTATUS Status;
HANDLE SectionHandle;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING UnicodeName;
ULONG Attributes = 0;
if ( bInheritHandle )
Attributes = OBJ_INHERIT;
RtlInitUnicodeString(&UnicodeName, lpName);
InitializeObjectAttributes(&ObjectAttributes,
&UnicodeName,
Attributes,
NULL,
NULL);
Status = ZwOpenSection(&SectionHandle,
SECTION_ALL_ACCESS,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
SetLastError(RtlNtStatusToDosError(Status));
return NULL;
}
return SectionHandle;
}

View file

@ -1,4 +1,4 @@
/* $Id: stubs.c,v 1.3 1999/08/29 06:59:03 ea Exp $
/* $Id: stubs.c,v 1.4 1999/09/27 20:58:44 ariadne Exp $
*
* KERNEL32.DLL stubs (unimplemented functions)
* Remove from this file, if you implement them.
@ -378,37 +378,8 @@ ConvertDefaultLocale (
}
HANDLE
STDCALL
CreateFileMappingA (
HANDLE hFile,
LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
DWORD flProtect,
DWORD dwMaximumSizeHigh,
DWORD dwMaximumSizeLow,
LPCSTR lpName
)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return INVALID_HANDLE_VALUE;
}
HANDLE
STDCALL
CreateFileMappingW (
HANDLE hFile,
LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
DWORD flProtect,
DWORD dwMaximumSizeHigh,
DWORD dwMaximumSizeLow,
LPCWSTR lpName
)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return INVALID_HANDLE_VALUE;
}
HANDLE
STDCALL
@ -2766,38 +2737,6 @@ InitAtomTable (
}
LONG
STDCALL
InterlockedDecrement (
LPLONG lpAddend
)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
LONG
STDCALL
InterlockedExchange (
LPLONG Target,
LONG Value
)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
LONG
STDCALL
InterlockedIncrement (
LPLONG lpAddend
)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
DWORD
@ -3157,36 +3096,6 @@ LockResource (
}
LPVOID
STDCALL
MapViewOfFile (
HANDLE hFileMappingObject,
DWORD dwDesiredAccess,
DWORD dwFileOffsetHigh,
DWORD dwFileOffsetLow,
DWORD dwNumberOfBytesToMap
)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return NULL;
}
LPVOID
STDCALL
MapViewOfFileEx (
HANDLE hFileMappingObject,
DWORD dwDesiredAccess,
DWORD dwFileOffsetHigh,
DWORD dwFileOffsetLow,
DWORD dwNumberOfBytesToMap,
LPVOID lpBaseAddress
)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return NULL;
}
int
STDCALL
@ -4047,15 +3956,6 @@ TrimVirtualBuffer (
}
WINBOOL
STDCALL
UnmapViewOfFile (
LPVOID lpBaseAddress
)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
WINBOOL

View file

@ -1277,366 +1277,4 @@ int STDCALL GetDateFormatA(LCID locale,DWORD flags,
if (xtime == NULL) {
GetSystemTime(&t);
thistime = &t;
} else {
thistime = (LPSYSTEMTIME)xtime;
};
if (format == NULL) {
GetLocaleInfoA(thislocale, ((flags&DATE_LONGDATE)
? LOCALE_SLONGDATE
: LOCALE_SSHORTDATE),
format_buf, sizeof(format_buf));
thisformat = format_buf;
} else {
thisformat = format;
};
ret = OLE_GetFormatA(thislocale, flags, 0, thistime, thisformat, date, datelen);
return ret;
}
int
STDCALL
GetTimeFormatW(
LCID Locale,
DWORD dwFlags,
CONST SYSTEMTIME *lpTime,
LPCWSTR lpFormat,
LPWSTR lpTimeStr,
int cchTime)
{
return 0;
}
/******************************************************************************
* GetTimeFormat32A [KERNEL32.422]
* Makes an ASCII string of the time
*
* Formats date according to format, or locale default if format is
* NULL. The format consists of literal characters and fields as follows:
*
* h hours with no leading zero (12-hour)
* hh hours with full two digits
* H hours with no leading zero (24-hour)
* HH hours with full two digits
* m minutes with no leading zero
* mm minutes with full two digits
* s seconds with no leading zero
* ss seconds with full two digits
* t time marker (A or P)
* tt time marker (AM, PM)
*
*/
int
STDCALL
GetTimeFormatA(
LCID Locale,
DWORD dwFlags,
CONST SYSTEMTIME *lpTime,
LPCSTR lpFormat,
LPSTR lpTimeStr,
int cchTime)
{
char format_buf[40];
LPCSTR thisformat;
SYSTEMTIME t;
LPSYSTEMTIME thistime;
LCID thislocale=0;
DWORD thisflags=LOCALE_STIMEFORMAT; /* standart timeformat */
INT ret;
thislocale = OLE2NLS_CheckLocale ( Locale );
if ( dwFlags & (TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT ))
{
//FIXME(ole,"TIME_NOTIMEMARKER or TIME_FORCE24HOURFORMAT not implemented\n");
}
dwFlags &= (TIME_NOSECONDS | TIME_NOMINUTESORSECONDS); /* mask for OLE_GetFormatA*/
if (lpFormat == NULL)
{ if (dwFlags & LOCALE_NOUSEROVERRIDE) /*use system default*/
{ thislocale = GetSystemDefaultLCID();
}
GetLocaleInfoA(thislocale, thisflags, format_buf, sizeof(format_buf));
thisformat = format_buf;
}
else
{ thisformat = lpFormat;
}
if (lpTime == NULL) /* NULL means use the current local time*/
{ GetSystemTime(&t);
thistime = &t;
}
else
{ thistime = lpTime;
}
ret = OLE_GetFormatA(thislocale, thisflags, dwFlags, thistime, thisformat,
lpTimeStr, cchTime);
return ret;
}
LCID OLE2NLS_CheckLocale (LCID locale)
{
if (!locale)
{ locale = LOCALE_SYSTEM_DEFAULT;
}
if (locale == LOCALE_SYSTEM_DEFAULT)
{ return GetSystemDefaultLCID();
}
else if (locale == LOCALE_USER_DEFAULT)
{ return GetUserDefaultLCID();
}
else
{ return locale;
}
}
/******************************************************************************
* OLE_GetFormatA [Internal]
*
* FIXME
* If datelen == 0, it should return the reguired string length.
*
This function implements stuff for GetDateFormat() and
GetTimeFormat().
d single-digit (no leading zero) day (of month)
dd two-digit day (of month)
ddd short day-of-week name
dddd long day-of-week name
M single-digit month
MM two-digit month
MMM short month name
MMMM full month name
y two-digit year, no leading 0
yy two-digit year
yyyy four-digit year
gg era string
h hours with no leading zero (12-hour)
hh hours with full two digits
H hours with no leading zero (24-hour)
HH hours with full two digits
m minutes with no leading zero
mm minutes with full two digits
s seconds with no leading zero
ss seconds with full two digits
t time marker (A or P)
tt time marker (AM, PM)
'' used to quote literal characters
'' (within a quoted string) indicates a literal '
These functions REQUIRE valid locale, date, and format.
*/
int OLE_GetFormatA(LCID locale,
DWORD flags,
DWORD tflags,
LPSYSTEMTIME xtime,
LPCSTR _format, /*in*/
LPSTR date, /*out*/
int datelen)
{
INT inpos, outpos;
int count, type, inquote, Overflow;
char buf[40];
char format[40];
char * pos;
int buflen;
const char * _dgfmt[] = { "%d", "%02d" };
const char ** dgfmt = _dgfmt - 1;
if(datelen == 0) {
return 255;
}
/* initalize state variables and output buffer */
inpos = outpos = 0;
count = 0; inquote = 0; Overflow = 0;
type = '\0';
date[0] = buf[0] = '\0';
strcpy(format,_format);
/* alter the formatstring, while it works for all languages now in wine
its possible that it fails when the time looks like ss:mm:hh as example*/
if (tflags & (TIME_NOMINUTESORSECONDS))
{ if ((pos = strstr ( format, ":mm")))
{ memcpy ( pos, pos+3, strlen(format)-(pos-format)-2 );
}
}
if (tflags & (TIME_NOSECONDS))
{ if ((pos = strstr ( format, ":ss")))
{ memcpy ( pos, pos+3, strlen(format)-(pos-format)-2 );
}
}
for (inpos = 0;; inpos++) {
/* TRACE(ole, "STATE inpos=%2d outpos=%2d count=%d inquote=%d type=%c buf,date = %c,%c\n", inpos, outpos, count, inquote, type, buf[inpos], date[outpos]); */
if (inquote) {
if (format[inpos] == '\'') {
if (format[inpos+1] == '\'') {
inpos += 1;
date[outpos++] = '\'';
} else {
inquote = 0;
continue; /* we did nothing to the output */
}
} else if (format[inpos] == '\0') {
date[outpos++] = '\0';
if (outpos > datelen) Overflow = 1;
break;
} else {
date[outpos++] = format[inpos];
if (outpos > datelen) {
Overflow = 1;
date[outpos-1] = '\0'; /* this is the last place where
it's safe to write */
break;
}
}
} else if ( (count && (format[inpos] != type))
|| count == 4
|| (count == 2 && strchr("ghHmst", type)) )
{
if (type == 'd') {
if (count == 4) {
GetLocaleInfoA(locale,
LOCALE_SDAYNAME1
+ xtime->wDayOfWeek - 1,
buf, sizeof(buf));
} else if (count == 3) {
GetLocaleInfoA(locale,
LOCALE_SABBREVDAYNAME1
+ xtime->wDayOfWeek - 1,
buf, sizeof(buf));
} else {
wsprintfA(buf, dgfmt[count], xtime->wDay);
}
} else if (type == 'M') {
if (count == 3) {
GetLocaleInfoA(locale,
LOCALE_SABBREVMONTHNAME1
+ xtime->wMonth - 1,
buf, sizeof(buf));
} else if (count == 4) {
GetLocaleInfoA(locale,
LOCALE_SMONTHNAME1
+ xtime->wMonth - 1,
buf, sizeof(buf));
} else {
wsprintfA(buf, dgfmt[count], xtime->wMonth);
}
} else if (type == 'y') {
if (count == 4) {
wsprintfA(buf, "%d", xtime->wYear);
} else if (count == 3) {
lstrcpyA(buf, "yyy");
// WARN(ole, "unknown format, c=%c, n=%d\n", type, count);
} else {
wsprintfA(buf, dgfmt[count], xtime->wYear % 100);
}
} else if (type == 'g') {
if (count == 2) {
// FIXME(ole, "LOCALE_ICALENDARTYPE unimp.\n");
lstrcpyA(buf, "AD");
} else {
lstrcpyA(buf, "g");
// WARN(ole, "unknown format, c=%c, n=%d\n", type, count);
}
} else if (type == 'h') {
/* gives us hours 1:00 -- 12:00 */
wsprintfA(buf, dgfmt[count], (xtime->wHour-1)%12 +1);
} else if (type == 'H') {
/* 24-hour time */
wsprintfA(buf, dgfmt[count], xtime->wHour);
} else if ( type == 'm') {
wsprintfA(buf, dgfmt[count], xtime->wMinute);
} else if ( type == 's') {
wsprintfA(buf, dgfmt[count], xtime->wSecond);
} else if (type == 't') {
if (count == 1) {
wsprintfA(buf, "%c", (xtime->wHour < 12) ? 'A' : 'P');
} else if (count == 2) {
/* sprintf(buf, "%s", (xtime->wHour < 12) ? "AM" : "PM"); */
GetLocaleInfoA(locale,
(xtime->wHour<12)
? LOCALE_S1159 : LOCALE_S2359,
buf, sizeof(buf));
}
};
/* we need to check the next char in the format string
again, no matter what happened */
inpos--;
/* add the contents of buf to the output */
buflen = lstrlenA(buf);
if (outpos + buflen < datelen) {
date[outpos] = '\0'; /* for strcat to hook onto */
lstrcatA(date, buf);
outpos += buflen;
} else {
date[outpos] = '\0';
strncat(date, buf, datelen - outpos);
date[datelen - 1] = '\0';
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return 0;
}
/* reset the variables we used to keep track of this item */
count = 0;
type = '\0';
} else if (format[inpos] == '\0') {
/* we can't check for this at the loop-head, because
that breaks the printing of the last format-item */
date[outpos] = '\0';
break;
} else if (count) {
/* continuing a code for an item */
count +=1;
continue;
} else if (strchr("hHmstyMdg", format[inpos])) {
type = format[inpos];
count = 1;
continue;
} else if (format[inpos] == '\'') {
inquote = 1;
continue;
} else {
date[outpos++] = format[inpos];
}
/* now deal with a possible buffer overflow */
if (outpos >= datelen) {
date[datelen - 1] = '\0';
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return 0;
}
}
if (Overflow) {
SetLastError(ERROR_INSUFFICIENT_BUFFER);
};
/* finish it off with a string terminator */
outpos++;
/* sanity check */
if (outpos > datelen-1) outpos = datelen-1;
date[outpos] = '\0';
return outpos;
}
thisti

View file

@ -1,4 +1,4 @@
/* $Id: critical.c,v 1.5 1999/08/29 06:59:03 ea Exp $
/* $Id: critical.c,v 1.6 1999/09/27 20:58:46 ariadne Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
@ -21,7 +21,8 @@ VOID
STDCALL
DeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
{
UNIMPLEMENTED;
CloseHandle(lpCriticalSection->LockSemaphore);
lpCriticalSection->Reserved = -1;
}
@ -29,7 +30,17 @@ VOID
STDCALL
EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
{
UNIMPLEMENTED;
if( InterlockedIncrement(&(lpCriticalSection->LockCount) ) != 0) {
if (lpCriticalSection->OwningThread != (HANDLE)GetCurrentThreadId() ) {
WaitForSingleObject(lpCriticalSection->LockSemaphore,100000);
// WAIT_TIMEOUT should give message if DEBUG
lpCriticalSection->OwningThread = (HANDLE)GetCurrentThreadId();
}
}
else
lpCriticalSection->OwningThread = (HANDLE)GetCurrentThreadId();
lpCriticalSection->RecursionCount++;
}
@ -37,7 +48,11 @@ VOID
STDCALL
InitializeCriticalSection(LPCRITICAL_SECTION pcritical)
{
UNIMPLEMENTED;
pcritical->LockCount = -1;
pcritical->RecursionCount = 0;
pcritical->LockSemaphore = CreateSemaphoreW(NULL,0,100,NULL);
pcritical->OwningThread = (HANDLE)-1; // critical section has no owner yet
pcritical->Reserved = 0;
}
@ -45,7 +60,19 @@ VOID
STDCALL
LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
{
UNIMPLEMENTED;
lpCriticalSection->RecursionCount--;
if ( lpCriticalSection->RecursionCount == 0 ) {
lpCriticalSection->OwningThread = (HANDLE)-1;
// if LockCount > 0 and RecursionCount == 0 there
// is a waiting thread
// ReleaseSemaphore will fire up a waiting thread
if (lpCriticalSection->LockCount > 0 )
ReleaseSemaphore( lpCriticalSection->LockSemaphore,1,NULL);
}
lpCriticalSection->LockCount--;
}
@ -53,8 +80,15 @@ WINBOOL
STDCALL
TryEnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
{
UNIMPLEMENTED;
return(FALSE);
if( InterlockedIncrement(&(lpCriticalSection->LockCount) ) != 0) {
if (lpCriticalSection->OwningThread != (HANDLE)GetCurrentThreadId() )
return FALSE;
}
else
lpCriticalSection->OwningThread = (HANDLE)GetCurrentThreadId();
lpCriticalSection->RecursionCount++;
return TRUE;
}

View file

@ -0,0 +1,162 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: lib/kernel32/sync/intrlck.c
* PURPOSE: Inter lock increments
* UPDATE HISTORY:
* Created 30/09/99
*/
/*
* Win32 kernel functions
*
* Copyright 1995 Martin von Loewis
* Copyright 1997 Onno Hovers
*/
/************************************************************************
* InterlockedIncrement *
* *
* InterlockedIncrement adds 1 to a long variable and returns *
* - a negative number if the result < 0 *
* - zero if the result == 0 *
* - a positive number if the result > 0 *
* *
* The returned number need not be equal to the result!!!! *
* note: *
* *
************************************************************************/
#include <windows.h>
LONG
STDCALL
InterlockedIncrement(PLONG Addend)
{
long ret = 0;
__asm__
(
"\tlock\n" /* for SMP systems */
"\tincl (%1)\n"
"\tje 2f\n"
"\tjl 1f\n"
"\tincl %0\n"
"\tjmp 2f\n"
"1:\tdec %0\n"
"2:\n"
:"=r" (ret):"r" (Addend), "0" (0): "memory"
);
return ret;
}
/************************************************************************
* InterlockedDecrement *
* *
* InterlockedIncrement adds 1 to a long variable and returns *
* - a negative number if the result < 0 *
* - zero if the result == 0 *
* - a positive number if the result > 0 *
* *
* The returned number need not be equal to the result!!!! *
************************************************************************/
LONG
STDCALL
InterlockedDecrement(LPLONG lpAddend)
{
long ret;
__asm__
(
"\tlock\n" /* for SMP systems */
"\tdecl (%1)\n"
"\tje 2f\n"
"\tjl 1f\n"
"\tincl %0\n"
"\tjmp 2f\n"
"1:\tdec %0\n"
"2:\n"
:"=r" (ret):"r" (lpAddend), "0" (0): "memory"
);
return ret;
}
/************************************************************************
* InterlockedExchange
*
* Atomically exchanges a pair of values.
*
* RETURNS
* Prior value of value pointed to by Target
*/
LONG
STDCALL
InterlockedExchange(LPLONG target, LONG value )
{
long ret;
__asm__ ( /* lock for SMP systems */
"lock\n\txchgl %0,(%1)"
:"=r" (ret):"r" (target), "0" (value):"memory" );
return ret;
}
/************************************************************************
* InterlockedCompareExchange
*
* Atomically compares Destination and Comperand, and if found equal exchanges
* the value of Destination with Exchange
*
* RETURNS
* Prior value of value pointed to by Destination
*/
PVOID
STDCALL
InterlockedCompareExchange(
PVOID *Destination,
PVOID Exchange,
PVOID Comperand )
{
PVOID ret;
__asm__ ( /* lock for SMP systems */
"lock\n\t"
"cmpxchgl %2,(%1)"
:"=r" (ret)
:"r" (Destination),"r" (Exchange), "0" (Comperand)
:"memory" );
return ret;
}
/************************************************************************
* InterlockedExchangeAdd
*
* Atomically adds Increment to Addend and returns the previous value of
* Addend
*
* RETURNS
* Prior value of value pointed to by Addend
*/
LONG
STDCALL
InterlockedExchangeAdd(
PLONG Addend,
LONG Increment
)
{
LONG ret;
__asm__ ( /* lock for SMP systems */
"lock\n\t"
"xaddl %0,(%1)"
:"=r" (ret)
:"r" (Addend), "0" (Increment)
:"memory" );
return ret;
}

View file

@ -0,0 +1,167 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: lib/kernel32/mem/timer.c
* PURPOSE: Implementing timer
* PROGRAMMER:
*/
/* INCLUDES ******************************************************************/
#include <windows.h>
#include <ddk/ntddk.h>
/* FUNCTIONS *****************************************************************/
HANDLE CreateWaitableTimerW(
LPSECURITY_ATTRIBUTES lpTimerAttributes,
WINBOOL bManualReset,
LPWSTR lpTimerName
)
{
NTSTATUS errCode;
HANDLE TimerHandle;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING UnicodeName;
ULONG TimerType;
if ( bManualReset )
TimerType = 1;
else
TimerType = 2;
RtlInitUnicodeString(&UnicodeName, lpTimerName);
InitializeObjectAttributes(&ObjectAttributes,
&UnicodeName,
0,
NULL,
NULL);
//TIMER_ALL_ACCESS
errCode = NtCreateTimer(
&TimerHandle,
0,
&ObjectAttributes,
TimerType
);
return TimerHandle;
}
HANDLE CreateWaitableTimerA(
LPSECURITY_ATTRIBUTES lpTimerAttributes,
WINBOOL bManualReset,
LPCSTR lpTimerName
)
{
WCHAR NameW[MAX_PATH];
ULONG i = 0;
while ((*lpTimerName)!=0 && i < MAX_PATH)
{
NameW[i] = *lpTimerName;
lpTimerName++;
i++;
}
NameW[i] = 0;
return CreateWaitableTimerW(lpTimerAttributes,
bManualReset,
NameW);
}
HANDLE OpenWaitableTimerW(
DWORD dwDesiredAccess,
WINBOOL bInheritHandle,
LPCWSTR lpTimerName
)
{
NTSTATUS errCode;
HANDLE TimerHandle;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING UnicodeName;
ULONG Attributes = 0;
if ( bInheritHandle )
Attributes = OBJ_INHERIT;
RtlInitUnicodeString(&UnicodeName, lpTimerName);
InitializeObjectAttributes(&ObjectAttributes,
&UnicodeName,
Attributes,
NULL,
NULL);
errCode = NtOpenTimer(
&TimerHandle,
dwDesiredAccess,
&ObjectAttributes
);
return TimerHandle;
}
HANDLE OpenWaitableTimerA(
DWORD dwDesiredAccess,
WINBOOL bInheritHandle,
LPCSTR lpTimerName
)
{
WCHAR NameW[MAX_PATH];
ULONG i = 0;
while ((*lpTimerName)!=0 && i < MAX_PATH)
{
NameW[i] = *lpTimerName;
lpTimerName++;
i++;
}
NameW[i] = 0;
return OpenWaitableTimerW(dwDesiredAccess, bInheritHandle,(LPCWSTR) NameW);
}
WINBOOL SetWaitableTimer(
HANDLE hTimer,
LARGE_INTEGER *pDueTime,
LONG lPeriod,
PTIMERAPCROUTINE pfnCompletionRoutine,
LPVOID lpArgToCompletionRoutine,
WINBOOL fResume
)
{
NTSTATUS errCode;
BOOLEAN pState;
errCode = NtSetTimer(hTimer, pDueTime,
pfnCompletionRoutine,
lpArgToCompletionRoutine, fResume, lPeriod, &pState);
if ( !NT_SUCCESS(errCode) ) {
SetLastError(RtlNtStatusToDosError(errCode));
return FALSE;
}
return TRUE;
}
WINBOOL CancelWaitableTimer(HANDLE hTimer)
{
NTSTATUS errCode;
BOOLEAN CurrentState;
errCode = NtCancelTimer(
hTimer,
&CurrentState
);
if ( !NT_SUCCESS(errCode) ) {
SetLastError(RtlNtStatusToDosError(errCode));
return FALSE;
}
return TRUE;
}