Hi all,

I was in need of using thread local storage for some of the EvasGL stuff that
I'm currently working on. I've noticed that Eina doesn't have thread local
storage functions.  It would be best to simply use load-time TLS by using
__thread in Linux or __declspec(thread) in Windows in front of variables but
these two are not supported in all platforms that EFL supports.

You can check out what's supported in different platforms at this link below:

https://chtekk.longitekk.com/index.php?/archives/70-TLS-and-shared-library-initialization.html

So, I've decdied to add Eina APIs for run-time TLS support.

Here's an initial set of APIs that I've implemented.

static inline Eina_Bool eina_tls_new(Eina_TLS *key);
static inline void eina_tls_free(Eina_TLS key);
static inline void *eina_tls_get(Eina_TLS key);
static inline Eina_Bool eina_tls_set(Eina_TLS key, const void *data);

I didn't add destructor function pointer in eina_tls_new even though it's
supported in pthreads because they're not supported in windows.

I've tested the posix implmentation but I haven't been able to test the Windows
version.  If someone can review/test the code, that would be very helpful.

Let me know what you think.

cheers,
Sung
Index: src/include/eina_inline_lock_void.x
===================================================================
--- src/include/eina_inline_lock_void.x	(revision 64010)
+++ src/include/eina_inline_lock_void.x	(working copy)
@@ -215,6 +215,30 @@
    return EINA_LOCK_FAIL;
 }
 
+static inline Eina_Bool 
+eina_tls_new(Eina_TLS *key)
+{
+   return EINA_FALSE;
+}
+
+static inline void 
+eina_tls_free(Eina_TLS key)
+{
+}
+
+static inline void *
+eina_tls_get(Eina_TLS key)
+{
+   return NULL;
+}
+
+static inline Eina_Bool 
+eina_tls_set(Eina_TLS key, const void *data)
+{
+   return EINA_FALSE;
+}
+
+
 /**
  * @}
  */
Index: src/include/eina_inline_lock_win32.x
===================================================================
--- src/include/eina_inline_lock_win32.x	(revision 64010)
+++ src/include/eina_inline_lock_win32.x	(working copy)
@@ -433,4 +433,32 @@
    return EINA_LOCK_SUCCEED;
 }
 
+static inline Eina_Bool 
+eina_tls_new(Eina_TLS *key)
+{
+   if (TlsAlloc() == TLS_OUT_OF_INDEXES)
+      return EINA_FALSE;
+   return EINA_TRUE;
+}
+
+static inline void 
+eina_tls_free(Eina_TLS key)
+{
+   TlsFree(key);
+}
+
+static inline void *
+eina_tls_get(Eina_TLS key)
+{
+   return (void*)TlsGetValue(key);
+}
+
+static inline Eina_Bool 
+eina_tls_set(Eina_TLS key, const void *data)
+{
+   if (TlsSetValue(key, (LPVOID)data) == 0)
+      return EINA_FALSE;
+   return EINA_TRUE;
+}
+
 #endif
Index: src/include/eina_lock.h
===================================================================
--- src/include/eina_lock.h	(revision 64010)
+++ src/include/eina_lock.h	(working copy)
@@ -76,6 +76,12 @@
 static inline Eina_Lock_Result eina_rwlock_take_write(Eina_RWLock *mutex);
 static inline Eina_Lock_Result eina_rwlock_release(Eina_RWLock *mutex);
 
+static inline Eina_Bool eina_tls_new(Eina_TLS *key);
+static inline void eina_tls_free(Eina_TLS key);
+static inline void *eina_tls_get(Eina_TLS key);
+static inline Eina_Bool eina_tls_set(Eina_TLS key, const void *data);
+
+
 #ifdef EINA_HAVE_DEBUG_THREADS
 # define EINA_MAIN_LOOP_CHECK_RETURN_VAL(val)				\
   do {									\
Index: src/include/eina_inline_lock_wince.x
===================================================================
--- src/include/eina_inline_lock_wince.x	(revision 64010)
+++ src/include/eina_inline_lock_wince.x	(working copy)
@@ -23,8 +23,9 @@
 
 EAPI extern Eina_Bool _threads_activated;
 
-typedef HANDLE Eina_Lock;
+typedef HANDLE    Eina_Lock;
 typedef Eina_Lock Eina_RWLock;
+typedef DWORD     Eina_TLS;
 
 static inline Eina_Bool
 eina_lock_new(Eina_Lock *mutex)
@@ -144,4 +145,34 @@
    return eina_lock_release(mutex);
 }
 
+static inline Eina_Bool 
+eina_tls_new(Eina_TLS *key)
+{
+   if (TlsAlloc() == TLS_OUT_OF_INDEXES)
+      return EINA_FALSE;
+   return EINA_TRUE;
+}
+
+static inline void 
+eina_tls_free(Eina_TLS key)
+{
+   TlsFree(key);
+}
+
+static inline void *
+eina_tls_get(Eina_TLS key)
+{
+   return (void*)TlsGetValue(key);
+}
+
+static inline Eina_Bool 
+eina_tls_set(Eina_TLS key, const void *data)
+{
+   if (TlsSetValue(key, (LPVOID)data) == 0)
+      return EINA_FALSE;
+   return EINA_TRUE;
+}
+
+
+
 #endif
Index: src/include/eina_inline_lock_posix.x
===================================================================
--- src/include/eina_inline_lock_posix.x	(revision 64010)
+++ src/include/eina_inline_lock_posix.x	(working copy)
@@ -44,6 +44,7 @@
 typedef struct _Eina_Lock Eina_Lock;
 typedef struct _Eina_RWLock Eina_RWLock;
 typedef struct _Eina_Condition Eina_Condition;
+typedef pthread_key_t Eina_TLS;
 
 struct _Eina_Lock
 {
@@ -477,4 +478,32 @@
    return EINA_LOCK_SUCCEED;
 }
 
+static inline Eina_Bool 
+eina_tls_new(Eina_TLS *key)
+{
+   if (pthread_key_create(key, NULL) != 0)
+      return EINA_FALSE;
+   return EINA_TRUE;
+}
+
+static inline void 
+eina_tls_free(Eina_TLS key)
+{
+   pthread_key_delete(key);
+}
+
+static inline void * 
+eina_tls_get(Eina_TLS key)
+{
+   return pthread_getspecific(key);
+}
+
+static inline Eina_Bool 
+eina_tls_set(Eina_TLS key, const void *data)
+{
+   if (pthread_setspecific(key, data) != 0)
+      return EINA_FALSE;
+   return EINA_TRUE;
+}
+
 #endif
------------------------------------------------------------------------------
All the data continuously generated in your IT infrastructure contains a
definitive record of customers, application performance, security
threats, fraudulent activity and more. Splunk takes this data and makes
sense of it. Business sense. IT sense. Common sense.
http://p.sf.net/sfu/splunk-d2d-oct
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to