source: libcf/trunk/src/cf_thread.c@ 126

Last change on this file since 126 was 126, checked in by cheese, 11 years ago

#1 separate header/source files for thread and mutex

File size: 4.5 KB
RevLine 
[4]1/**
[119]2 * \file cf_thread.c
3 * \author myusgun <myusgun@gmail.com>
[117]4 *
[126]5 * \brief 멀티 스레드 구현
[4]6 */
7#include "cf_thread.h"
[40]8#include "cf_error.h"
[4]9
10#include <stdlib.h>
11
[50]12#if defined(_WIN32) || defined(_WIN64)
[4]13# include <windows.h>
14# include <process.h>
15# define THREAD_TYPE HANDLE
16# define MUTEX_TYPE HANDLE
[57]17# define THREAD_RETURN unsigned long /**< 스레드 워커 함수 반환 형 */
18# define THREAD_CALL __stdcall
[50]19#else // #if defined(_WIN32) || defined(_WIN64)
[4]20# include <pthread.h>
21# define THREAD_TYPE pthread_t
22# define MUTEX_TYPE pthread_mutex_t
[57]23# define THREAD_RETURN void * /**< 스레드 워커 함수 반환 형 */
24# define THREAD_CALL
[50]25#endif // #if defined(_WIN32) || defined(_WIN64)
[4]26
[122]27#define ASSERT_THREAD_CTX(__ctx) \
28 if (__ctx == NULL) \
29 return CF_ERROR_THREAD_INVALID_CTX
[4]30
[65]31typedef THREAD_RETURN (THREAD_CALL * THREAD_WORKER) (void *);
[60]32
[122]33typedef struct __cf_thread_ctx__
34{
35 THREAD_TYPE tid;
36 THREAD_WORKER callback;
37 void * arg;
38} CF_THREAD_CTX;
39
[23]40static int
[122]41CF_Thread_Local_Close (THREAD_TYPE tid)
[4]42{
[50]43#if defined(_WIN32) || defined(_WIN64)
[123]44 if (tid == NULL)
45 return CF_ERROR_THREAD_INVALID_ARGS;
46
[122]47 CloseHandle (tid);
48#endif
49
50 return CF_OK;
51}
52
[35]53/**
[122]54 * 스레드 컨텍스트를 생성
[35]55 *
[119]56 * \return 성공 시, CF_OK; 실패 시, 오류 코드
[35]57 *
[122]58 * \param ctx 스레드 컨텍스트 주소
[119]59 * \param callback 스레드 워커 함수 이름
60 * \param arg 스레드 함수로 전달할 인자
[122]61 */
62int
63CF_Thread_CreateCtx (CF_Thread_Ctx * ctx,
64 CF_Thread_Function callback,
65 void * arg)
66{
67 CF_THREAD_CTX * context = NULL;
68
69 context = (CF_THREAD_CTX *) calloc (sizeof (CF_THREAD_CTX), 1);
70 if (context == NULL)
71 return CF_ERROR_THREAD_CREATE_CTX;
72
73 context->callback = (THREAD_WORKER) callback;
74 context->arg = arg;
75
76 *ctx = (CF_Thread_Ctx) context;
77
78 return CF_OK;
79}
80
81/**
82 * 스레드를 실행
[80]83 *
[122]84 * \return 성공 시, CF_OK; 실패 시, 오류 코드
85 *
86 * \param ctx 스레드 컨텍스트
87 *
[119]88 * \remarks
[122]89 * pthread에서 지원되는 스케줄링 정책은 SCHED_OTHER, SCHED_FIFO, SCHED_RR 등이 존재 <br />
[80]90 * 일반적으로 설정되는 스케줄링 정책의 기본값은 SCHED_OTHER이며, 솔라리스 환경에서 SCHED_OTHER는 TS(timesharing) 방식으로 명시되어 있음 <br />
91 * 그러나 개발 단계에서 테스트된 동작은 SCHED_FIFO와 동일하였으며, 때문에 솔라리스 환경에서는 스케줄링 정책을 SCHED_RR로 명시하도록 함 <br />
92 * <br />
93 * 참고 url <br />
94 * - http://kldp.org/node/18841 , "SCHED_OTHER, SCHED_FIFO, SCHED_RR에 대해..." <br />
95 * - http://blog.naver.com/popjunior/80021646476 , "AIX, CPU 모니터링과 튜닝" <br />
[35]96 */
[4]97int
[122]98CF_Thread_Start (CF_Thread_Ctx ctx)
[4]99{
100 int result = 0;
101
[122]102 CF_THREAD_CTX * context = (CF_THREAD_CTX *) ctx;
[57]103
[122]104 ASSERT_THREAD_CTX (ctx);
105
[50]106#if defined(_WIN32) || defined(_WIN64)
[122]107 context->tid = CreateThread (NULL, 0, context->callback, context->arg, 0, NULL);
108 if (context->tid == NULL)
109 return CF_ERROR_THREAD_START;
[81]110#else
[57]111
[81]112 pthread_attr_t * attr = NULL;
[80]113# if defined(_SOLARIS)
[81]114 pthread_attr_t solarisAttr;
115 struct sched_param sched;
[4]116
[81]117 attr = &solarisAttr;
[80]118
[81]119 result = pthread_attr_init (attr);
120 if (result)
121 return CF_ERROR_THREAD_INIT_ATTR;
[80]122
[81]123 result = pthread_attr_setinheritsched (attr, PTHREAD_EXPLICIT_SCHED);
124 if (result)
125 return CF_ERROR_THREAD_SET_INHERIT_SCHED;
[80]126
[81]127 result = pthread_attr_setschedpolicy (attr, SCHED_RR);
128 if (result)
129 return CF_ERROR_THREAD_SET_SCHED_POLICY;
130
131 sched.sched_priority = 1;
132 result = pthread_attr_setschedparam (attr, &sched);
133 if (result)
134 return CF_ERROR_THREAD_SET_SCHED_PARAM;
[80]135# endif // # if defined(_SOLARIS)
136
[122]137 result = pthread_create (&context->tid, attr, context->callback, context->arg);
[84]138 if (result)
[122]139 return CF_ERROR_THREAD_START;
[81]140#endif
[80]141 return result;
[4]142}
143
[35]144/**
[122]145 * 스레드 컨텍스트를 해제
[35]146 *
[119]147 * \return 성공 시, CF_OK; 실패 시, 오류 코드
[35]148 *
[122]149 * \param ctx 스레드 컨텍스트
[35]150 *
[122]151 * \remarks 스레드 컨텍스트를 해제하는 것이며 워커 스레드가 종료되지 않음
[35]152 */
[4]153int
[122]154CF_Thread_DestroyCtx (CF_Thread_Ctx ctx)
[4]155{
[122]156 CF_THREAD_CTX * context = (CF_THREAD_CTX *) ctx;
[4]157
[122]158 ASSERT_THREAD_CTX (ctx);
159
160 CF_Thread_Local_Close (context->tid);
161 free (context);
162
163 return CF_OK;
[4]164}
165
[35]166/**
167 * 스레드가 종료될 때 까지 대기
168 *
[119]169 * \return CF_OK 반환
[35]170 *
[122]171 * \param ctx 스레드 컨텍스트
[35]172 */
[4]173int
[122]174CF_Thread_Join (CF_Thread_Ctx ctx)
[4]175{
[122]176 CF_THREAD_CTX * context = (CF_THREAD_CTX *) ctx;
[4]177
[122]178 char status[16] = {0x00,};
179
180 ASSERT_THREAD_CTX (ctx);
181
[50]182#if defined(_WIN32) || defined(_WIN64)
[122]183 WaitForSingleObject (context->tid, INFINITE);
[4]184#else
[122]185 pthread_join (context->tid, (void **)status);
[4]186#endif
187
188 return CF_OK;
189}
Note: See TracBrowser for help on using the repository browser.