| 190 | } |
| 191 | |
| 192 | int acl_pthread_create(acl_pthread_t *thread, acl_pthread_attr_t *attr, |
| 193 | void *(*start_routine)(void *), void *arg) |
| 194 | { |
| 195 | const char *myname = "acl_pthread_create"; |
| 196 | acl_pthread_t *h_thread; |
| 197 | HANDLE handle; |
| 198 | unsigned long id, flag; |
| 199 | |
| 200 | if (thread == NULL) { |
| 201 | acl_msg_error("%s, %s(%d): input invalid", |
| 202 | __FILE__, myname, __LINE__); |
| 203 | acl_set_error(ACL_EINVAL); |
| 204 | return ACL_EINVAL; |
| 205 | } |
| 206 | acl_pthread_once(&__create_thread_control_once, acl_pthread_init_once); |
| 207 | memset(thread, 0, sizeof(acl_pthread_t)); |
| 208 | |
| 209 | h_thread = acl_default_calloc(__FILE__, __LINE__, |
| 210 | 1, sizeof(acl_pthread_t)); |
| 211 | if (h_thread == NULL) { |
| 212 | acl_msg_error("%s, %s(%d): calloc error(%s)", |
| 213 | __FILE__, myname, __LINE__, acl_last_serror()); |
| 214 | acl_set_error(ACL_ENOMEM); |
| 215 | return ACL_ENOMEM; |
| 216 | } |
| 217 | |
| 218 | if (attr != NULL) { |
| 219 | h_thread->detached = attr->detached; |
| 220 | } else { |
| 221 | h_thread->detached = 0; |
| 222 | } |
| 223 | h_thread->start_routine = start_routine; |
| 224 | h_thread->routine_arg = arg; |
| 225 | |
| 226 | if (__thread_inited) { |
| 227 | acl_pthread_mutex_lock(&__thread_lock); |
| 228 | flag = 0; |
| 229 | } else { |
| 230 | flag = CREATE_SUSPENDED; |
| 231 | } |
| 232 | |
| 233 | #define MIN_STACK (1024 * 4096) |
| 234 | |
| 235 | #ifdef ACL_WIN32_STDC |
| 236 | h_thread->handle = handle = (HANDLE) _beginthreadex(NULL, |
| 237 | attr && attr->stacksize > MIN_STACK ? |
| 238 | (unsigned int) attr->stacksize : MIN_STACK, |
| 239 | RunThreadWrap, |
| 240 | (void *) h_thread, |
| 241 | flag, |
| 242 | &id); |
| 243 | #else |
| 244 | h_thread->handle = handle = CreateThread(NULL, |
| 245 | attr && attr->stacksize > MIN_STACK ? |
| 246 | (unsigned int) attr->stacksize : MIN_STACK, |
| 247 | RunThreadWrap, |
| 248 | h_thread, |
| 249 | flag, |
searching dependent graphs…