Thread Local Storage

>> Sunday, October 18, 2009


Suppose we have a Dll module, and in this dll occurs dynamic memory allocation.

If this Dll is used by only one thread of attched process, then we only need 1 pointer to save the address of new allocated memory.
But we can use this mechanism if there are many threads accessing the Dll.
Now we need TLS ( Thread Local Storage).
TLS of thread is an array of pointers, which are accessed through indexes.
We need to do the following:
+ Allocation memory
+ Work with pointer
+ Free allocated memory.
The functions used are TlsAlloc, TlsSetValue and TlsGetValue, and TlsFree.
That's all about TLS !!!
Here's the sample code of the DLL and the process with multiple threads.


#include "windows.h>
#include "iostream"
using namespace std;
int (*Add)(int);
DWORD WINAPI thread(LPVOID iNum)
{
for(int i = 0; i < (int)iNum; ++i) { cout << "count = " << Add((int)iNum) << endl; Sleep(15); } return 0;}int main(){ char c; HMODULE hDll; HANDLE hThread[2]; DWORD idThread[2]; hDll = LoadLibrary("Count.dll"); Add = (int (*)(int))GetProcAddress(hDll,"Add"); hThread[0] = CreateThread(NULL, 0, thread, (void*)3, 0, &idThread[0]); hThread[1] = CreateThread(NULL, 0, thread, (void*)5, 0, &idThread[1]); WaitForMultipleObjects(2,hThread,TRUE,INFINITE); FreeLibrary(hDll); return 0;}




Dll


#include "windows.h"
#include "iostream"
using namespace std;
DWORD dwTlsIndex;

BOOL WINAPI DllMain(HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved)
{
BOOL retVal = TRUE;
int *pCount;
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
dwTlsIndex = TlsAlloc();
break;
case DLL_THREAD_ATTACH:
pCount = new int(0);
TlsSetValue(dwTlsIndex,pCount);
break;
case DLL_THREAD_DETACH:
pCount = (int*)TlsGetValue(dwTlsIndex);
delete pCount;
break;
case DLL_PROCESS_DETACH:
TlsFree(dwTlsIndex);
brek;
}
return retVal;
}
extern "C" __declspec(dllexport) int Add(int n)
{
int *pCount;
pCount = (int*)TlsGetValue(dwTlsIndex);
*pCount += n;
return *pCount;
}

0 comments: