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

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

#1 rename context-implemented structures for readability

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