ThreadLocalStorage

Supports storage (variables and stack space) for every creatd thread and the main thread.  The main thread is initialized with <initmain_threadtls> all other with <init_threadtls>.

Summary
ThreadLocalStorageSupports storage (variables and stack space) for every creatd thread and the main thread.
CopyrightThis program is free software.
Files
C-kern/api/platform/task/thread_tls.hHeader file ThreadLocalStorage.
C-kern/platform/Linux/task/thread_tls.cImplementation file ThreadLocalStorage impl.
Types
struct thread_tls_tExport thread_tls_t into global namespace.
Functions
test
unittest_platform_task_thread_tlsTest thread_tls_t functionality.
thread_tls_tHolds thread local memory.
lifetime
thread_tls_FREEStatic initializer.
init_threadtlsAllocates a memory block big enoug to hold all thread local storage data.
free_threadtlsChanges protection of memory to normal and frees it.
initmain_threadtlsSame as init_threadtls but calls no other functions of C-kern system.
freemain_threadtlsSame as free_threadtls but calls no other functions of C-kern system.
query
current_threadtlsReturns thread_tls_t of the current thread.
context_threadtlsReturns pointer to threadcontext_t stored in thread local storage.
thread_threadtlsReturns pointer to thread_t stored in thread local storage.
size_threadtlsReturns the size of the allocated memory block.
signalstack_threadtlsReturns in stackmem the signalstack from tls.
threadstack_threadtlsReturns in stackmem the thread stack from tls.
generic
genericcast_threadtlsCasts pointer to an object into pointer to thread_tls_t.
inline implementation
Macros
context_threadtlsImplements thread_tls_t.context_threadtls.
current_threadtlsImplements thread_tls_t.current_threadtls.
genericcast_threadtlsImplements thread_tls_t.genericcast_threadtls.
thread_threadtlsImplements thread_tls_t.thread_threadtls.
size_threadtlsImplements thread_tls_t.size_threadtls.

Copyright

This program is free software.  You can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.

Author

© 2013 Jörg Seebohn

Files

C-kern/api/platform/task/thread_tls.h

Header file ThreadLocalStorage.

C-kern/platform/Linux/task/thread_tls.c

Implementation file ThreadLocalStorage impl.

Types

struct thread_tls_t

typedef struct thread_tls_t thread_tls_t

Export thread_tls_t into global namespace.

Functions

test

unittest_platform_task_thread_tls

int unittest_platform_task_thread_tls(void)

Test thread_tls_t functionality.

thread_tls_t

struct thread_tls_t

Holds thread local memory.  The memory comprises the variables thread_t and threadcontext_t, the signal stack and thread stack and 3 protection pages in between.

Summary
lifetime
thread_tls_FREEStatic initializer.
init_threadtlsAllocates a memory block big enoug to hold all thread local storage data.
free_threadtlsChanges protection of memory to normal and frees it.
initmain_threadtlsSame as init_threadtls but calls no other functions of C-kern system.
freemain_threadtlsSame as free_threadtls but calls no other functions of C-kern system.
query
current_threadtlsReturns thread_tls_t of the current thread.
context_threadtlsReturns pointer to threadcontext_t stored in thread local storage.
thread_threadtlsReturns pointer to thread_t stored in thread local storage.
size_threadtlsReturns the size of the allocated memory block.
signalstack_threadtlsReturns in stackmem the signalstack from tls.
threadstack_threadtlsReturns in stackmem the thread stack from tls.
generic
genericcast_threadtlsCasts pointer to an object into pointer to thread_tls_t.

lifetime

thread_tls_FREE

#define thread_tls_FREE { 0 }

Static initializer.

init_threadtls

int init_threadtls(/*out*/thread_tls_t *tls)

Allocates a memory block big enoug to hold all thread local storage data.  The access rights of parts of the memory block is changed to protect the stack from overflowing.  The allocated memory block is aligned to its own size.  The thread local variables (threadcontext_t and thread_t) are initialized with their INIT_STATIC resp.  INIT_FREEABLE values.

free_threadtls

int free_threadtls(thread_tls_t *tls)

Changes protection of memory to normal and frees it.

initmain_threadtls

int initmain_threadtls(/*out*/thread_tls_t *tls,
/*out*/struct memblock_t *threadstack,
/*out*/struct memblock_t *signalstack)

Same as init_threadtls but calls no other functions of C-kern system.  Called from platform_t.init_platform.  Especially no logging is done and no calls to pagesize_vm and <initaligned_vmpage> are made.

freemain_threadtls

int freemain_threadtls(thread_tls_t *tls)

Same as free_threadtls but calls no other functions of C-kern system.  Especially no logging is done and no calls to pagesize_vm and <free_vmpage> are made.

query

current_threadtls

thread_tls_t current_threadtls(void *local_var)

Returns thread_tls_t of the current thread.  The parameter local_var must point to a local variable on the current stack.  The function <sys_context_thread> is identical with context_threadtls(&current_threadtls(&err)).  If you change this function change sys_context_thread (and self_thread) also.

context_threadtls

struct threadcontext_t * context_threadtls(const thread_tls_t *tls)

Returns pointer to threadcontext_t stored in thread local storage.  The function <sys_context_thread> is identical with context_threadtls(&current_threadtls()).  If you change this function change sys_context_thread also.

thread_threadtls

struct thread_t * thread_threadtls(const thread_tls_t *tls)

Returns pointer to thread_t stored in thread local storage.  The function self_thread is identical with thread_threadtls(&current_threadtls()).  If you change this function change self_thread also.

size_threadtls

