/** * Copyright (C) 2008 Happy Fish / YuQing * * FastDFS may be copied only under the terms of the GNU General * Public License V3, which may be found in the FastDFS source kit. * Please visit the FastDFS Home Page http://www.fastken.com/ for more detail. **/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "fc_memory.h" #include "logger.h" #include "pthread_func.h" int init_pthread_lock(pthread_mutex_t *pthread_lock) { pthread_mutexattr_t mat; int result; if ((result=pthread_mutexattr_init(&mat)) != 0) { logError("file: "__FILE__", line: %d, " "call pthread_mutexattr_init fail, " "errno: %d, error info: %s", __LINE__, result, STRERROR(result)); return result; } if ((result=pthread_mutexattr_settype(&mat, PTHREAD_MUTEX_ERRORCHECK)) != 0) { logError("file: "__FILE__", line: %d, " "call pthread_mutexattr_settype fail, " "errno: %d, error info: %s", __LINE__, result, STRERROR(result)); return result; } if ((result=pthread_mutex_init(pthread_lock, &mat)) != 0) { logError("file: "__FILE__", line: %d, " "call pthread_mutex_init fail, " "errno: %d, error info: %s", __LINE__, result, STRERROR(result)); return result; } if ((result=pthread_mutexattr_destroy(&mat)) != 0) { logError("file: "__FILE__", line: %d, " "call thread_mutexattr_destroy fail, " "errno: %d, error info: %s", __LINE__, result, STRERROR(result)); return result; } return 0; } int init_pthread_attr(pthread_attr_t *pattr, const int stack_size) { size_t old_stack_size; size_t new_stack_size; int result; if ((result=pthread_attr_init(pattr)) != 0) { logError("file: "__FILE__", line: %d, " "call pthread_attr_init fail, " "errno: %d, error info: %s", __LINE__, result, STRERROR(result)); return result; } if ((result=pthread_attr_getstacksize(pattr, &old_stack_size)) != 0) { logError("file: "__FILE__", line: %d, " "call pthread_attr_getstacksize fail, " "errno: %d, error info: %s", __LINE__, result, STRERROR(result)); return result; } if (stack_size > 0) { if (old_stack_size != stack_size) { new_stack_size = stack_size; } else { new_stack_size = 0; } } else if (old_stack_size < 1 * 1024 * 1024) { new_stack_size = 1 * 1024 * 1024; } else { new_stack_size = 0; } if (new_stack_size > 0) { if ((result=pthread_attr_setstacksize(pattr, new_stack_size)) != 0) { logError("file: "__FILE__", line: %d, " "call pthread_attr_setstacksize to %d fail, " "errno: %d, error info: %s", __LINE__, (int)new_stack_size, result, STRERROR(result)); return result; } } if ((result=pthread_attr_setdetachstate(pattr, PTHREAD_CREATE_DETACHED)) != 0) { logError("file: "__FILE__", line: %d, " "call pthread_attr_setdetachstate fail, " "errno: %d, error info: %s", __LINE__, result, STRERROR(result)); return result; } return 0; } int create_work_threads(int *count, void *(*start_func)(void *), void **args, pthread_t *tids, const int stack_size) { #define FIXED_TID_COUNT 256 int result; pthread_attr_t thread_attr; void **current_arg; pthread_t fixed_tids[FIXED_TID_COUNT]; pthread_t *the_tids; pthread_t *ptid; pthread_t *ptid_end; if ((result=init_pthread_attr(&thread_attr, stack_size)) != 0) { return result; } if (tids != NULL) { the_tids = tids; } else { if (*count <= FIXED_TID_COUNT) { the_tids = fixed_tids; } else { int bytes; bytes = sizeof(pthread_t) * *count; the_tids = (pthread_t *)fc_malloc(bytes); if (the_tids == NULL) { pthread_attr_destroy(&thread_attr); return ENOMEM; } } } result = 0; ptid_end = the_tids + (*count); for (ptid=the_tids,current_arg=args; ptidlock)) != 0) { logError("file: "__FILE__", line: %d, " "init_pthread_lock fail, errno: %d, error info: %s", __LINE__, result, STRERROR(result)); return result; } if ((result=pthread_cond_init(&lcp->cond, NULL)) != 0) { logError("file: "__FILE__", line: %d, " "pthread_cond_init fail, " "errno: %d, error info: %s", __LINE__, result, STRERROR(result)); return result; } return 0; } void destroy_pthread_lock_cond_pair(pthread_lock_cond_pair_t *lcp) { pthread_cond_destroy(&lcp->cond); pthread_mutex_destroy(&lcp->lock); }