Indeed, I think that to be thread safe, all dynamic memory allocations/reallocations/deallocations requests are internally protected by a mutex.
So concurrent requests will actually be serialized by this internal locking/unlocking of the mutex.
This obviously happens when the user calls these requests directly, but also indirectly when using var-len strings (or string functions or string operators, on any string) or dynamic arrays.
- Example of multi-threading using the '= (assign)' operator, applied either on zstrings or on bytes:
Code: Select all
Type Thread
Dim As UInteger value
Dim As Any Ptr pHandle
Declare Static Sub thread1(ByVal pt As Thread Ptr)
Declare Static Sub thread2(ByVal pt As Thread Ptr)
End Type
Sub Thread.thread1(ByVal pt As Thread Ptr)
Dim As Zstring * 32 z
For i As Integer = 1 To pt->value
z = "X"
Next i
End Sub
Sub Thread.thread2(ByVal pt As Thread Ptr)
Dim As Zstring * 32 z
For i As Integer = 1 To pt->value
z[0] = Asc("X"): z[1] = 0
Next i
End Sub
Sub MyThreads(ByVal pThread As Any Ptr, ByVal threadNB As UInteger = 1)
Dim As Thread td(1 To threadNB)
Dim As Double t
t = Timer
For i As Integer = 1 To threadNB
td(i).value = 1000000
td(i).pHandle = ThreadCreate(pThread, @td(i))
Next I
For i As Integer = 1 To threadNB
ThreadWait(td(i).pHandle)
Next I
t = Timer - t
Print " total time for " & threadNB & " threads in parallel: " & t & " s"
Print
End Sub
Print
For i As Integer = 1 To 8
Print "Each thread using the 'z = ""X""' instruction:"
Mythreads(@Thread.thread1, I)
Print "Each thread using the 'z[0] = Asc(""X""): z[1] = 0' instruction:"
Mythreads(@Thread.thread2, I)
Print "-----------------------------------------------------------------------------"
Print
Next i
Sleep
- Output example:
Code: Select all
Each thread using the 'z = "X"' instruction:
total time for 1 threads in parallel: 0.03509200000115698 s
Each thread using the 'z[0] = Asc("X"): z[1] = 0' instruction:
total time for 1 threads in parallel: 0.007378499991006038 s
-----------------------------------------------------------------------------
Each thread using the 'z = "X"' instruction:
total time for 2 threads in parallel: 0.1292754000276091 s
Each thread using the 'z[0] = Asc("X"): z[1] = 0' instruction:
total time for 2 threads in parallel: 0.005797399973516804 s
-----------------------------------------------------------------------------
Each thread using the 'z = "X"' instruction:
total time for 3 threads in parallel: 0.2533639000275798 s
Each thread using the 'z[0] = Asc("X"): z[1] = 0' instruction:
total time for 3 threads in parallel: 0.008446999977678615 s
-----------------------------------------------------------------------------
Each thread using the 'z = "X"' instruction:
total time for 4 threads in parallel: 0.4020076999898095 s
Each thread using the 'z[0] = Asc("X"): z[1] = 0' instruction:
total time for 4 threads in parallel: 0.01053689998224172 s
-----------------------------------------------------------------------------
Each thread using the 'z = "X"' instruction:
total time for 5 threads in parallel: 0.5048076000225876 s
Each thread using the 'z[0] = Asc("X"): z[1] = 0' instruction:
total time for 5 threads in parallel: 0.009472399993427416 s
-----------------------------------------------------------------------------
Each thread using the 'z = "X"' instruction:
total time for 6 threads in parallel: 0.6370484999799544 s
Each thread using the 'z[0] = Asc("X"): z[1] = 0' instruction:
total time for 6 threads in parallel: 0.01175199999403276 s
-----------------------------------------------------------------------------
Each thread using the 'z = "X"' instruction:
total time for 7 threads in parallel: 0.8271034999968663 s
Each thread using the 'z[0] = Asc("X"): z[1] = 0' instruction:
total time for 7 threads in parallel: 0.0117849000017145 s
-----------------------------------------------------------------------------
Each thread using the 'z = "X"' instruction:
total time for 8 threads in parallel: 1.059193899973081 s
Each thread using the 'z[0] = Asc("X"): z[1] = 0' instruction:
total time for 8 threads in parallel: 0.01265520000160336 s
We see here that for 1 thread, the assign operator applied on zstrings is about 5 times slower than when it is applied on bytes, but that this factor increases to about 100 for 8 threads!
- Even the '= (equal)' operator is impacted:
Code: Select all
Type Thread
Dim As UInteger value
Dim As Any Ptr pHandle
Declare Static Sub thread1(ByVal pt As Thread Ptr)
Declare Static Sub thread2(ByVal pt As Thread Ptr)
End Type
Sub Thread.thread1(ByVal pt As Thread Ptr)
Dim As Zstring * 32 z1 = "FreeBASIC"
Dim As Zstring * 32 z2 = "version"
Dim As Integer result
For i As Integer = 1 To pt->value
result = (z1 = Z2)
Next i
End Sub
Sub Thread.thread2(ByVal pt As Thread Ptr)
Dim As Zstring * 32 z1 = "FreeBASIC"
Dim As Zstring * 32 z2 = "version"
Dim As Integer result
For i As Integer = 1 To pt->value
result = -1
If Len(z1) <> Len(z2) Then
result = 0
Else
For j As Integer = 0 To Len(z1) - 1
If z1[j] <> z2[j] Then result = 0 : Exit For
Next j
End If
Next i
End Sub
Sub MyThreads(ByVal pThread As Any Ptr, ByVal threadNB As UInteger = 1)
Dim As Thread td(1 To threadNB)
Dim As Double t
t = Timer
For i As Integer = 1 To threadNB
td(i).value = 1000000
td(i).pHandle = ThreadCreate(pThread, @td(i))
Next I
For i As Integer = 1 To threadNB
ThreadWait(td(i).pHandle)
Next I
t = Timer - t
Print " total time for " & threadNB & " threads in parallel: " & t & " s"
Print
End Sub
Print
For i As Integer = 1 To 8
Print "Each thread using the '(z1 = Z2)' instruction:"
Mythreads(@Thread.thread1, I)
Print "Each thread using the a loop on 'z1[j] <> z2[j]' instruction:"
Mythreads(@Thread.thread2, I)
Print "-----------------------------------------------------------------------------"
Print
Next i
Sleep
- Output example:
Code: Select all
Each thread using the '(z1 = Z2)' instruction:
total time for 1 threads in parallel: 0.04545439999657219 s
Each thread using the a loop on 'z1[j] <> z2[j]' instruction:
total time for 1 threads in parallel: 0.01287489997355351 s
-----------------------------------------------------------------------------
Each thread using the '(z1 = Z2)' instruction:
total time for 2 threads in parallel: 0.0903127999720823 s
Each thread using the a loop on 'z1[j] <> z2[j]' instruction:
total time for 2 threads in parallel: 0.01764429998527817 s
-----------------------------------------------------------------------------
Each thread using the '(z1 = Z2)' instruction:
total time for 3 threads in parallel: 0.1638007999845854 s
Each thread using the a loop on 'z1[j] <> z2[j]' instruction:
total time for 3 threads in parallel: 0.01940870002488282 s
-----------------------------------------------------------------------------
Each thread using the '(z1 = Z2)' instruction:
total time for 4 threads in parallel: 0.3058213999951533 s
Each thread using the a loop on 'z1[j] <> z2[j]' instruction:
total time for 4 threads in parallel: 0.02044119999339955 s
-----------------------------------------------------------------------------
Each thread using the '(z1 = Z2)' instruction:
total time for 5 threads in parallel: 0.4767383999892161 s
Each thread using the a loop on 'z1[j] <> z2[j]' instruction:
total time for 5 threads in parallel: 0.01874520001169344 s
-----------------------------------------------------------------------------
Each thread using the '(z1 = Z2)' instruction:
total time for 6 threads in parallel: 0.6476152000108186 s
Each thread using the a loop on 'z1[j] <> z2[j]' instruction:
total time for 6 threads in parallel: 0.02309240000610657 s
-----------------------------------------------------------------------------
Each thread using the '(z1 = Z2)' instruction:
total time for 7 threads in parallel: 0.8365377000048682 s
Each thread using the a loop on 'z1[j] <> z2[j]' instruction:
total time for 7 threads in parallel: 0.02092179999965538 s
-----------------------------------------------------------------------------
Each thread using the '(z1 = Z2)' instruction:
total time for 8 threads in parallel: 1.084742900010554 s
Each thread using the a loop on 'z1[j] <> z2[j]' instruction:
total time for 8 threads in parallel: 0.02315860001729675 s
-----------------------------------------------------------------------------
We see here that for 1 thread, the equal operator applied on zstrings is about 3.5 times slower than when it is applied on bytes, but that this factor increases to about 50 for 8 threads!