Skip to content

Commit a3ca3d2

Browse files
author
zhengshuxin
committed
Optimize pthread wrapper for windows platform.
1 parent 41a96ed commit a3ca3d2

1 file changed

Lines changed: 87 additions & 56 deletions

File tree

lib_fiber/c/src/common/pthread_patch.c

Lines changed: 87 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -120,91 +120,104 @@ int pthread_once(pthread_once_t *once_control, void (*init_routine)(void))
120120

121121
///////////////////////////////////////////////////////////////////////////////
122122

123-
typedef struct {
124-
pthread_key_t tkey;
123+
#include "common/htable.h"
124+
125+
typedef struct FLS_KEY FLS_KEY;
126+
typedef struct TLS_KEY TLS_KEY;
127+
128+
struct FLS_KEY {
129+
HTABLE *keys;
130+
};
131+
132+
struct TLS_KEY {
133+
pthread_key_t key;
125134
void (*destructor)(void *);
126-
FIFO *keys;
127-
} TLS_KEY;
135+
FIFO *objs;
136+
};
128137

129-
static pthread_key_t __tls_key = TLS_OUT_OF_INDEXES;
130-
static pthread_key_t __fls_key = FLS_OUT_OF_INDEXES;
138+
static pthread_key_t __tls_key = TLS_OUT_OF_INDEXES;
139+
static pthread_key_t __fls_key = FLS_OUT_OF_INDEXES;
131140

132141
extern int acl_fiber_scheduled(void);
133142

