11'' examples/manual/proguide/multithreading/criticalsectionfaq12.bas
22''
33'' Example extracted from the FreeBASIC Manual
4- '' from topic 'Critical Sections FAQ '
4+ '' from topic 'Emulate a TLS (Thread Local Storage) and a TP (Thread Pooling) feature '
55''
6- '' See Also: https://www.freebasic.net/wiki/wikka.php?wakka=ProPgMtCriticalSectionsFAQ
6+ '' See Also: https://www.freebasic.net/wiki/wikka.php?wakka=ProPgEmulateTlsTp
77'' --------
88
99#include Once "crt/string.bi"
2323#macro CreateTLSdatatypeVariableFunction (variable_function_name, variable_datatype)
2424' Creation of a "variable_function_name" function to emulate a static datatype variable (not an array),
2525' with a value depending on the thread using it.
26- Function variable_function_name ( ByVal cd As Boolean = True ) ByRef As variable_datatype
27- ' Function emulating (creation/access/destruction) a static datatype variable with value depending on thread using it:
28- ' If calling without parameter (or with 'True') parameter, this allows to [create and] access the static datatype variable.
29- ' If calling with the 'False' parameter, this allows to destroy the static datatype variable.
30- Dim As Integer bound = 0
31- Static As Any Ptr TLSindex(bound)
32- Static As variable_datatype TLSdata(bound)
33- Dim As Any Ptr Threadhandle = ThreadSelf()
34- Dim As Integer index = 0
35- For I As Integer = 1 To UBound(TLSindex) ' search existing TLS variable (existing array element) for the running thread
36- If TLSindex(I) = Threadhandle Then
37- index = I
38- Exit For
26+ Namespace TLS
27+ Function variable_function_name ( ByVal cd As Boolean = True ) ByRef As variable_datatype
28+ ' Function emulating (creation/access/destruction) a static datatype variable with value depending on thread using it:
29+ ' If calling without parameter (or with 'True') parameter, this allows to [create and] access the static datatype variable.
30+ ' If calling with the 'False' parameter, this allows to destroy the static datatype variable.
31+ Dim As Integer bound = 0
32+ Static As Any Ptr TLSindex(bound)
33+ Static As variable_datatype TLSdata(bound)
34+ Dim As Any Ptr Threadhandle = ThreadSelf()
35+ Dim As Integer index = 0
36+ For I As Integer = 1 To UBound(TLSindex) ' search existing TLS variable (existing array element) for the running thread
37+ If TLSindex(I) = Threadhandle Then
38+ index = I
39+ Exit For
40+ End If
41+ Next I
42+ If index = 0 And cd = True Then ' create a new TLS variable (new array element) for a new thread
43+ index = UBound(TLSindex) + 1
44+ ReDim Preserve TLSindex(index)
45+ TLSindex(index) = Threadhandle
46+ ReDim Preserve TLSdata(index)
47+ ElseIf index > 0 And cd = False Then ' destroy a TLS variable (array element) and compact the array
48+ If index < UBound(TLSindex) Then ' reorder the array elements
49+ memmove( @TLSindex(index), @TLSindex(index + 1 ), (UBound(TLSindex) - index) * SizeOf(Any Ptr))
50+ Dim As variable_datatype Ptr p = Allocate(SizeOf(variable_datatype)) ' for compatibility to object with destructor
51+ memmove(p, @TLSdata(index), SizeOf(variable_datatype)) ' for compatibility to object with destructor
52+ memmove( @TLSdata(index), @TLSdata(index + 1 ), (UBound(TLSdata) - index) * SizeOf(variable_datatype))
53+ memmove( @TLSdata(UBound(TLSdata)), p, SizeOf(variable_datatype)) ' for compatibility to object with destructor
54+ Deallocate(p) ' for compatibility to object with destructor
55+ End If
56+ ReDim Preserve TLSindex(UBound(TLSindex) - 1 )
57+ ReDim Preserve TLSdata(UBound(TLSdata) - 1 )
58+ index = 0
3959 End If
40- Next I
41- If index = 0 And cd = True Then ' create a new TLS variable (new array element) for a new thread
42- index = UBound(TLSindex) + 1
43- ReDim Preserve TLSindex(index)
44- TLSindex(index) = Threadhandle
45- ReDim Preserve TLSdata(index)
46- ElseIf index > 0 And cd = False Then ' destroy a TLS variable (array element) and compact the array
47- If index < UBound(TLSindex) Then ' reorder the array elements
48- memmove( @TLSindex(index), @TLSindex(index + 1 ), (UBound(TLSindex) - index) * SizeOf(Any Ptr))
49- Dim As variable_datatype Ptr p = Allocate(SizeOf(variable_datatype)) ' for compatibility to object with destructor
50- memmove(p, @TLSdata(index), SizeOf(variable_datatype)) ' for compatibility to object with destructor
51- memmove( @TLSdata(index), @TLSdata(index + 1 ), (UBound(TLSdata) - index) * SizeOf(variable_datatype))
52- memmove( @TLSdata(UBound(TLSdata)), p, SizeOf(variable_datatype)) ' for compatibility to object with destructor
53- Deallocate(p) ' for compatibility to object with destructor
54- End If
55- ReDim Preserve TLSindex(UBound(TLSindex) - 1 )
56- ReDim Preserve TLSdata(UBound(TLSdata) - 1 )
57- index = 0
58- End If
59- Return TLSdata(index)
60- End Function
60+ Return TLSdata(index)
61+ End Function
62+ End Namespace
6163#endmacro
6264
6365'------------------------------------------------------------------------------
@@ -75,11 +77,11 @@ End Type
7577 Dim As Any Ptr threadData.mutex
7678# endif
7779
78- CreateTLSdatatypeVariableFunction (TLScount , Integer ) ' create a TLS static integer function
80+ CreateTLSdatatypeVariableFunction (count , Integer ) ' create a TLS static integer function
7981
8082Function counter() As Integer ' definition of a generic counter with counting depending on thread calling it
81- TLScount () += 1 ' increment the TLS static integer
82- Return TLScount () ' return the TLS static integer
83+ TLS.count () += 1 ' increment the TLS static integer
84+ Return TLS.count () ' return the TLS static integer
8385End Function
8486
8587Sub Thread( ByVal p As Any Ptr)
@@ -101,7 +103,7 @@ Sub Thread(ByVal p As Any Ptr)
101103 MutexLock(threadData.mutex)
102104 ThreadSelf() = ptd->handle
103105 # endif
104- TLScount (False ) ' destroy the TLS static integer
106+ TLS.count (False ) ' destroy the TLS static integer
105107 # if __FB_VERSION__ < "1.08"
106108 MutexUnlock(threadData.mutex)
107109 # endif
0 commit comments