size_t size_threadtls(void)

Returns the size of the allocated memory block.

signalstack_threadtls

void signalstack_threadtls(const thread_tls_t *tls,
/*out*/struct memblock_t *stackmem)

Returns in stackmem the signalstack from tls.  If tls is in a freed state stackmem is set to <memblock_FREE>.  The signal stack is used in case of a signal (exceptions).  For example if the thread stack overflows SIGSEGV signal is thrown.  To handle this case the system must have an extra signal stack cause signal handling needs stack space.

threadstack_threadtls

void threadstack_threadtls(const thread_tls_t *tls,
/*out*/struct memblock_t *stackmem)

Returns in stackmem the thread stack from tls.  If tls is in a freed state stackmem is set to <memblock_FREE>.

generic

genericcast_threadtls

thread_tls_t * genericcast_threadtls(void *obj,
IDNAME nameprefix)

Casts pointer to an object into pointer to thread_tls_t.  The object must have a single member with name nameprefix##addr of the same type as thread_tls_t.

Macros

context_threadtls

#define context_threadtls(tls) ((threadcontext_t*) ( (tls)->addr ))

Implements thread_tls_t.context_threadtls.

current_threadtls

#define current_threadtls(
   local_var
) (thread_tls_t) { (uint8_t*) ( (uintptr_t)(local_var) & ~(uintptr_t) (size_threadtls()-1) ) }

Implements thread_tls_t.current_threadtls.

genericcast_threadtls

#define genericcast_threadtls(
   obj,
   nameprefix
) ( __extension__ ({ typeof(obj) _obj = (obj) ; static_assert( sizeof(_obj->nameprefix##addr) == sizeof(((thread_tls_t*)0)->addr) && (typeof(_obj->nameprefix##addr))10 == (uint8_t*)10 && 0 == offsetof(thread_tls_t, addr), "obj is compatible") ; (thread_tls_t *)(&_obj->nameprefix##addr) ; }))

Implements thread_tls_t.genericcast_threadtls.

thread_threadtls

#define thread_threadtls(
   tls
) ((thread_t*) ( (tls)->addr + sizeof(threadcontext_t) ))

Implements thread_tls_t.thread_threadtls.

size_threadtls

#define size_threadtls() (sys_size_threadtls())

Implements thread_tls_t.size_threadtls.

Supports storage (variables and stack space) for every creatd thread and the main thread.
Implements ThreadLocalStorage.
typedef struct thread_tls_t thread_tls_t
Export thread_tls_t into global namespace.
struct thread_tls_t
Holds thread local memory.
int unittest_platform_task_thread_tls(void)
Test thread_tls_t functionality.
#define thread_tls_FREE { 0 }
Static initializer.
int init_threadtls(/*out*/thread_tls_t *tls)
Allocates a memory block big enoug to hold all thread local storage data.
int free_threadtls(thread_tls_t *tls)
Changes protection of memory to normal and frees it.
int initmain_threadtls(/*out*/thread_tls_t *tls,
/*out*/struct memblock_t *threadstack,
/*out*/struct memblock_t *signalstack)
Same as init_threadtls but calls no other functions of C-kern system.
int freemain_threadtls(thread_tls_t *tls)
Same as free_threadtls but calls no other functions of C-kern system.
thread_tls_t current_threadtls(void *local_var)
Returns thread_tls_t of the current thread.
struct threadcontext_t * context_threadtls(const thread_tls_t *tls)
Returns pointer to threadcontext_t stored in thread local storage.
struct thread_t * thread_threadtls(const thread_tls_t *tls)
Returns pointer to thread_t stored in thread local storage.
size_t size_threadtls(void)
Returns the size of the allocated memory block.
void signalstack_threadtls(const thread_tls_t *tls,
/*out*/struct memblock_t *stackmem)
Returns in stackmem the signalstack from tls.
void threadstack_threadtls(const thread_tls_t *tls,
/*out*/struct memblock_t *stackmem)
Returns in stackmem the thread stack from tls.
thread_tls_t * genericcast_threadtls(void *obj,
IDNAME nameprefix)
Casts pointer to an object into pointer to thread_tls_t.
#define context_threadtls(tls) ((threadcontext_t*) ( (tls)->addr ))
Implements thread_tls_t.context_threadtls.
#define current_threadtls(
   local_var
) (thread_tls_t) { (uint8_t*) ( (uintptr_t)(local_var) & ~(uintptr_t) (size_threadtls()-1) ) }
Implements thread_tls_t.current_threadtls.
#define genericcast_threadtls(
   obj,
   nameprefix
) ( __extension__ ({ typeof(obj) _obj = (obj) ; static_assert( sizeof(_obj->nameprefix##addr) == sizeof(((thread_tls_t*)0)->addr) && (typeof(_obj->nameprefix##addr))10 == (uint8_t*)10 && 0 == offsetof(thread_tls_t, addr), "obj is compatible") ; (thread_tls_t *)(&_obj->nameprefix##addr) ; }))
Implements thread_tls_t.genericcast_threadtls.
#define thread_threadtls(
   tls
) ((thread_t*) ( (tls)->addr + sizeof(threadcontext_t) ))
Implements thread_tls_t.thread_threadtls.
#define size_threadtls() (sys_size_threadtls())
Implements thread_tls_t.size_threadtls.
int init_platform(mainthread_f main_thread,
void *user)
Initialize system context and calls main_thread.
uint32_t pagesize_vm(void)
Returns the virtual memory page size supported by the underlying system.
#define self_thread() (sys_thread_threadtls())
Implements thread_t.self_thread.
Close