Bugzilla bug 135448: removed a level of code to make semaphores faster. NSPRPUB_PRE_4_2_CLIENT_BRANCH REFLOW_20020412_BASE REFLOW_20020422_BASE
authorwtc%netscape.com
Thu, 11 Apr 2002 21:50:00 +0000
branchNSPRPUB_PRE_4_2_CLIENT_BRANCH
changeset 2342 e98d531809252c5e458f43515a0ca681372e9db0
parent 2341 5fcd8f7143f15375e4c380259910ae5c3b1d2198
child 2343 b702614863441ddc5d46639edd71783523cc2a5e
child 2344 5a1d1265129623e19a785c416eb430bee8a59f00
child 2347 cd7f71bd2220d4eedf3ae3d578de2b760215c784
push idunknown
push userunknown
push dateunknown
bugs135448
Bugzilla bug 135448: removed a level of code to make semaphores faster. This patch is contributed by Michael Kaply <mkaply@us.ibm.com>. Modified files: _os2 os2cv.c os2vacpp.asm Tag: NSPRPUB_PRE_4_2_CLIENT_BRANCH
pr/include/md/_os2.h
pr/src/md/os2/os2cv.c
pr/src/md/os2/os2vacpp.asm
--- a/pr/include/md/_os2.h
+++ b/pr/include/md/_os2.h
@@ -63,20 +63,18 @@ typedef struct _RAMSEM
 } 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);
+APIRET _Optlink SemRequest486(PRAMSEM, ULONG);
+APIRET _Optlink SemReleasex86(PRAMSEM, ULONG);
 #endif
 
 #ifdef XP_OS2_EMX
 /*
  * EMX-specific tweaks:
  *    o Use stricmp instead of strcmpi.
  *    o Use errno rather than sock_errno()
  *    o Use close rather than soclose
@@ -375,21 +373,43 @@ extern PRInt32 _MD_Accept(PRFileDesc *fd
 #define _MD_BEGIN_RESUME_ALL()
 #define _MD_END_SUSPEND_ALL()
 #define _MD_END_RESUME_ALL()
 
 /* --- Lock stuff --- */
 #define _PR_LOCK                      _MD_LOCK
 #define _PR_UNLOCK					  _MD_UNLOCK
 
+#ifdef USE_RAMSEM
 #define _MD_NEW_LOCK                  (_PR_MD_NEW_LOCK)
-#define _MD_FREE_LOCK                 (_PR_MD_FREE_LOCK)
-#define _MD_LOCK                      (_PR_MD_LOCK)
-#define _MD_TEST_AND_LOCK             (_PR_MD_TEST_AND_LOCK)
-#define _MD_UNLOCK                    (_PR_MD_UNLOCK)
+#define _MD_FREE_LOCK(lock)           (DosCloseEventSem(((PRAMSEM)(&((lock)->mutex)))->hevSem))
+#define _MD_LOCK(lock)                (SemRequest486(&((lock)->mutex), -1))
+#define _MD_TEST_AND_LOCK(lock)       (SemRequest486(&((lock)->mutex), -1),0)
+#define _MD_UNLOCK(lock)              \
+    PR_BEGIN_MACRO \
+    if (0 != (lock)->notified.length) { \
+        md_UnlockAndPostNotifies((lock), NULL, NULL); \
+    } else { \
+        SemReleasex86( &(lock)->mutex, 0 ); \
+    } \
+    PR_END_MACRO
+#else
+#define _MD_NEW_LOCK                  (_PR_MD_NEW_LOCK)
+#define _MD_FREE_LOCK(lock)           (DosCloseMutexSem((lock)->mutex))
+#define _MD_LOCK(lock)                (DosRequestMutexSem((lock)->mutex, SEM_INDEFINITE_WAIT))
+#define _MD_TEST_AND_LOCK(lock)       (DosRequestMutexSem((lock)->mutex, SEM_INDEFINITE_WAIT),0)
+#define _MD_UNLOCK(lock)              \
+    PR_BEGIN_MACRO \
+    if (0 != (lock)->notified.length) { \
+        md_UnlockAndPostNotifies((lock), NULL, NULL); \
+    } else { \
+        DosReleaseMutexSem((lock)->mutex); \
+    } \
+    PR_END_MACRO
+#endif
 
 /* --- lock and cv waiting --- */
 #define _MD_WAIT                      (_PR_MD_WAIT)
 #define _MD_WAKEUP_WAITER             (_PR_MD_WAKEUP_WAITER)
 
 /* --- CVar ------------------- */
 #define _MD_WAIT_CV					  (_PR_MD_WAIT_CV)
 #define _MD_NEW_CV					  (_PR_MD_NEW_CV)
--- a/pr/src/md/os2/os2cv.c
+++ b/pr/src/md/os2/os2cv.c
@@ -45,18 +45,16 @@
  *  until right after we unlock the lock.  This way the awakened threads
  *  have a better chance to reaquire the lock.
  */
  
 #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;
