diff options
Diffstat (limited to 'pr/src/md/os2/os2vacpp.asm')
-rw-r--r-- | pr/src/md/os2/os2vacpp.asm | 199 |
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 |