зеркало из https://github.com/mozilla/gecko-dev.git
Add "fast RAM semaphore" support.
Thanks to Mike Kaply <mkaply@us.ibm.com> for the patch. Bug #125123 r=wtc
This commit is contained in:
Родитель
98bb38ac3e
Коммит
5aa65e3ac5
|
@ -47,6 +47,33 @@
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
#define USE_RAMSEM
|
||||||
|
|
||||||
|
#ifdef USE_RAMSEM
|
||||||
|
#pragma pack(4)
|
||||||
|
|
||||||
|
#pragma pack(2)
|
||||||
|
typedef struct _RAMSEM
|
||||||
|
{
|
||||||
|
ULONG ulTIDPID;
|
||||||
|
ULONG hevSem;
|
||||||
|
ULONG cLocks;
|
||||||
|
USHORT cWaiting;
|
||||||
|
USHORT cPosts;
|
||||||
|
} RAMSEM, *PRAMSEM;
|
||||||
|
|
||||||
|
typedef struct _CRITICAL_SECTION
|
||||||
|
{
|
||||||
|
ULONG ulReserved[4]; /* Same size as RAMSEM */
|
||||||
|
} CRITICAL_SECTION, *PCRITICAL_SECTION, *LPCRITICAL_SECTION;
|
||||||
|
#pragma pack(4)
|
||||||
|
|
||||||
|
VOID APIENTRY DeleteCriticalSection(PCRITICAL_SECTION);
|
||||||
|
VOID APIENTRY EnterCriticalSection(PCRITICAL_SECTION);
|
||||||
|
VOID APIENTRY InitializeCriticalSection(PCRITICAL_SECTION);
|
||||||
|
VOID APIENTRY LeaveCriticalSection(PCRITICAL_SECTION);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef XP_OS2_EMX
|
#ifdef XP_OS2_EMX
|
||||||
/*
|
/*
|
||||||
* EMX-specific tweaks:
|
* EMX-specific tweaks:
|
||||||
|
@ -162,7 +189,11 @@ struct _MDNotified {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _MDLock {
|
struct _MDLock {
|
||||||
HMTX mutex; /* this is recursive on NT */
|
#ifdef USE_RAMSEM
|
||||||
|
CRITICAL_SECTION mutex; /* this is recursive on NT */
|
||||||
|
#else
|
||||||
|
HMTX mutex; /* this is recursive on NT */
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When notifying cvars, there is no point in actually
|
* When notifying cvars, there is no point in actually
|
||||||
|
|
|
@ -48,6 +48,40 @@
|
||||||
|
|
||||||
#include "primpl.h"
|
#include "primpl.h"
|
||||||
|
|
||||||
|
#ifdef USE_RAMSEM
|
||||||
|
ULONG _Far16 _Pascal Dos16GetInfoSeg(PSEL pselGlobal, PSEL pselLocal);
|
||||||
|
APIRET _Optlink SemRequest486(PRAMSEM, ULONG);
|
||||||
|
APIRET _Optlink SemReleasex86(PRAMSEM, ULONG);
|
||||||
|
|
||||||
|
typedef struct _LINFOSEG
|
||||||
|
{
|
||||||
|
USHORT pidCurrent;
|
||||||
|
USHORT pidParent;
|
||||||
|
USHORT prtyCurrent;
|
||||||
|
USHORT tidCurrent;
|
||||||
|
USHORT sgCurrent;
|
||||||
|
UCHAR rfProcStatus;
|
||||||
|
UCHAR dummy1;
|
||||||
|
BOOL16 fForeground;
|
||||||
|
UCHAR typProcess;
|
||||||
|
UCHAR dummy2;
|
||||||
|
SEL selEnvironment;
|
||||||
|
USHORT offCmdLine;
|
||||||
|
USHORT cbDataSegment;
|
||||||
|
USHORT cbStack;
|
||||||
|
USHORT cbHeap;
|
||||||
|
USHORT hmod;
|
||||||
|
SEL selDS;
|
||||||
|
SEL selPack;
|
||||||
|
SEL selPackShr;
|
||||||
|
SEL selPackPck;
|
||||||
|
ULONG ulReserved;
|
||||||
|
} LINFOSEG;
|
||||||
|
typedef LINFOSEG FAR *PLINFOSEG;
|
||||||
|
|
||||||
|
PLINFOSEG plisCurrent = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AddThreadToCVWaitQueueInternal --
|
* AddThreadToCVWaitQueueInternal --
|
||||||
*
|
*
|
||||||
|
@ -163,7 +197,11 @@ md_UnlockAndPostNotifies(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Release the lock before notifying */
|
/* Release the lock before notifying */
|
||||||
DosReleaseMutexSem(lock->mutex);
|
#ifdef USE_RAMSEM
|
||||||
|
SemReleasex86(&lock->mutex, 0);
|
||||||
|
#else
|
||||||
|
DosReleaseMutexSem(lock->mutex);
|
||||||
|
#endif
|
||||||
|
|
||||||
notified = &post; /* this is where we start */
|
notified = &post; /* this is where we start */
|
||||||
do {
|
do {
|
||||||
|
@ -270,7 +308,11 @@ _PR_MD_WAIT_CV(_MDCVar *cv, _MDLock *lock, PRIntervalTime timeout )
|
||||||
md_UnlockAndPostNotifies(lock, thred, cv);
|
md_UnlockAndPostNotifies(lock, thred, cv);
|
||||||
} else {
|
} else {
|
||||||
AddThreadToCVWaitQueueInternal(thred, cv);
|
AddThreadToCVWaitQueueInternal(thred, cv);
|
||||||
|
#ifdef USE_RAMSEM
|
||||||
|
SemReleasex86( &lock->mutex, 0 );
|
||||||
|
#else
|
||||||
DosReleaseMutexSem(lock->mutex);
|
DosReleaseMutexSem(lock->mutex);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wait for notification or timeout; don't really care which */
|
/* Wait for notification or timeout; don't really care which */
|
||||||
|
@ -279,7 +321,11 @@ _PR_MD_WAIT_CV(_MDCVar *cv, _MDLock *lock, PRIntervalTime timeout )
|
||||||
DosResetEventSem(thred->md.blocked_sema, &count);
|
DosResetEventSem(thred->md.blocked_sema, &count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_RAMSEM
|
||||||
|
SemRequest486(&(lock->mutex), -1);
|
||||||
|
#else
|
||||||
DosRequestMutexSem((lock->mutex), SEM_INDEFINITE_WAIT);
|
DosRequestMutexSem((lock->mutex), SEM_INDEFINITE_WAIT);
|
||||||
|
#endif
|
||||||
|
|
||||||
PR_ASSERT(rv == NO_ERROR || rv == ERROR_TIMEOUT);
|
PR_ASSERT(rv == NO_ERROR || rv == ERROR_TIMEOUT);
|
||||||
|
|
||||||
|
@ -336,27 +382,70 @@ _PR_MD_NOTIFY_CV(_MDCVar *cv, _MDLock *lock)
|
||||||
PRStatus
|
PRStatus
|
||||||
_PR_MD_NEW_LOCK(_MDLock *lock)
|
_PR_MD_NEW_LOCK(_MDLock *lock)
|
||||||
{
|
{
|
||||||
|
#ifdef USE_RAMSEM
|
||||||
|
// It's better if this API traps when pCriticalSect is not a valid
|
||||||
|
// pointer, because we can't return an error code and if we just return
|
||||||
|
// the API caller will have nasty bugs that are hard to find.
|
||||||
|
|
||||||
|
PRAMSEM pramsem = (PRAMSEM)(&(lock->mutex));
|
||||||
|
/* First time, set up addresses of processor specific functions
|
||||||
|
*/
|
||||||
|
if (plisCurrent == NULL)
|
||||||
|
{
|
||||||
|
SEL selGlobal = 0, selLocal = 0;
|
||||||
|
|
||||||
|
/* Convert 16 bit global information segment to 32 bit address
|
||||||
|
* by performing CRMA on the 16 bit address: "shift" operation
|
||||||
|
* to convert sel to flat, "and" operation to mask the address
|
||||||
|
* to 32-bit
|
||||||
|
*/
|
||||||
|
Dos16GetInfoSeg(&selGlobal, &selLocal);
|
||||||
|
plisCurrent = (PLINFOSEG)(((ULONG)selLocal << 13) &
|
||||||
|
(ULONG)0x1fff0000);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(pramsem, 0, sizeof(pramsem));
|
||||||
|
DosCreateEventSem(0, &pramsem->hevSem, DC_SEM_SHARED, 0);
|
||||||
|
|
||||||
|
lock->notified.length=0;
|
||||||
|
lock->notified.link=NULL;
|
||||||
|
return PR_SUCCESS;
|
||||||
|
#else
|
||||||
DosCreateMutexSem(0, &(lock->mutex), 0, 0);
|
DosCreateMutexSem(0, &(lock->mutex), 0, 0);
|
||||||
(lock)->notified.length=0;
|
(lock)->notified.length=0;
|
||||||
(lock)->notified.link=NULL;
|
(lock)->notified.link=NULL;
|
||||||
return PR_SUCCESS;
|
return PR_SUCCESS;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_PR_MD_FREE_LOCK(_MDLock *lock)
|
_PR_MD_FREE_LOCK(_MDLock *lock)
|
||||||
{
|
{
|
||||||
|
#ifdef USE_RAMSEM
|
||||||
|
DosCloseEventSem(((PRAMSEM)(&(lock->mutex)))->hevSem);
|
||||||
|
#else
|
||||||
DosCloseMutexSem(lock->mutex);
|
DosCloseMutexSem(lock->mutex);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void _PR_MD_LOCK(_MDLock *lock)
|
void _PR_MD_LOCK(_MDLock *lock)
|
||||||
{
|
{
|
||||||
|
#ifdef USE_RAMSEM
|
||||||
|
SemRequest486(&(lock->mutex), -1);
|
||||||
|
#else
|
||||||
DosRequestMutexSem(lock->mutex, SEM_INDEFINITE_WAIT);
|
DosRequestMutexSem(lock->mutex, SEM_INDEFINITE_WAIT);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
PRIntn
|
PRIntn
|
||||||
_PR_MD_TEST_AND_LOCK(_MDLock *lock)
|
_PR_MD_TEST_AND_LOCK(_MDLock *lock)
|
||||||
{
|
{
|
||||||
|
#ifdef USE_RAMSEM
|
||||||
|
SemRequest486(&(lock->mutex), -1);
|
||||||
|
#else
|
||||||
DosRequestMutexSem(lock->mutex, SEM_INDEFINITE_WAIT);
|
DosRequestMutexSem(lock->mutex, SEM_INDEFINITE_WAIT);
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,7 +462,11 @@ _PR_MD_UNLOCK(_MDLock *lock)
|
||||||
if (0 != lock->notified.length) {
|
if (0 != lock->notified.length) {
|
||||||
md_UnlockAndPostNotifies(lock, NULL, NULL);
|
md_UnlockAndPostNotifies(lock, NULL, NULL);
|
||||||
} else {
|
} else {
|
||||||
|
#ifdef USE_RAMSEM
|
||||||
|
SemReleasex86( &lock->mutex, 0 );
|
||||||
|
#else
|
||||||
DosReleaseMutexSem(lock->mutex);
|
DosReleaseMutexSem(lock->mutex);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,20 +30,258 @@ COMMENT | -*- Mode: asm; tab-width: 8; c-basic-offset: 4 -*-
|
||||||
GPL.
|
GPL.
|
||||||
|
|
||||||
Windows uses inline assembly for their atomic functions, so we have
|
Windows uses inline assembly for their atomic functions, so we have
|
||||||
created an assembly file for VACPP on OS/2
|
created an assembly file for VACPP on OS/2.
|
||||||
|
|
||||||
|
This assembly file also contains an implementation of RAM semaphores.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
The ulTIDPID element of the RAMSEM structure is overloaded in the 386
|
||||||
|
implementation to hold the TID:PID in the lower 31 bits and the lock
|
||||||
|
bit in the high bit
|
||||||
|
|
|
|
||||||
|
page ,132
|
||||||
|
|
||||||
.486P
|
.486P
|
||||||
.MODEL FLAT, OPTLINK
|
ASSUME CS:FLAT, DS:FLAT, SS:FLAT, ES:FLAT, FS:FLAT
|
||||||
.STACK
|
|
||||||
|
|
||||||
.CODE
|
EXTRN Dos32PostEventSem:PROC
|
||||||
|
EXTRN Dos32WaitEventSem:PROC
|
||||||
|
EXTRN Dos32ResetEventSem:PROC
|
||||||
|
|
||||||
|
ramsem STRUC
|
||||||
|
ramsem_ulTIDPID DD ?
|
||||||
|
ramsem_hevSem DD ?
|
||||||
|
ramsem_cLocks DD ?
|
||||||
|
ramsem_cWaiting DW ?
|
||||||
|
ramsem_cPosts DW ?
|
||||||
|
ramsem ENDS
|
||||||
|
|
||||||
|
ERROR_SEM_TIMEOUT equ 121
|
||||||
|
ERROR_NOT_OWNER equ 288
|
||||||
|
SEM_RELEASE_UNOWNED equ 1
|
||||||
|
SEM_RELEASE_ALL equ 2
|
||||||
|
TS_LOCKBIT equ 31
|
||||||
|
|
||||||
|
|
||||||
|
DATA SEGMENT DWORD USE32 PUBLIC 'DATA'
|
||||||
|
|
||||||
|
EXTRN plisCurrent:DWORD
|
||||||
|
|
||||||
|
DATA ENDS
|
||||||
|
|
||||||
|
CODE32 SEGMENT DWORD USE32 PUBLIC 'CODE'
|
||||||
|
|
||||||
|
PUBLIC SemRequest386
|
||||||
|
PUBLIC SemRequest486
|
||||||
|
PUBLIC SemReleasex86
|
||||||
|
|
||||||
|
PUBLIC _PR_MD_ATOMIC_SET
|
||||||
|
PUBLIC _PR_MD_ATOMIC_ADD
|
||||||
|
PUBLIC _PR_MD_ATOMIC_INCREMENT
|
||||||
|
PUBLIC _PR_MD_ATOMIC_DECREMENT
|
||||||
|
|
||||||
|
;;; RAM Semaphores
|
||||||
|
|
||||||
|
;;;---------------------------------------------------------------------------
|
||||||
|
;;; APIRET _Optlink SemRequest(PRAMSEM pramsem, ULONG ulTimeout);
|
||||||
|
;;;
|
||||||
|
;;; Registers:
|
||||||
|
;;; EAX - packed TID:PID word
|
||||||
|
;;; ECX - address of RAMSEM structure
|
||||||
|
;;; EDX - length of timeout in milli-seconds
|
||||||
|
;;;---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ALIGN 04H
|
||||||
|
SemRequest386 PROC
|
||||||
|
mov ecx, eax ; For consistency use ecx
|
||||||
|
; for PRAMSEM (see 486 imp)
|
||||||
|
|
||||||
|
push ebx ; Save ebx (volatile)
|
||||||
|
mov ebx, dword ptr [plisCurrent]
|
||||||
|
mov eax, dword ptr [ebx+4] ; Place thread id in high
|
||||||
|
; word, process id in low
|
||||||
|
mov ax, word ptr [ebx] ; word
|
||||||
|
pop ebx ; Restore ebx
|
||||||
|
|
||||||
|
req386_test:
|
||||||
|
push eax
|
||||||
|
sub eax, (ramsem PTR [ecx]).ramsem_ulTIDPID ; This thread the owner?
|
||||||
|
shl eax,1 ; Don't compare top bit
|
||||||
|
pop eax
|
||||||
|
jz req386_inc_exit ; increment the use count
|
||||||
|
|
||||||
|
lock inc (ramsem PTR [ecx]).ramsem_cWaiting ; inc waiting flag
|
||||||
|
|
||||||
|
; lock ; Uncomment for SMP
|
||||||
|
lock bts (ramsem PTR [ecx]).ramsem_ulTIDPID, 31 ; Use the high bit as the
|
||||||
|
jc req386_sleep ; semaphore
|
||||||
|
or (ramsem PTR [ecx]).ramsem_ulTIDPID, eax ; Copy the rest of the bits
|
||||||
|
|
||||||
|
req386_inc_exit:
|
||||||
|
lock inc (ramsem PTR [ecx]).ramsem_cLocks
|
||||||
|
xor eax,eax
|
||||||
|
|
||||||
|
req386_exit:
|
||||||
|
ret
|
||||||
|
|
||||||
|
req386_sleep:
|
||||||
|
push eax ; Save eax (volatile)
|
||||||
|
push ecx ; Save ecx (volatile)
|
||||||
|
push edx ; Save edx (volatile)
|
||||||
|
push edx ; timeout
|
||||||
|
push (ramsem PTR [ecx]).ramsem_hevSem
|
||||||
|
call Dos32WaitEventSem
|
||||||
|
add esp, 8
|
||||||
|
pop edx ; restore edx
|
||||||
|
pop ecx ; restore ecx
|
||||||
|
or eax, eax
|
||||||
|
je req386_reset ; If no error, reset
|
||||||
|
pop edx ; junk stored eax
|
||||||
|
jmp req386_exit ; Exit, timed out
|
||||||
|
|
||||||
|
req386_reset:
|
||||||
|
push ecx ; Save ecx (volatile)
|
||||||
|
push edx ; Save edx (volatile)
|
||||||
|
sub esp, 4 ; Use stack space for
|
||||||
|
push esp ; dummy pulPostCt
|
||||||
|
push (ramsem PTR [ecx]).ramsem_hevSem
|
||||||
|
call Dos32ResetEventSem
|
||||||
|
add esp, 12
|
||||||
|
pop edx ; restore edx
|
||||||
|
pop ecx ; restore ecx
|
||||||
|
pop eax ; restore eax
|
||||||
|
jmp req386_test ; Retry the semaphore
|
||||||
|
SemRequest386 ENDP
|
||||||
|
|
||||||
|
ALIGN 04H
|
||||||
|
SemRequest486 PROC
|
||||||
|
push ebx ; Save ebx (volatile)
|
||||||
|
mov ecx, eax ; PRAMSEM must be in ecx,
|
||||||
|
; not eax, for cmpxchg
|
||||||
|
|
||||||
|
mov ebx, dword ptr [plisCurrent]
|
||||||
|
mov eax, dword ptr [ebx+4] ; Place thread id in high
|
||||||
|
; word, process id in low
|
||||||
|
mov ax, word ptr [ebx] ; word
|
||||||
|
mov ebx,eax
|
||||||
|
|
||||||
|
req486_test:
|
||||||
|
xor eax,eax
|
||||||
|
cmp (ramsem PTR [ecx]).ramsem_ulTIDPID, ebx ; If we own the sem, just
|
||||||
|
jz req486_inc_exit ; increment the use count
|
||||||
|
|
||||||
|
lock inc (ramsem PTR [ecx]).ramsem_cWaiting ; inc waiting flag
|
||||||
|
|
||||||
|
; lock ; Uncomment for SMP
|
||||||
|
DB 0F0h
|
||||||
|
; cmpxchg (ramsem PTR [ecx]).ramsem_ulTIDPID, ebx
|
||||||
|
; (byte 3 is the offset of ulProcessThread into the RAMSEM structure)
|
||||||
|
DB 00Fh
|
||||||
|
DB 0B1h
|
||||||
|
DB 019h
|
||||||
|
jnz req486_sleep
|
||||||
|
|
||||||
|
req486_inc_exit:
|
||||||
|
lock inc (ramsem PTR [ecx]).ramsem_cLocks
|
||||||
|
|
||||||
|
req486_exit:
|
||||||
|
pop ebx ; Restore ebx
|
||||||
|
ret
|
||||||
|
|
||||||
|
req486_sleep:
|
||||||
|
push ecx ; Save ecx (volatile)
|
||||||
|
push edx ; Save edx (volatile)
|
||||||
|
push edx ; timeout
|
||||||
|
push (ramsem PTR [ecx]).ramsem_hevSem
|
||||||
|
call Dos32WaitEventSem
|
||||||
|
add esp, 8
|
||||||
|
pop edx ; restore edx
|
||||||
|
pop ecx ; restore ecx
|
||||||
|
or eax, eax
|
||||||
|
jne req486_exit ; Exit, if error
|
||||||
|
|
||||||
|
push ecx ; Save ecx (volatile)
|
||||||
|
push edx ; Save edx (volatile)
|
||||||
|
sub esp, 4 ; Use stack space for
|
||||||
|
push esp ; dummy pulPostCt
|
||||||
|
push (ramsem PTR [ecx]).ramsem_hevSem
|
||||||
|
call Dos32ResetEventSem
|
||||||
|
add esp, 12
|
||||||
|
pop edx ; restore edx
|
||||||
|
pop ecx ; restore ecx
|
||||||
|
jmp req486_test ; Retry the semaphore
|
||||||
|
|
||||||
|
SemRequest486 ENDP
|
||||||
|
|
||||||
|
;;;---------------------------------------------------------------------
|
||||||
|
;;; APIRET _Optlink SemReleasex86(PRAMSEM pramsem, ULONG flFlags);
|
||||||
|
;;;
|
||||||
|
;;; Registers:
|
||||||
|
;;; EAX - address of RAMSEM structure
|
||||||
|
;;; ECX - temporary variable
|
||||||
|
;;; EDX - flags
|
||||||
|
;;;---------------------------------------------------------------------
|
||||||
|
|
||||||
|
ALIGN 04H
|
||||||
|
SemReleasex86 PROC
|
||||||
|
test edx, SEM_RELEASE_UNOWNED ; If set, don't bother
|
||||||
|
jnz rel_ownerok ; getting/checking PID/TID
|
||||||
|
|
||||||
|
push ebx ; Save ebx (volatile)
|
||||||
|
mov ebx, dword ptr [plisCurrent]
|
||||||
|
mov ecx, dword ptr [ebx+4] ; Place thread id in high
|
||||||
|
; word, process id in low
|
||||||
|
mov cx, word ptr [ebx] ; word
|
||||||
|
pop ebx ; Restore ebx
|
||||||
|
|
||||||
|
sub ecx, (ramsem PTR [eax]).ramsem_ulTIDPID ; This thread the owner?
|
||||||
|
shl ecx,1 ; Don't compare top bit
|
||||||
|
jnz rel_notowner
|
||||||
|
|
||||||
|
rel_ownerok:
|
||||||
|
test edx, SEM_RELEASE_ALL
|
||||||
|
jnz rel_clear
|
||||||
|
|
||||||
|
lock dec (ramsem PTR [eax]).ramsem_cLocks
|
||||||
|
jnz rel_exit
|
||||||
|
|
||||||
|
rel_disown:
|
||||||
|
mov (ramsem PTR [eax]).ramsem_ulTIDPID, 0
|
||||||
|
|
||||||
|
lock inc (ramsem PTR [eax]).ramsem_cPosts
|
||||||
|
mov cx, (ramsem PTR [eax]).ramsem_cWaiting
|
||||||
|
cmp (ramsem PTR [eax]).ramsem_cPosts, cx
|
||||||
|
jne rel_post
|
||||||
|
|
||||||
|
rel_exit:
|
||||||
|
xor eax, eax
|
||||||
|
ret
|
||||||
|
|
||||||
|
rel_clear:
|
||||||
|
lock mov (ramsem PTR [eax]).ramsem_cLocks,0
|
||||||
|
jmp rel_disown
|
||||||
|
|
||||||
|
rel_notowner:
|
||||||
|
mov eax, ERROR_NOT_OWNER
|
||||||
|
ret
|
||||||
|
|
||||||
|
rel_post:
|
||||||
|
mov (ramsem PTR [eax]).ramsem_cPosts, cx
|
||||||
|
push (ramsem PTR [eax]).ramsem_hevSem
|
||||||
|
call Dos32PostEventSem
|
||||||
|
add esp,4
|
||||||
|
xor eax,eax
|
||||||
|
ret
|
||||||
|
|
||||||
|
SemReleasex86 ENDP
|
||||||
|
|
||||||
|
;;; Atomic functions
|
||||||
|
|
||||||
;;;---------------------------------------------------------------------
|
;;;---------------------------------------------------------------------
|
||||||
;;; PRInt32 _Optlink _PR_MD_ATOMIC_SET(PRInt32* val, PRInt32 newval)
|
;;; PRInt32 _Optlink _PR_MD_ATOMIC_SET(PRInt32* val, PRInt32 newval)
|
||||||
;;;---------------------------------------------------------------------
|
;;;---------------------------------------------------------------------
|
||||||
_PR_MD_ATOMIC_SET PROC OPTLINK EXPORT
|
_PR_MD_ATOMIC_SET proc
|
||||||
lock xchg dword ptr [eax],edx
|
lock xchg dword ptr [eax],edx
|
||||||
mov eax, edx;
|
mov eax, edx;
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
@ -52,7 +290,7 @@ _PR_MD_ATOMIC_SET endp
|
||||||
;;;---------------------------------------------------------------------
|
;;;---------------------------------------------------------------------
|
||||||
;;; PRInt32 _Optlink _PR_MD_ATOMIC_ADD(PRInt32* ptr, PRInt32 val)
|
;;; PRInt32 _Optlink _PR_MD_ATOMIC_ADD(PRInt32* ptr, PRInt32 val)
|
||||||
;;;---------------------------------------------------------------------
|
;;;---------------------------------------------------------------------
|
||||||
_PR_MD_ATOMIC_ADD PROC OPTLINK EXPORT
|
_PR_MD_ATOMIC_ADD proc
|
||||||
mov ecx, edx
|
mov ecx, edx
|
||||||
lock xadd dword ptr [eax], edx
|
lock xadd dword ptr [eax], edx
|
||||||
mov eax, edx
|
mov eax, edx
|
||||||
|
@ -64,7 +302,7 @@ _PR_MD_ATOMIC_ADD endp
|
||||||
;;;---------------------------------------------------------------------
|
;;;---------------------------------------------------------------------
|
||||||
;;; PRInt32 _Optlink _PR_MD_ATOMIC_INCREMENT(PRInt32* val)
|
;;; PRInt32 _Optlink _PR_MD_ATOMIC_INCREMENT(PRInt32* val)
|
||||||
;;;---------------------------------------------------------------------
|
;;;---------------------------------------------------------------------
|
||||||
_PR_MD_ATOMIC_INCREMENT PROC OPTLINK EXPORT
|
_PR_MD_ATOMIC_INCREMENT proc
|
||||||
mov edx, 1
|
mov edx, 1
|
||||||
lock xadd dword ptr [eax], edx
|
lock xadd dword ptr [eax], edx
|
||||||
mov eax, edx
|
mov eax, edx
|
||||||
|
@ -76,7 +314,7 @@ _PR_MD_ATOMIC_INCREMENT endp
|
||||||
;;;---------------------------------------------------------------------
|
;;;---------------------------------------------------------------------
|
||||||
;;; PRInt32 _Optlink _PR_MD_ATOMIC_DECREMENT(PRInt32* val)
|
;;; PRInt32 _Optlink _PR_MD_ATOMIC_DECREMENT(PRInt32* val)
|
||||||
;;;---------------------------------------------------------------------
|
;;;---------------------------------------------------------------------
|
||||||
_PR_MD_ATOMIC_DECREMENT PROC OPTLINK EXPORT
|
_PR_MD_ATOMIC_DECREMENT proc
|
||||||
mov edx, 0ffffffffh
|
mov edx, 0ffffffffh
|
||||||
lock xadd dword ptr [eax], edx
|
lock xadd dword ptr [eax], edx
|
||||||
mov eax, edx
|
mov eax, edx
|
||||||
|
@ -85,4 +323,5 @@ _PR_MD_ATOMIC_DECREMENT PROC OPTLINK EXPORT
|
||||||
ret
|
ret
|
||||||
_PR_MD_ATOMIC_DECREMENT endp
|
_PR_MD_ATOMIC_DECREMENT endp
|
||||||
|
|
||||||
END
|
CODE32 ENDS
|
||||||
|
END
|
||||||
|
|
Загрузка…
Ссылка в новой задаче