@@ -111,17 +109,17 @@ AddThreadToCVWaitQueueInternal(PRThread 
  *
  * Unlock the lock, and then do the deferred condition notifies.
  * If waitThred and waitCV are not NULL, waitThred is added to
  * the wait queue of waitCV before the lock is unlocked.
  *
  * This function is called by _PR_MD_WAIT_CV and _PR_MD_UNLOCK,
  * the two places where a lock is unlocked.
  */
-static void
+void
 md_UnlockAndPostNotifies(
     _MDLock *lock,
     PRThread *waitThred,
     _MDCVar *waitCV)
 {
     PRIntn index;
     _MDNotified post;
     _MDNotified *notified, *prev = NULL;
@@ -415,58 +413,13 @@ PRStatus
     DosCreateMutexSem(0, &(lock->mutex), 0, 0);
     (lock)->notified.length=0;
     (lock)->notified.link=NULL;
     return PR_SUCCESS;
 #endif
 }
 
 void
-_PR_MD_FREE_LOCK(_MDLock *lock)
-{
-#ifdef USE_RAMSEM
-    DosCloseEventSem(((PRAMSEM)(&(lock->mutex)))->hevSem);
-#else
-    DosCloseMutexSem(lock->mutex);
-#endif
-}
-
-void _PR_MD_LOCK(_MDLock *lock)
-{
-#ifdef USE_RAMSEM
-    SemRequest486(&(lock->mutex), -1);
-#else
-    DosRequestMutexSem(lock->mutex, SEM_INDEFINITE_WAIT);
-#endif
-}
-
-PRIntn
-_PR_MD_TEST_AND_LOCK(_MDLock *lock)
-{
-#ifdef USE_RAMSEM
-    SemRequest486(&(lock->mutex), -1);
-#else
-    DosRequestMutexSem(lock->mutex, SEM_INDEFINITE_WAIT);
-#endif
-    return 0;
-}
-
-void
 _PR_MD_NOTIFYALL_CV(_MDCVar *cv, _MDLock *lock)
 {
     md_PostNotifyToCvar(cv, lock, PR_TRUE);
     return;
 }
-
-void
-_PR_MD_UNLOCK(_MDLock *lock)
-{
-    if (0 != lock->notified.length) {
-        md_UnlockAndPostNotifies(lock, NULL, NULL);
-    } else {
-#ifdef USE_RAMSEM
-        SemReleasex86( &lock->mutex, 0 );
-#else
-        DosReleaseMutexSem(lock->mutex);
-#endif
-    }
-    return;
-}
--- a/pr/src/md/os2/os2vacpp.asm
+++ b/pr/src/md/os2/os2vacpp.asm
@@ -64,127 +64,62 @@ TS_LOCKBIT                      equ     
 
 
 DATA    SEGMENT DWORD USE32 PUBLIC 'DATA'
 
         EXTRN   plisCurrent:DWORD
 
 DATA    ENDS
 
-CODE32  SEGMENT DWORD USE32 PUBLIC 'CODE'
+CODE32  SEGMENT 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
+        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      req486_inc_exit                      ; increment the use count
+        jz short req486_inc_exit                      ; increment the use count
 
-   lock inc     (ramsem PTR [ecx]).ramsem_cWaiting       ; inc waiting flag
+        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
+        jnz short req486_sleep
 
 req486_inc_exit:
    lock inc     (ramsem PTR [ecx]).ramsem_cLocks
 
 req486_exit:
         pop     ebx                                  ; Restore ebx
         ret
 
@@ -217,46 +152,46 @@ SemRequest486     ENDP
 ;;; APIRET _Optlink SemReleasex86(PRAMSEM pramsem, ULONG flFlags);
 ;;;
 ;;; Registers:
 ;;;   EAX - address of RAMSEM structure
 ;;;   ECX - temporary variable
 ;;;   EDX - flags
 ;;;---------------------------------------------------------------------
 
-        ALIGN   04H
+        ALIGN   10H
 SemReleasex86     PROC
         test    edx, SEM_RELEASE_UNOWNED             ; If set, don't bother
-        jnz     rel_ownerok                          ; getting/checking PID/TID
+        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     rel_notowner
+        jnz short rel_notowner
 
 rel_ownerok:
         test    edx, SEM_RELEASE_ALL
-        jnz     rel_clear
+        jnz short rel_clear
 
    lock dec     (ramsem PTR [eax]).ramsem_cLocks
-        jnz     rel_exit
+        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     rel_post
+        jne short rel_post
 
 rel_exit:
         xor     eax, eax
         ret
 
 rel_clear:
    lock mov     (ramsem PTR [eax]).ramsem_cLocks,0
         jmp     rel_disown
@@ -267,61 +202,58 @@ rel_notowner:
 
 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)
 ;;;---------------------------------------------------------------------
+        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)
 ;;;---------------------------------------------------------------------
+        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)
 ;;;---------------------------------------------------------------------
+        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)
 ;;;---------------------------------------------------------------------
+        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
 
 CODE32  ENDS
 END