134143
static void thread_exit(void *ctx)
135144
{
136-
TLS_KEY *tkey = (TLS_KEY *) ctx;
137-
void (*destructor)(void*);
138-
void *context;
139-
140-
if (tkey->keys) {
141-
TLS_KEY *iter;
142-
while ((iter = (TLS_KEY *) tkey->keys->pop_back(tkey->keys))) {
143-
if (iter->destructor) {
144-
destructor = iter->destructor;
145-
context = TlsGetValue(iter->tkey);
146-
mem_free(iter);
147-
148-
destructor(context);
149-
}
150-
}
151-
}
145+
FLS_KEY *fkey = (FLS_KEY *) ctx;
146+
void *ctx;
152147

153-
destructor = tkey->destructor;
154-
context = TlsGetValue(tkey->tkey);
148+
assert(fkey);
149+
assert(fkey->keys);
155150

156-
fifo_free(tkey->keys, mem_free);
157-
mem_free(tkey);
151+
ITER iter;
152+
foreach(iter, fkey->keys) {
153+
TLS_KEY *tkey = (TLS_KEY *) iter.data;
154+
assert(tkey);
155+
156+
if (tkey->destructor == NULL) {
157+
continue;
158+
}
158159

159-
if (destructor) {
160-
destructor(context);
160+
while ((ctx = tkey->objs->pop_front(tkey->objs))) {
161+
tkey->destructor(ctx);
162+
}
163+
164+
fifo_free(tkey->objs, NULL);
161165
}
166+
167+
htable_free(tkey->keys, mem_free);
168+
mem_free(tkey);
162169
}
163170

164171
/* 每个进程的唯一初始化函数 */
165172

166-
static void pthread_init_once(void)
173+
static void thread_once(void)
167174
{
168175
__tls_key = TlsAlloc();
169176
__fls_key = FlsAlloc(thread_exit);
170177
}
171178

179+
static void hash_key(pthread_key_t key, char *buf, size_t n)
180+
{
181+
assert(n > 10);
182+
_snprintf(buf, n, "%d", key);
183+
buf[n - 1] = '\0';
184+
}
185+
172186
int pthread_key_create(pthread_key_t *key_ptr, void (*destructor)(void*))
173187
{
174-
pthread_once(&__control_once, pthread_init_once);
188+
pthread_once(&__control_once, thread_once);
189+
190+
assert(__tls_key != TLS_OUT_OF_INDEXES);
191+
assert(__fls_key != FLS_OUT_OF_INDEXES);
175192

176193
if (*key_ptr <= 0 && *key_ptr != TLS_OUT_OF_INDEXES) {
177194
*key_ptr = TlsAlloc();
178195
assert(*key_ptr != TLS_OUT_OF_INDEXES);
179196
}
180197

181-
TLS_KEY *tkey = (TLS_KEY*) mem_calloc(sizeof(TLS_KEY), 1), *curr;
182-
tkey->tkey = *key_ptr;
198+
TLS_KEY *tkey = (TLS_KEY*) mem_calloc(sizeof(TLS_KEY), 1);
199+
tkey->key = *key_ptr;
183200
tkey->destructor = destructor;
201+
tkey->objs = fifo_new();
184202

185-
if (acl_fiber_scheduled()) {
186-
curr = (TLS_KEY *) TlsGetValue(__tls_key);
187-
if (curr && curr->keys) {
188-
curr->keys->push_back(curr->keys, tkey);
189-
} else {
190-
msg_error("%s(%d): no TLS_KEY for key=%d",
191-
__FUNCTION__, __LINE__, __tls_key);
192-
}
193-
} else if (__tls_key == TLS_OUT_OF_INDEXES) {
194-
msg_error("%s(%d): __tls_key is invalid", __FUNCTION__, __LINE__);
195-
} else if ((curr = TlsGetValue(__tls_key)) != NULL) {
196-
if (curr->keys) {
197-
curr->keys->push_back(curr->keys, tkey);
198-
} else {
199-
msg_error("%s(%d): keys is null", __FUNCTION__, __LINE__);
203+
char kbuf[32];
204+
hash_key(*key_ptr, kbuf, sizeof(kbuf));
205+
FLS_KEY *fkey;
206+
207+
if ((fkey = (FLS_KEY *) TlsGetValue(__tls_key)) == NULL) {
208+
if (acl_fiber_scheduled()) {
209+
msg_fatal("%s(%d): should be in thread mode",
210+
__FUNCTION__, __LINE__);
200211
}
201-
} else {
202-
assert(__fls_key != FLS_OUT_OF_INDEXES);
203-
tkey->keys = fifo_new();
204-
TlsSetValue(__tls_key, tkey);
205-
FlsSetValue(__fls_key, tkey);
212+
213+
fkey = (FLS_KEY *) mem_calloc(sizeof(FLS_KEY), 1);
214+
fkey->keys = htable_create(10);
215+
216+
TlsSetValue(__tls_key, fkey);
217+
FlsSetValue(__fls_key, fkey);
206218
}
207219

220+
htable_enter(fkey->keys, kbuf, tkey);
208221
return 0;
209222
}
210223

@@ -215,18 +228,36 @@ void *pthread_getspecific(pthread_key_t key)
215228

216229
int pthread_setspecific(pthread_key_t key, void *value)
217230
{
218-
if (key <= 0 || key == TLS_OUT_OF_INDEXES) {
231+
if (key < 0 || key == TLS_OUT_OF_INDEXES) {
219232
msg_error("%s(%d): key(%d) invalid", __FUNCTION__, __LINE__, key);
220233
return EINVAL;
221234
}
222235

223-
if (TlsSetValue(key, value)) {
224-
return 0;
225-
} else {
236+
FLS_KEY *fkey = (FLS_KEY *) TlsGetValue(__tls_key);
237+
if (fkey == NULL) {
238+
msg_error("%s(%d): no FLS_KEY for __tls_key=%d",
239+
__FUNCTION__, __LINE__, __fls_key);
240+
return EINVAL;
241+
}
242+
243+
char kbuf[32];
244+
hash_key(key, kbuf, sizeof(kbuf));
245+
246+
TLS_KEY *tkey = (TLS_KEY *) htable_find(fkey->keys, kbuf);
247+
if (tkey == NULL) {
248+
msg_error("%s(%d): no TLS_KEY for key=%d, __tls_key=%d",
249+
__FUNCTION__, __LINE__, key, __tls_key);
250+
return EINVAL;
251+
}
252+
253+
if (!TlsSetValue(key, value)) {
226254
msg_error("%s(%d): TlsSetValue(key=%d) error(%s)",
227255
__FUNCTION__, __LINE__, key, last_serror());
228256
return -1;
229257
}
258+
259+
tkey->objs->push_back(tkey->objs, value);
260+
return 0;
230261
}
231262

232263
#endif /* USE_FLS */

0 commit comments

Comments
 (0)