minzkn/thread
¹®¼ÀÇ ¼öÁ¤
¸ñÂ÷ ¶1.2. °³¿ä ¶
1.4.1. ÄÄÆÄÀÏ·¯ÀÇ ÃÖÀûÈ¿¡ µû¸¥ ºñÀǵµÀû °á°ú ¶ÃÖÀûÈ¿¡ ÀÇÇÑ Thread codeÀÇ ÀǵµµÇÁö ¾ÊÀº Çö»óÀÌ ¹ß»ýÇÒ¼öÀÖ½À´Ï´Ù.
ÀÏ´Ü ±×·¯ÇÑ ºÎºÐ¿¡ ´ëÇØ¼´Â ºÒ°¡ÇÇÇÏ°Ô Assembly·Î ±¸ÇöÇÏ¿© Àú´Â ÇØ°á¹æ¹ýÀ» ¸ð»öÇÏ¿´½À´Ï´Ù.
±×·¯³ª ÇÔ¼ö ÀÚüÀÇ FrameÀÇ ÃÖÀûȰ¡ ÀÌ·ïÁú¶§¸é ¹æ¹ýÀÌ ³ÇØÇÕ´Ï´Ù. ÀÌ¿¡ ´ëÇÑ °í¹ÎÀº ¹Ýµå½Ã ÇÊ¿äÇÕ´Ï´Ù.
ÀÌ¿¡ ´ëÇÑ ÃæºÐÇÑ °í·Á°¡ µÇÁö ¾ÊÀ¸¸é ¿ÀÁ÷ ÀÚ½ÅÀÇ PC¿¡¼¸¸ ½ÇÇàµÇ´Â ±âÇüÀûÀÎ Thread code°¡ µÉ°ÍÀÔ´Ï´Ù.
1.4.2. StackÀÇ °¡º¯Àû °ËÃâ ¶°¢ Thread´Â °íÀ¯ÀÇ StackÀ» ¼ÒÀ¯ÇÏ°Ô ¼³°èµË´Ï´Ù.
ÇÏÁö¸¸ ±×°ÍÀÌ °íÁ¤ÀûÀ̶ó¸é Áö¿ªº¯¼ö·Î Ä¿´Ù¶õ ¹è¿À» ¼±¾ðÇÏ¿© »ç¿ëÇϴµ¥ ºÎ´ãÀÌ ¾Æ´Ò¼ö ¾ø°Ú½À´Ï´Ù.
¶§¹®¿¡ StackÀ» °¡º¯ÀûÀ¸·Î ´Ã·ÁÁÙ¼ö ÀÖ´Â ¹æ¹ýÀÌ ¿ä±¸µË´Ï´Ù.
1.4.3. How to swap ¶À̰ÍÀº StackÀÌ SwapµÇ´Â°Í¿¡ ´ëÇÑ °í¹ÎÀÌ ÇÊ¿äÇϴٴµ¥ ÀÖ½À´Ï´Ù.
¹«Åδë°í ¸ðµÎ SwapÀÌ ¾Ë¾Æ¼ µÇ¸é ÁÁ°ÚÁö¸¸ Àß »ý°¢Çغ¸½Ã¸é ThreadÀÇ StackÀº °ú¿¬ SwapÀÌ ÇÊ¿äÇѰ¡¸¦ »ý°¢ÇغÁ¾ß ÇÕ´Ï´Ù. À߸øÇÏ¸é ¿ÀÈ÷·Á ºÎÀÛ¿ëÀÌ ¸¸¸¸Ä¡ ¾Ê´Ù´Âµ¥ ÁßÁ¡À» µÎ°í »ý°¢Çغ¼ ¹®Á¦ÀÓÀÌ ºÐ¸íÇÕ´Ï´Ù.
ÇÊÀÚÀÇ ¼Ò°ßÀº "StackÀº Heap°ú ´Ù¸£´Ù" ÀÔ´Ï´Ù. °áÄÚ SwapÀÌ µÇÁö ¾Ê°í ¾Æ¿¹ °í·ÁµÇÁö ¾Ê´Â°ÍÀÌ ÁÁ´Ù´Â »ý°¢ÀÔ´Ï´Ù.
¿©·¯ºÐµéÀÇ »ý°¢Àº ¾î¶°½ÅÁö¿ä? °¢ÀÚ ¸¸µé¾îº¸°í ¼º´ÉÀÇ Æò°¡¸¦ ÇÒ¼ö ÀÖ´Â ±âȸ°¡ ¾ðÁ¨°¡ ÁÖ¾îÁ³À¸¸é ÁÁ°Ú±º¿ä.
1.6. ¿¹Á¦ ¶¾Æ·¡ÀÇ ¿¹Á¦ ¼Ò½º´Â ½ÇÁ¦ ÇÊÀÚ°¡ ¸¸µé°í ÀÖ´Â ¿î¿µÃ¼Á¦ÀÇ ÀϺθ¦ ¹ßÃéÇѰÍÀÔ´Ï´Ù. ¹ßÃéÇÏ¸é¼ ¾à°£ÀÇ ºÒÇÊ¿äÇÑ ºÎºÐ°ú ³ª¸§´ë·ÎÀÇ ÁÖ¿ä ¼Ò½º´Â ¹ßÃéÇÏÁö ¾Ê¾Ò½À´Ï´Ù. Â÷ÈÄ¿¡´Â ¿ÏÀüÇÑ Thread¿¹Á¦¸¦ °ø°³Çϵµ·Ï ³ë·ÂÇϰڽÀ´Ï´Ù. ÇÏÁö¸¸ Çö½ÃÁ¡¿¡¼´Â ÀÌ ÀÌ»óÀÇ ¼Ò½º´Â °ø°³ÇÏÁö ¾ÊÀ» ¹æÄ§ÀÔ´Ï´Ù.
/*
Copyright (c) Information Equipment co.,LTD.
Code by JaeHyuk Cho <mailto:minzkn@infoeq.co.kr> KOREA
MZ Local Thread library v0.0.1b
- Simple is best !
*/
#if !defined(DEF_SOURCE_thread_c)
#define DEF_SOURCE_thread_c "thread.c"
typedef struct ts_STACK
{
void *Stack;
int StackSize, StackPointer;
}t_STACK;
typedef struct ts_THREAD_TASK
{
struct ts_THREAD_TASK *Next;
t_STACK *Stack;
unsigned int TaskID, ESP, Tick, Active;
void * (*Entry)(void *, void *);
void *Argument;
}t_THREAD_TASK;
typedef struct ts_THREAD
{
t_THREAD_TASK *Task;
t_THREAD_TASK *CurrentTask;
unsigned int TaskCount, MakeID;
}t_THREAD;
t_THREAD *ML_CreateTHREAD(void);
t_THREAD *ML_DestroyTHREAD(t_THREAD *s_THREAD);
t_THREAD *ML_AddTHREAD(t_THREAD *s_THREAD, void * (*s_ThreadFunction)(void *, void *), void *s_Argument, int s_StackSize);
t_THREAD *ML_RunTHREAD(t_THREAD *s_THREAD);
int ML_SleepTHREAD(t_THREAD *s_THREAD);
t_STACK *ML_CreateSTACK(int s_StackSize);
t_STACK *ML_DestroySTACK(t_STACK *s_STACK);
int ML_PushSTACK(t_STACK *s_STACK, int s_Value);
int ML_PopSTACK(t_STACK *s_STACK, int *s_Value);
int ML_SetSTACK(t_STACK *s_STACK, int s_StackPointer);
void __ML_ReturnTHREAD__(void);
static void *__ML_ManagerTHREAD__(void *s_ThreadHandle, void *s_Argument)
{
static t_THREAD *sg_THREAD = (t_THREAD *)0;
if(sg_THREAD != (t_THREAD *)s_ThreadHandle)sg_THREAD = (t_THREAD *)s_ThreadHandle;
ML_SleepTHREAD((t_THREAD *)s_ThreadHandle);
if(((t_THREAD *)s_ThreadHandle)->Task->Active == 0)return(s_Argument);
t_inline_asm(
"__ML_ReturnTHREAD__:\n\t"
"pushl $__ML_ReturnTHREAD__\n\t" /* Retry push return address */
);
t_inline_asm(
"\n\t"
: "=a"(((t_THREAD *)s_ThreadHandle)->CurrentTask->Argument)
);
((t_THREAD *)s_ThreadHandle)->CurrentTask->Active = 0;
ML_SleepTHREAD((t_THREAD *)s_ThreadHandle);
return(s_Argument);
}
t_THREAD *ML_CreateTHREAD(void)
{
t_THREAD *s_Return;
s_Return = (t_THREAD *)ML_Alloc(sizeof(t_THREAD));
if(s_Return)
{
s_Return->Task = s_Return->CurrentTask = (t_THREAD_TASK *)0;
s_Return->TaskCount = s_Return->MakeID = 0u;
s_Return = ML_AddTHREAD(s_Return, __ML_ManagerTHREAD__, (void *)0, (4 << 10));
}
return(s_Return);
}
t_THREAD *ML_DestroyTHREAD(t_THREAD *s_THREAD)
{
t_THREAD_TASK *s_THREAD_TASK;
if(s_THREAD)
{
while(s_THREAD->Task && s_THREAD->TaskCount--)
{
s_THREAD_TASK = s_THREAD->Task;
s_THREAD->Task = s_THREAD->Task->Next;
if(s_THREAD_TASK->Stack)(void)ML_DestroySTACK(s_THREAD_TASK->Stack);
(void)ML_Free(s_THREAD_TASK);
}
(void)ML_Free(s_THREAD);
s_THREAD = (t_THREAD *)0;
}
return(s_THREAD);
}
t_THREAD *ML_AddTHREAD(t_THREAD *s_THREAD, void * (*s_ThreadFunction)(void *, void *), void *s_Argument, int s_StackSize)
{
t_THREAD_TASK *s_THREAD_TASK;
if(s_THREAD == (t_THREAD *)0)s_THREAD = ML_CreateTHREAD();
if(s_THREAD)
{
if(s_THREAD->Task)
{
s_THREAD_TASK = s_THREAD->Task;
while(s_THREAD_TASK->Next && s_THREAD_TASK->Next != s_THREAD->Task)s_THREAD_TASK = s_THREAD_TASK->Next;
s_THREAD_TASK->Next = (t_THREAD_TASK *)ML_Alloc(sizeof(t_THREAD_TASK));
s_THREAD_TASK = s_THREAD_TASK->Next;
if(s_THREAD->CurrentTask == (t_THREAD_TASK *)0)s_THREAD->CurrentTask = s_THREAD->Task;
}
else s_THREAD->Task = s_THREAD->CurrentTask = s_THREAD_TASK = (t_THREAD_TASK *)ML_Alloc(sizeof(t_THREAD_TASK));
if(s_THREAD_TASK)
{
if(s_StackSize < ( 4 << 10 ))s_StackSize = ( 4 << 10 );
s_THREAD_TASK->Next = s_THREAD->Task;
s_THREAD_TASK->Stack = ML_CreateSTACK(s_StackSize);
s_THREAD_TASK->TaskID = (s_THREAD->MakeID++);
s_THREAD_TASK->Tick = 0;
s_THREAD_TASK->Active = 1;
s_THREAD_TASK->Entry = s_ThreadFunction;
s_THREAD_TASK->Argument = s_Argument;
s_THREAD_TASK->ESP = (unsigned int)s_THREAD_TASK->Stack->Stack + s_THREAD_TASK->Stack->StackPointer;
s_THREAD->TaskCount++;
}
}
return(s_THREAD);
}
t_THREAD *ML_RunTHREAD(t_THREAD *s_THREAD)
{
struct { unsigned int eax, ebx, ecx, edx, esi, edi, ebp, esp, flags; }s_Register;
t_THREAD_TASK *s_THREAD_TASK;
unsigned int s_RegisterAddress, s_TempEBX;
if(s_THREAD)
{
if(s_THREAD->Task)
{
s_RegisterAddress = (unsigned int)(&s_Register);
t_inline_asm(
"\n\t"
"movl %%ebx, %1\n\t"
"movl %0, %%ebx\n\t"
"movl %%eax, 0(%%ebx)\n\t"
"movl %1, %%eax\n\t"
"movl %%eax, 4(%%ebx)\n\t"
"movl 0(%%ebx), %%eax\n\t"
"movl %%ecx, 8(%%ebx)\n\t"
"movl %%edx, 12(%%ebx)\n\t"
"movl %%esi, 16(%%ebx)\n\t"
"movl %%edi, 20(%%ebx)\n\t"
"movl %%ebp, 24(%%ebx)\n\t"
"movl %%esp, 28(%%ebx)\n\t"
"pushfl\n\t"
"popl 32(%%ebx)\n\t"
"movl 4(%%ebx), %%ebx\n\t"
"\n\t"
:
: "m"(s_RegisterAddress), "m"(s_TempEBX)
);
s_THREAD_TASK = s_THREAD->Task;
ML_PushSTACK(s_THREAD_TASK->Stack, s_Register.flags);
ML_PushSTACK(s_THREAD_TASK->Stack, s_Register.esp);
ML_PushSTACK(s_THREAD_TASK->Stack, s_Register.ebp);
ML_PushSTACK(s_THREAD_TASK->Stack, s_Register.edi);
ML_PushSTACK(s_THREAD_TASK->Stack, s_Register.esi);
ML_PushSTACK(s_THREAD_TASK->Stack, s_Register.edx);
ML_PushSTACK(s_THREAD_TASK->Stack, s_Register.ecx);
ML_PushSTACK(s_THREAD_TASK->Stack, s_Register.ebx);
ML_PushSTACK(s_THREAD_TASK->Stack, (int)s_THREAD_TASK->Argument);
ML_PushSTACK(s_THREAD_TASK->Stack, (int)s_THREAD);
s_THREAD_TASK->ESP = (unsigned int)s_THREAD_TASK->Stack->Stack + s_THREAD_TASK->Stack->StackPointer;
s_THREAD_TASK = s_THREAD_TASK->Next;
while(s_THREAD_TASK && s_THREAD_TASK != s_THREAD->Task)
{
ML_PushSTACK(s_THREAD_TASK->Stack, (int)s_THREAD_TASK->Argument);
ML_PushSTACK(s_THREAD_TASK->Stack, (int)s_THREAD);
ML_PushSTACK(s_THREAD_TASK->Stack, (int)__ML_ReturnTHREAD__);
ML_PushSTACK(s_THREAD_TASK->Stack, (int)s_THREAD_TASK->Argument);
ML_PushSTACK(s_THREAD_TASK->Stack, (int)s_THREAD);
ML_PushSTACK(s_THREAD_TASK->Stack, (int)__ML_ReturnTHREAD__);
ML_PushSTACK(s_THREAD_TASK->Stack, (int)s_THREAD_TASK->Entry); /* First swich entry */
ML_PushSTACK(s_THREAD_TASK->Stack, s_Register.flags);
ML_PushSTACK(s_THREAD_TASK->Stack, s_Register.ebp);
ML_PushSTACK(s_THREAD_TASK->Stack, s_Register.edi);
ML_PushSTACK(s_THREAD_TASK->Stack, s_Register.esi);
ML_PushSTACK(s_THREAD_TASK->Stack, s_Register.edx);
ML_PushSTACK(s_THREAD_TASK->Stack, s_Register.ecx);
ML_PushSTACK(s_THREAD_TASK->Stack, s_Register.ebx);
s_THREAD_TASK->ESP = (unsigned int)s_THREAD_TASK->Stack->Stack + s_THREAD_TASK->Stack->StackPointer;
s_THREAD_TASK = s_THREAD_TASK->Next;
}
t_inline_asm(
"\n\t"
"movl %1, %%ecx\n\t"
"movl %0, %%ebp\n\t"
"movl %%ebp, %%esp\n\t"
"call *%%ecx\n\t"
"addl $4 + 4, %%esp\n\t"
"popl %%ebx\n\t"
"popl %%ecx\n\t"
"popl %%edx\n\t"
"popl %%esi\n\t"
"popl %%edi\n\t"
"popl %%ebp\n\t"
"popl %%eax\n\t" /* Change stack (x86) */
"popfl\n\t"
"movl %%eax, %%esp\n\t"
"\n\t"
:
: "m"(s_THREAD->Task->ESP), "m"(s_THREAD->Task->Entry)
);
}
}
return(s_THREAD);
}
int ML_SleepTHREAD(t_THREAD *s_THREAD)
{
s_THREAD->CurrentTask->Tick++;
t_inline_asm(
"\n\t"
"movl %%esp, %%eax\n\t"
"subl $28, %%eax\n\t"
"\n\t"
: "=a"(s_THREAD->CurrentTask->ESP)
);
do
{
s_THREAD->CurrentTask = s_THREAD->CurrentTask->Next;
if(s_THREAD->CurrentTask == s_THREAD->Task)
{
if(s_THREAD->Task->Active == 1)
{
s_THREAD->CurrentTask->Active = 0;
continue;
}
else break;
}
}while(s_THREAD->CurrentTask->Active == 0);
if(s_THREAD->CurrentTask != s_THREAD->Task)s_THREAD->Task->Active = 1;
t_inline_asm(
"\n\t"
"pushfl\n\t"
"pushl %%ebp\n\t"
"pushl %%edi\n\t"
"pushl %%esi\n\t"
"pushl %%edx\n\t"
"pushl %%ecx\n\t"
"pushl %%ebx\n\t"
"movl %0, %%esp\n\t"
"popl %%ebx\n\t"
"popl %%ecx\n\t"
"popl %%edx\n\t"
"popl %%esi\n\t"
"popl %%edi\n\t"
"popl %%ebp\n\t"
"popfl\n\t"
"\n\t"
:
: "a"(s_THREAD->CurrentTask->ESP)
);
return(1);
}
t_STACK *ML_CreateSTACK(int s_StackSize)
{
t_STACK *s_Return;
if(s_StackSize < (4 << 10))s_StackSize = (4 << 10);
s_Return = (t_STACK *)ML_Alloc(sizeof(t_STACK));
if(s_Return)
{
s_Return->Stack = (void *)ML_Alloc(s_StackSize);
s_Return->StackSize = s_Return->StackPointer = s_StackSize;
}
return(s_Return);
}
t_STACK *ML_DestroySTACK(t_STACK *s_STACK)
{
if(s_STACK)
{
if(s_STACK->Stack && s_STACK->StackSize > 0)(void)ML_Free(s_STACK->Stack);
(void)ML_Free(s_STACK);
s_STACK = (t_STACK *)0;
}
return(s_STACK);
}
int ML_PushSTACK(t_STACK *s_STACK, int s_Value)
{
if(s_STACK)
{
if(s_STACK->Stack && s_STACK->StackSize >= sizeof(s_Value) && s_STACK->StackPointer >= sizeof(s_Value))
{
s_STACK->StackPointer -= sizeof(s_Value);
ML_PokeDoubleWord(s_STACK->Stack, s_STACK->StackPointer, s_Value);
return(s_STACK->StackPointer);
}
}
return(0);
}
int ML_PopSTACK(t_STACK *s_STACK, int *s_Value)
{
int s_Return = (-1);
if(s_STACK)
{
if(s_STACK->Stack && s_STACK->StackSize >= sizeof(int) && s_STACK->StackPointer <= (s_STACK->StackSize - sizeof(int)))
{
s_Return = ML_PeekDoubleWord(s_STACK->Stack, s_STACK->StackPointer);
s_STACK->StackPointer += sizeof(int);
}
}
if(s_Value)*(s_Value) = s_Return;
return(s_Return);
}
int ML_SetSTACK(t_STACK *s_STACK, int s_StackPointer)
{
if(s_STACK)
{
s_STACK->StackPointer = s_StackPointer;
return(s_STACK->StackPointer);
}
return(0);
}
#endif
/* End of source */
1.8. ¹®¼¸¦ ¸¶Ä¡¸é¼ ¶ÀÌ ¹®¼¿¡¼ Ʋ¸° ºÎºÐÀ̳ª °íÃÄ¾ß ÇҺκÐÀÌ ÀÖÀ¸¸é ²À ¾Ë·ÁÁֽʽÿä. À̱ÛÀÇ ÃÖ±Ù ¹®¼´Â http://doc.kldp.org ¿¡¼ ¸¸³ªº¸½Ç¼ö ÀÖ½À´Ï´Ù.
ÇÊÀÚÀÇ È¨ÆäÀÌÁö:
![]() |
You will meet an important person who will help you advance professionally. |