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

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

#1 fix interface and add util module

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