Namespaces

Variants
Actions

Please note that as of October 24, 2014, the Nokia Developer Wiki will no longer be accepting user contributions, including new entries, edits and comments, as we begin transitioning to our new home, in the Windows Phone Development Wiki. We plan to move over the majority of the existing entries over the next few weeks. Thanks for all your past and future contributions.

How to use Thread Local Storage

From Wiki
Jump to: navigation, search

This article explains how to use Thread Local Storage (TLS) to store DLL specific static data. Note that in most cases you won't want to do this - for application developers you're much better off enabling support for Writeable static data in your project file, as described in Symbian Platform Support for Writeable Static Data in DLLs

Note.pngNote: Historically Writeable static data in DLLs was not supported, and TLS was one mechanism to get around the limitation. WSD is now supported in DLLs via a simple project file setting.

Article Metadata
Article
Created: eswar_illuri (03 May 2007)
Last edited: hamishwillee (24 Jan 2012)

Overview

DLL can manage writable static data on a per-thread basis using thread-local storage, commonly known as "TLS". This allocates a single machine word of writable static data per thread for every DLL, regardless of whether the DLL uses it. Obviously, the memory overhead is far less significant than allocating a 4 KB chunk for each DLL which uses static data. However, the price of using TLS instead of Direct Memory Access is performance; data is retrieved from TLS about 30 times slower than direct access, because the lookup involves a context switch to the kernel in order to access the data.

Thread-local storage is usually initialized when the DLL is attached to a thread within the DLL entry point, E32Dll().Typically, code is added to construct the struct containing the global data and store it in thread-local storage using the static function Dll::SetTLS().To access the data, you should use the static function Dll::Tls(). This will return a TAny* which can be cast and used to access the data. For simplicity, you may wish to provide a utility function, or set of functions, to access the data from a single point.

TLS is thread and DLL -specific so every DLL in a thread can use it without risk of mixups.

Usage example

// Create an object and store the pointer in TLS
CSomeClass* object = CSomeClass::NewL();
User::LeaveIfError( Dll::SetTls( object ) );
 
// Get the object from TLS
object = static_cast<CSomeClass*>( Dll::Tls() );
 
// When done with the object, delete it and free TLS
delete object;
object = NULL;
Dll::FreeTls();

Note! The TLS does not take ownership of the object so the user is responsible for deleting it.

Usage example in an EXE project

The above code uses the static Dll class to access the TLS which means it only works in a DLL project. TLS can also be used in an EXE project, but through a different static class. UserSvr provides the same API to TLS except that it requires somekind of an id to the pointer being stored. The Dll class actually uses UserSvr to access TLS provinding the DLL module handle as the id. The same code example in an EXE project would look something like this:

#include <e32svr.h> // For UserSvr
 
// Define a handle. This has to be unique within the thread.
const TInt KMyTlsHandle = 0xC0FFEE;
 
// Create an object and store the pointer in TLS
CSomeObject* object = CSomeObject::NewL();
User::LeaveIfError( UserSvr::DllSetTls( KMyTlsHandle, object ) );
 
// Get the object from TLS
object = static_cast<CSomeObject*>( UserSvr::DllTls( KMyTlsHandle ) );
 
// When done with the object, delete it and free TLS
delete object;
object = NULL;
UserSvr::DllFreeTls( KMyTlsHandle );
This page was last modified on 24 January 2012, at 04:00.
66 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×