S60 Open C
Threads, Processes, IPC, and Synchronization

Threads, Processes, IPC, and Synchronization

Table of Contents

How TLS differs between Symbian OS and POSIX?
Symbian TLS
POSIX TLS
Example code for using POSIX TLS

 


How TLS differs between Symbian OS and POSIX?

Thread Local Storage (TLS) is the memory area that is available to every thread and is not accessible to other threads. Each thread can use it for storing its thread-specific information in it. The size of the TLS and the way it is accessed is operating system-dependent. Some times the scope of the TLS also differs from OS to OS. The POSIX standard has defined the way to access TLS and the size of TLS. Symbian OS is not POSIX-compliant and has defined TLS in a different way.

 


Symbian TLS

Thread local storage is a single machine word (4 bytes) of static writable memory. The scope of this machine word is the thread, which means that there is one word per thread. The word is accessible only to code running in a DLL. Generally, this word is almost always used to hold a pointer to the allocated memory; this makes the allocated memory available to all DLL code running on behalf of the same thread. The following summarizes the main points of TLS:

  • TLS is 4 bytes of space.
  • TLS is available per DLL per thread.
  • It can be read using the Dll::Tls() API.
  • It can be written using the Dll::SetTls() API.
  • There is no need to allocate this space and free it.
  • It is available throughout the life time of the application.

 


POSIX TLS

TLS or thread-specific data is the memory area that is specific to that thread. Any DLL or executable can use this. As the name indicates, it is data that is specific to the respective thread. TLS is provided in chunks of 4 bytes. Each such 4 bytes of chunk (memory space) is called a key. If a program needs TLS, then it has to create a key. Once a key is created, an ID (handle) is returned. Subsequently this ID should be used to read and write to the key.

Creating a key

The pthread_key_create() API creates a new key and returns the ID (handle). If one thread calls pthread_key_create(), then a key (4 bytes) is created in all the threads. The ID (handle) to access that key in all threads is the same (which is returned by this API). Hence, one thread can create a key and store the handle (ID) in a global variable and all the other threads can use the same handle to access their respective key. When the key is created, it is assigned to NULL in all the threads.

In addition to this, POSIX also defines an associating destructor routine to each key. The associated destructor routine is called when the thread is terminating and the key value is not NULL. Most of the time the key holds a pointer to an allocated memory. This needs to be freed when the thread is terminating. This freeing can be done from the destructor routine. A program can create a maximum of 128 or 256 keys in a process. This value is defined as PTHREAD_KEY_MAX in the pthread.h header file.

Reading from a key

The pthread_getspecific() API can be used to get the value of the key. It takes the handle (ID) of the key as an argument.

Writing to a key

pthread_setspecific() API can be used to set the value to a key. It takes the handle (ID) of the key as argument.

Freeing the key

The pthread_key_delete() API deletes the key in all the threads. Once the key is deleted, no thread should use the old handle to set and get the key value. All the above APIs are part of the libpthread library.

The following summarizes the main points of POSIX TLS :

  • The key is 4 bytes of space.
  • The key created successfully means, that a separate key is available in all the threads. The same handle is used to access in all threads.
  • A maximum of PTHREAD_KEY_MAX keys can be created.
  • The key value can be read using the pthread_getspecific() API
  • The key value can be written using the pthread_setspecific() API.
  • The key can be created when needed and can be destroyed after use.
  • When a key is deleted, it is removed from all the threads.
  • If a thread is created after the key is created, then the key is available in the new thread from the beginning.

It is important to know if the DLL is written on top of the Open C platform, so that both POSIX TLS as well as Symbian TLS techniques can be used. Both of these techniques work without failure.

 


Example code for using POSIX TLS

#inlcude <pthread.h>
#inlcude <stdio.h>
#inlcude <stdlib.h>
#inlcude <unistd.h>

static pthread_key_t key; 
void *thread_func_1(void*)
{
   void* rc2; 
   pthread_setspecific(key, (void *)(200));
   printf("Setting Thread_1 key value to %d\n", 200); 
   sleep(5); 
   rc2 = pthread_getspecific(key);
   printf("Getting Thread_1 key value %d\n", rc2); 
   pthread_exit(0);
   return NULL;
} 
void *thread_func_2(void*) 
{
   void* rc2; 
   sleep(1); 
   pthread_setspecific(key, (void *)(400));
   printf("Setting Thread_2 key value to %d\n", 400); 
   sleep(1); 
   rc2 = pthread_getspecific(key);
   printf("Getting Thread_2 key value %d\n", rc2); 
   pthread_exit(0);
   return NULL;
} 
int main()
{
   pthread_t new_th_1;	
   pthread_t new_th_2; 
   void* rc1;     
   /* Create the key */	
   pthread_key_create(&key, NULL); 
   /* Set the value for the main thread key */ 
   pthread_setspecific(key, (void *)(100)); 
   printf("Setting Main thread key value to %d\n", 100); 
   /* Create 2 threads */
   pthread_create(&new_th1_1, NULL, thread_func_1, NULL);
   pthread_create(&new_th1_2, NULL, thread_func_2, NULL); 
   /* Wait for thread to end execution */
   pthread_join(new_th_1, NULL);
   pthread_join(new_th_2, NULL); 
   /* Get the value associated for the key in the main thread */
   rc1 = pthread_getspecific(key);
   printf("Getting Main thread key value %d\n", rc1); 
   sleep(10); 
   return 0;
}

The output is:

Setting Main thread key value to 100
Setting Thread_1 key value to 200
Setting Thread_2 key value to 400
Getting Thread_2 key value 400
Getting Thread_1 key value 200
Getting Main thread key value 100

Give feedback of this section


©Nokia 2007

Back to top


This material, including documentation and any related computer programs, is protected by copyright controlled by Nokia. All rights are reserved. Copying, including reproducing, storing, adapting or translating, any or all of this material requires the prior written consent of Nokia. This material also contains confidential information, which may not be disclosed to others without the prior written consent of Nokia.

Nokia is a registered trademark of Nokia Corporation. S60 and logo is a trademark of Nokia Corporation. Java and all Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. Other company and product names mentioned herein may be trademarks or tradenames of their respective owners.