It is currently Wed Jan 27, 2021 4:43 am

All times are UTC + 1 hour




Post new topic Reply to topic  [ 10 posts ] 
Author Message
 Post subject: InterlockedIncrement..., does anyone have one???
PostPosted: Wed Aug 05, 2015 12:16 am 
Offline
Addict
Addict
User avatar

Joined: Wed Sep 22, 2010 1:50 am
Posts: 811
Location: Bradenton, FL
Do any of the good people contributing to the Assembly forum have an InterlockedIncrement process they could share?

Certainly, it's easy to write with a mutex, but I believe the overhead involved is substantially more than what is needed to just lock a variable, increment it, assign it to another variable, unlock it, and have it go on its merry way.

Thanks!


Top
 Profile  
Reply with quote  
 Post subject: Re: InterlockedIncrement..., does anyone have one???
PostPosted: Wed Aug 05, 2015 5:12 am 
Offline
Addict
Addict
User avatar

Joined: Fri Sep 21, 2007 5:52 am
Posts: 3556
Location: New Zealand
you can do it via macros

assumes that you only use global vars

Code:
nableASM

Macro _gLockINC(var)
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
    lock inc dword [v_#var]
  CompilerElse
    lock inc qword [v_#var]
  CompilerEndIf   
EndMacro

Macro _gLockDEC(var)
 CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
    lock dec dword [v_#var]
  CompilerElse
    lock dec qword [v_#var]
  CompilerEndIf   
EndMacro

Macro _gLockADD(var,vadd)
 CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
    mov eax, vadd
    lock add dword [v_#var],eax
 CompilerElse
    mov rax,vadd
    lock add qword [v_#var],rax
 CompilerEndIf   
EndMacro

Macro _gLockSUB(var,vsub)
 CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
   mov eax, vsub
   lock sub dword [v_#var],eax
 CompilerElse
   mov rax, vsub
   lock sub qword [v_#var],rax
 CompilerEndIf
EndMacro

Macro _gLockXCHG(var,var1)
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
    mov eax,var1
    xchg dword [v_#var],eax
    mov var1,eax
  CompilerElse
    mov rax,var1
    xchg qword [v_#var],rax
    mov var1,rax
  CompilerEndIf
EndMacro

Macro _gLockINCXCHG(var,var1)
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
    lock inc dword [v_#var1]
    lock xchg eax, [v_#var1]
    mov var , eax
  CompilerElse
    lock inc qword [v_#var1]
    lock xchg rax, [v_#var1]
    mov var , rax
  CompilerEndIf
EndMacro

Macro SpinLock(var)
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
  !mov ecx,1
  !Spinlock#MacroExpandedCount:
  !xor eax,eax
  lock cmpxchg dword [v_#var],ecx
  !jnz Spinlock#MacroExpandedCount
 CompilerElse
  !mov rcx,1
  !Spinlock#MacroExpandedCount:
  !xor rax,rax
  lock cmpxchg qword [v_#var],rcx
  !jnz Spinlock#MacroExpandedCount
 CompilerEndIf 
EndMacro

Macro SpinUnlock(var)
  _gLockDEC(var)
EndMacro   


Global a=0,b=2
_gLockINC(a)
Debug a
_gLockADD(a,b)
Debug a
_gLockSUB(a,b)
Debug a
_gLockDEC(a)
Debug a

Global lock

Procedure tSpin(v)
   
  For a = 0 To 10
     SpinLock(lock)
     Debug "thread " + Str(v)
     SpinUnlock(lock) 
     Delay(1)
  Next   
     
EndProcedure   

t1 = CreateThread(@tspin(),1)
t2 = CreateThread(@tspin(),2)

Delay(1000)


Global nextSocketToUse=1 

Procedure attach()
  Protected useThisNumber
  _gLockINCXCHG(useThisNumber,nextSocketToUse)
  Debug useThisNumber ;=2
   
EndProcedure   

attach()



Top
 Profile  
Reply with quote  
 Post subject: Re: InterlockedIncrement..., does anyone have one???
PostPosted: Wed Aug 05, 2015 10:13 am 
Offline
Addict
Addict

Joined: Fri Nov 09, 2012 11:04 pm
Posts: 1811
Location: Uttoxeter, UK
@idle,

This error occurred on my MacBook Pro:
OSX wrote:
purebasic.asm:835: error: undefined symbol `@b’ (first use)
purebasic.asm:835: error: (for each undefined symbol is reported only once.)

_________________
DE AA EB


Top
 Profile  
Reply with quote  
 Post subject: Re: InterlockedIncrement..., does anyone have one???
PostPosted: Wed Aug 05, 2015 10:32 am 
Offline
Addict
Addict
User avatar

Joined: Fri Sep 21, 2007 5:52 am
Posts: 3556
Location: New Zealand
davido wrote:
@idle,

This error occurred on my MacBook Pro:
OSX wrote:
purebasic.asm:835: error: undefined symbol `@b’ (first use)
purebasic.asm:835: error: (for each undefined symbol is reported only once.)


Thanks, I did mention the spinlock won't work on osx as it's using fasm's anonymous labels

I've edited the post and updated it, so should work now :)


Top
 Profile  
Reply with quote  
 Post subject: Re: InterlockedIncrement..., does anyone have one???
PostPosted: Wed Aug 05, 2015 8:42 pm 
Offline
Addict
Addict
User avatar

Joined: Wed Sep 22, 2010 1:50 am
Posts: 811
Location: Bradenton, FL
Thank you Idle for your time and efforts with this. It is truly appreciated!

I'm not sure I explained myself clearly enough as to what I need this for. I have an IIS Extension dll process running inside, of course, Internet Information Server, the web server from Microsoft. When the Extension initially loads, the AttachProcess procedure creates a fixed number of client socket connections to a separate server process. The number of connections is limited to the numberConnections variable. As the sockets connect, they are set to an initial available state, by setting availabConnections(useThisNumber) = 0. As browsers connect to the IIS server, and request data, a thread will check for an available socket. If the socket is available, it will grab the socket, and request data. Basically, it looks like this:
Code:
; AttachProcess...
    Global useConnectLock.i  = CreateMutex()

; thread procedure...
; now lock the mutex, and get the next socket to use

    Repeat
        attemptCount    + 1

        LockMutex(useConnectLock)
        nextSocketToUse + 1
        useThisNumber   = nextSocketToUse
        UnlockMutex(useConnectLock)

        useThisNumber   = Mod(useThisNumber, numberConnections)

        If  availabConnections(useThisNumber) = 0
            socketToUse = mappingConnections(useThisNumber)
            If socketToUse > 0
                availabConnections(useThisNumber) = 1
                Break
            EndIf
        Else
            Delay(10 * attemptCount)
        EndIf
    ForEver

; send request to server, read in returned data

; now release the socket we used

    availabConnections(useThisNumber) = 0

From what I have read, using a mutex for this is like using a sledgehammer to kill a mosquito. There must be a lightweight way to lock access to a global integer or address, increment it, assign the value to local variable, then release the lock. My concern is that the local variable must be assigned, before the lock is released, to keep from crashing by two threads attempting to use a single socket.


Top
 Profile  
Reply with quote  
 Post subject: Re: InterlockedIncrement..., does anyone have one???
PostPosted: Wed Aug 05, 2015 9:13 pm 
Offline
Addict
Addict

Joined: Fri Nov 09, 2012 11:04 pm
Posts: 1811
Location: Uttoxeter, UK
@idle,

The following errors now occur:
OSX wrote:
purebasic.asm:124: error: invalid size for operand 1
purebasic.asm:181: error: invalid size for operand 1
purebasic.asm:931: error: invalid size for operand 1


This is purely for your information should you find it useful.
It is not a request to you to put it right.

_________________
DE AA EB


Top
 Profile  
Reply with quote  
 Post subject: Re: InterlockedIncrement..., does anyone have one???
PostPosted: Wed Aug 05, 2015 10:49 pm 
Offline
Addict
Addict
User avatar

Joined: Fri Sep 21, 2007 5:52 am
Posts: 3556
Location: New Zealand
RichAlgeni wrote:
Thank you Idle for your time and efforts with this. It is truly appreciated!

I'm not sure I explained myself clearly enough as to what I need this for. I have an IIS Extension dll process running inside, of course, Internet Information Server, the web server from Microsoft. When the Extension initially loads, the AttachProcess procedure creates a fixed number of client socket connections to a separate server process. The number of connections is limited to the numberConnections variable. As the sockets connect, they are set to an initial available state, by setting availabConnections(useThisNumber) = 0. As browsers connect to the IIS server, and request data, a thread will check for an available socket. If the socket is available, it will grab the socket, and request data. Basically, it looks like this:
Code:
; AttachProcess...
    Global useConnectLock.i  = CreateMutex()

; thread procedure...
; now lock the mutex, and get the next socket to use

    Repeat
        attemptCount    + 1

        LockMutex(useConnectLock)
        nextSocketToUse + 1
        useThisNumber   = nextSocketToUse
        UnlockMutex(useConnectLock)

        useThisNumber   = Mod(useThisNumber, numberConnections)

        If  availabConnections(useThisNumber) = 0
            socketToUse = mappingConnections(useThisNumber)
            If socketToUse > 0
                availabConnections(useThisNumber) = 1
                Break
            EndIf
        Else
            Delay(10 * attemptCount)
        EndIf
    ForEver

; send request to server, read in returned data

; now release the socket we used

    availabConnections(useThisNumber) = 0

From what I have read, using a mutex for this is like using a sledgehammer to kill a mosquito. There must be a lightweight way to lock access to a global integer or address, increment it, assign the value to local variable, then release the lock. My concern is that the local variable must be assigned, before the lock is released, to keep from crashing by two threads attempting to use a single socket.



I don't know what the best option is
PB mutex is a critical section so it's probably not that bad.
but if you have a thread pool maybe semaphores are a better option to use so the thread can sleep until a connection request is made
as for a spinlock it might be ok in this case but It depends on how fast it can be resolved as it'll just eat cycles

but if you just need an atomic inc and set maybe this will work

Code:
Macro _gLockINCXCHG(var,var1)
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
    lock inc dword [v_#var1]
    lock xchg eax, [v_#var1]
    mov var , eax
  CompilerElse
    lock inc qword [v_#var1]
    lock xchg rax, [v_#var1]
    mov var , rax
  CompilerEndIf
EndMacro

Global nextSocketToUse=1 

Procedure attach()
  Protected useThisNumber

  _gLockINCXCHG(useThisNumber,nextSocketToUse)
  Debug useThisNumber 
   
EndProcedure   

attach()



@davido

it'll be wanting me to specify the sizes as either a qword or dword
maybe wilbert can take a look since I don't have osx


Top
 Profile  
Reply with quote  
 Post subject: Re: InterlockedIncrement..., does anyone have one???
PostPosted: Thu Aug 06, 2015 3:36 am 
Offline
Addict
Addict
User avatar

Joined: Wed Sep 22, 2010 1:50 am
Posts: 811
Location: Bradenton, FL
I'll try it out, thanks Idle!


Top
 Profile  
Reply with quote  
 Post subject: Re: InterlockedIncrement..., does anyone have one???
PostPosted: Thu Aug 06, 2015 4:28 am 
Offline
Addict
Addict

Joined: Fri Nov 09, 2012 11:04 pm
Posts: 1811
Location: Uttoxeter, UK
@idle,


idle wrote:
@davido

it'll be wanting me to specify the sizes as either a qword or dword
maybe wilbert can take a look since I don't have osx


Seems to work OK, now.

Debugger wrote:
1
3
1
0
thread 1
thread 2
thread 2
thread 1
thread 1
thread 2
thread 1
thread 2
thread 1
thread 2
thread 1
thread 2
thread 2
thread 1
thread 2
thread 1
2


Excellent. Thank you.

_________________
DE AA EB


Top
 Profile  
Reply with quote  
 Post subject: Re: InterlockedIncrement..., does anyone have one???
PostPosted: Thu Aug 06, 2015 6:22 am 
Offline
Addict
Addict
User avatar

Joined: Fri Sep 21, 2007 5:52 am
Posts: 3556
Location: New Zealand
thanks for the debugging help.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 10 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye