Index: trunk/psLib/src/sys/psThread.c
===================================================================
--- trunk/psLib/src/sys/psThread.c	(revision 19016)
+++ trunk/psLib/src/sys/psThread.c	(revision 19057)
@@ -26,4 +26,5 @@
 static psArray *pool = NULL;            // array of defined threads
 static psHash *tasks = NULL;            // List of defined tasks
+static psArray *tsd = NULL;             // Thread-specific data
 
 
@@ -165,5 +166,5 @@
 }
 
-bool psThreadTaskDelete(const char *type)
+bool psThreadTaskRemove(const char *type)
 {
     PS_ASSERT_STRING_NON_EMPTY(type, false);
@@ -316,5 +317,69 @@
     tasks = NULL;
 
+    psFree(tsd);
+    tsd = NULL;
+
     return true;
 }
 
+
+#if 0
+// This doesn't work like I thought it would: pthread_self can return anything.
+bool psThreadDataAdd(const char *name, psPtr ptr)
+{
+    PS_ASSERT_STRING_NON_EMPTY(name, false);
+    PS_ASSERT_PTR_NON_NULL(ptr, false);
+
+    pthread_key_t *key = psAlloc(sizeof(pthread_key_t)); // Key for data
+    pthread_key_create(key, psFree);
+
+    if (!tsd) {
+        tsd = psArrayAlloc(numThreads);
+    }
+
+    psHashAdd(
+
+    pthread_t tid = pthread_self();     // Thread identifier
+    int numThreads = psThreadPoolSize();// Number of threads
+    psAssert(tid < numThreads, "Thread identifier (%d) exceeds number of threads (%d)", (int)tid, numThreads);
+
+    if (!tsd) {
+        tsd = psArrayAlloc(numThreads);
+    }
+
+    psHash *hash = tsd->data[tid];      // Thread-specific hash of data
+    return psHashAdd(hash, name, ptr);
+}
+
+void *psThreadDataLookup(const char *name)
+{
+    PS_ASSERT_STRING_NON_EMPTY(name, NULL);
+
+    if (!tsd) {
+        return NULL;
+    }
+
+    pthread_t tid = pthread_self();     // Thread identifier
+    int numThreads = psThreadPoolSize();// Number of threads
+    psAssert(tid < numThreads, "Thread identifier (%d) exceeds number of threads (%d)", (int)tid, numThreads);
+
+    psHash *hash = tsd->data[tid];      // Thread-specific hash of data
+    return psHashLookup(hash, name);
+}
+
+bool psThreadDataRemove(const char *name)
+{
+    PS_ASSERT_STRING_NON_EMPTY(name, false);
+
+    if (!tsd) {
+        return false;
+    }
+
+    pthread_t tid = pthread_self();     // Thread identifier
+    int numThreads = psThreadPoolSize();// Number of threads
+    psAssert(tid < numThreads, "Thread identifier (%d) exceeds number of threads (%d)", (int)tid, numThreads);
+
+    psHash *hash = tsd->data[tid];      // Thread-specific hash of data
+    return psHashRemove(hash, name);
+}
+#endif
