summaryrefslogtreecommitdiff
path: root/pr/src/md/os2/os2vacpp.asm
diff options
context:
space:
mode:
Diffstat (limited to 'pr/src/md/os2/os2vacpp.asm')
-rw-r--r--pr/src/md/os2/os2vacpp.asm199
1 files changed, 185 insertions, 14 deletions
diff --git a/pr/src/md/os2/os2vacpp.asm b/pr/src/md/os2/os2vacpp.asm
index 2581323b..6b49e407 100644
--- a/pr/src/md/os2/os2vacpp.asm
+++ b/pr/src/md/os2/os2vacpp.asm
@@ -30,59 +30,230 @@ COMMENT | -*- Mode: asm; tab-width: 8; c-basic-offset: 4 -*-
GPL.
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
- .MODEL FLAT, OPTLINK
- .STACK
+ ASSUME CS:FLAT, DS:FLAT, SS:FLAT, ES:FLAT, FS:FLAT
+
+ 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 USE32 PUBLIC 'CODE'
+
+ PUBLIC SemRequest486
+ PUBLIC SemReleasex86
+
+ PUBLIC _PR_MD_ATOMIC_SET
+ PUBLIC _PR_MD_ATOMIC_ADD
+ PUBLIC _PR_MD_ATOMIC_INCREMENT
+ PUBLIC _PR_MD_ATOMIC_DECREMENT
+
+;;;---------------------------------------------------------------------------
+;;; 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 10H
+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 short 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 short 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
- .CODE
+ 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 10H
+SemReleasex86 PROC
+ test edx, SEM_RELEASE_UNOWNED ; If set, don't bother
+ jnz short 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 short rel_notowner
+
+rel_ownerok:
+ test edx, SEM_RELEASE_ALL
+ jnz short rel_clear
+
+ lock dec (ramsem PTR [eax]).ramsem_cLocks
+ jnz short 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 short 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
;;;---------------------------------------------------------------------
;;; PRInt32 _Optlink _PR_MD_ATOMIC_SET(PRInt32* val, PRInt32 newval)
;;;---------------------------------------------------------------------
-_PR_MD_ATOMIC_SET PROC OPTLINK EXPORT
- lock xchg dword ptr [eax],edx
+ ALIGN 10H
+_PR_MD_ATOMIC_SET proc
+ lock xchg dword ptr [eax],edx
mov eax, edx;
-
ret
_PR_MD_ATOMIC_SET endp
;;;---------------------------------------------------------------------
;;; PRInt32 _Optlink _PR_MD_ATOMIC_ADD(PRInt32* ptr, PRInt32 val)
;;;---------------------------------------------------------------------
-_PR_MD_ATOMIC_ADD PROC OPTLINK EXPORT
+ ALIGN 10H
+_PR_MD_ATOMIC_ADD proc
mov ecx, edx
lock xadd dword ptr [eax], edx
mov eax, edx
add eax, ecx
-
ret
_PR_MD_ATOMIC_ADD endp
;;;---------------------------------------------------------------------
;;; PRInt32 _Optlink _PR_MD_ATOMIC_INCREMENT(PRInt32* val)
;;;---------------------------------------------------------------------
-_PR_MD_ATOMIC_INCREMENT PROC OPTLINK EXPORT
+ ALIGN 10H
+_PR_MD_ATOMIC_INCREMENT proc
mov edx, 1
lock xadd dword ptr [eax], edx
mov eax, edx
inc eax
-
ret
_PR_MD_ATOMIC_INCREMENT endp
;;;---------------------------------------------------------------------
;;; PRInt32 _Optlink _PR_MD_ATOMIC_DECREMENT(PRInt32* val)
;;;---------------------------------------------------------------------
-_PR_MD_ATOMIC_DECREMENT PROC OPTLINK EXPORT
+ ALIGN 10H
+_PR_MD_ATOMIC_DECREMENT proc
mov edx, 0ffffffffh
lock xadd dword ptr [eax], edx
mov eax, edx
dec eax
-
ret
_PR_MD_ATOMIC_DECREMENT endp
- END
+CODE32 ENDS
+END