InterlockedIncrement..., does anyone have one???
- RichAlgeni
- Addict
- Posts: 914
- Joined: Wed Sep 22, 2010 1:50 am
- Location: Bradenton, FL
InterlockedIncrement..., does anyone have one???
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!
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!
Re: InterlockedIncrement..., does anyone have one???
you can do it via macros
assumes that you only use global vars
assumes that you only use global vars
Code: Select all
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()
Windows 11, Manjaro, Raspberry Pi OS
Re: InterlockedIncrement..., does anyone have one???
@idle,
This error occurred on my MacBook Pro:
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
Re: InterlockedIncrement..., does anyone have one???
Thanks, I did mention the spinlock won't work on osx as it's using fasm's anonymous labelsdavido 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.)
I've edited the post and updated it, so should work now
Windows 11, Manjaro, Raspberry Pi OS
- RichAlgeni
- Addict
- Posts: 914
- Joined: Wed Sep 22, 2010 1:50 am
- Location: Bradenton, FL
Re: InterlockedIncrement..., does anyone have one???
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:
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'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: Select all
; 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
Re: InterlockedIncrement..., does anyone have one???
@idle,
The following errors now occur:
It is not a request to you to put it right.
The following errors now occur:
This is purely for your information should you find it useful.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
It is not a request to you to put it right.
DE AA EB
Re: InterlockedIncrement..., does anyone have one???
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: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.Code: Select all
; 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
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: Select all
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
Windows 11, Manjaro, Raspberry Pi OS
- RichAlgeni
- Addict
- Posts: 914
- Joined: Wed Sep 22, 2010 1:50 am
- Location: Bradenton, FL
Re: InterlockedIncrement..., does anyone have one???
I'll try it out, thanks Idle!
Re: InterlockedIncrement..., does anyone have one???
@idle,
Seems to work OK, now.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
Excellent. Thank you.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
DE AA EB
Re: InterlockedIncrement..., does anyone have one???
thanks for the debugging help.
Windows 11, Manjaro, Raspberry Pi OS