mWin에 멀티미디어를 위한 Preemptive 멀티쓰래딩 시스템 - PowerPoint by leader6

VIEWS: 2 PAGES: 52

									 mWin에 멀티미디어를 위한
Preemptive 멀티쓰래딩 시스템

       2002.8.22
        홍차연
                          Contents
•   Abstract
•   Why preemptive multitasking under mWin?
•   Review – mWin
•   Multitasking under mWin
•   Design requirement
•   Design
     – Threads design
     – New clipping system design
     – Win32 APIs design
•   Clip rectangles localization
•   Control winthread
•   Conclusion
•   Future work
               Abstract
• 현재 mWin은 멀티태스킹을 Nonpreemptive한 방식으
  로 지원한다. 즉, 한 윈도우의 event(message) 처리가
  끝나야만 다른 윈도우가 event(message)를 할 수 있
  다. 이는 Real-time 주기 처리를 요하는 Multimedia를
  적용하기에는 부적합하다. 따라서 Preemptive 멀티태
  스킹 시스템을 mWin에 design하여 Multimedia data를
  처리할 수 있게 하되, 되도록 이면 Win32 API와 호환
  되게 design한다
   Why preemptive multitasking
  under mWin? (motivation) (1/2)
• Multimedia는 실시간 주기성을 갖는다
  – MPEG (30 frame/sec)
  – MP3 (44 Hz sampling rate)            Video – E.T.   X
  – Game (24 frame/sec)
                           Game – Doom     X
   Why preemptive multitasking
  under mWin? (motivation) (2/2)
  – 기존의 실시간 주기 Data 처리 방법
    • 주기적으로 발생하는 WM_TIMER 메시지를 이용하여 처리
  – 한계
    • WM_TIMER는 다른 메시지가 처리 중일 경우 정확한 주기성을
      보장 받을 수 없다
• Nonpreemptive로 멀티미디어 데이터를 처리할 때 많
  은 시간이 걸리면 다른 윈도우는 메시지를 받아드릴
  수 없다
               Review – mWin (1/4)
• mWin의 구조
  – API 계층
  – Device independent graphic engine 계층
  – Device drivers 계층



            Applications

                                         APIs
     Libs      Microwindows

                                  Device independent
               Velos                graphic engine

                                        Drivers
             Hardware
                       Review – mWin (2/4)
• Message 처리

                                                                                           Message handler
          Keyboard                                        Main loop (WinMain())
                                                               (6) Dispatch the message
                                                                             Message
                       (1) event
                                                            Dispatch()                       swhtch(message){
 Timer
           (1) event                                                 (9) sleep    (8) return case WM_XXXX:
                                        (2) Wake up!                                                …
                          Semaphore                         GetMessage()

           (1) event                     Event handlers     (3) Invoke                            (7) Message handle
                                                        An event handler   (5) Get the message
                   (1) event       (4) Transform the event to a message
  Mouse

                                                            Message Message
                  Touch
                  screen

                                       Device independent
         Device drivers                                                                APIs
                                         graphic engines
                           Review – mWin (3/4)
      • Clipping 영역 계산
          – Clip rectangles
                • 한 윈도우에서 실제로 그림이 그려지는 부분
                • 다른 윈도우를 그릴 때, update
                • 같은 윈도우 내에서 그림을 그릴 경우 cache를 이용함
          – 그리기 API 함수 내부에서 Clipping 영역 계산 루틴
            (MwSetClipWindow())이 호출된다                                          Test2


                                                             Clipping test
                           call
  APIs    Graphic APIs            MwSetClipWindow()           Clip rectangle
                  call                       copy
                                                      Test
                            refer          Clip                   Clip rectangle
D.I.G.E   Graphic engine                rectangles
                                          Cache
                  call                                             Clip rectangle

Drivers   Screen driver
                                                                         그림: Clipping 계산
                          Review – mWin (4/4)
  • 그림 그리기

                                                           Test2
        그리기 API 호출
                                           Clipping test

       Clipping 영역 계산
                                    Test

Device independent graphic engine
              호출



       Screen driver 호출
   Multitasking under mWin (1/2)
• 현재 mWin의 multitasking
   – Nonpreemtive multitasking            WndProc2()


                                                        WndProc3()
                          WndProc1()




              WinMain()    Message Q                   GetMessage() loop in WinMain()



                                                                     WndProc4()

                                       mWin


                                          Preemtive
                                          scheduler
                                       Velos
   Multitasking under mWin (2/2)
• Multithreading을 적용하였을 때의 mWin의 multitasking
   – Preemptive multitasking              WndProc2()


                                                        WndProc3()
                          WndProc1()




              WinMain()    Message Q                   GetMessage() loop in WinMain()



                                                                     WndProc4()

                                       mWin


                                          Preemtive
                                          scheduler
                                       Velos
         Design requirement
• 될 수 있는 한 mWin의 구조가 많이 바뀌어서는 안 된
  다
  – mWin의 3계층 구조를 벗어나서는 안된다
• Multithreading 관련 Win32 API와 호환을 이루어야 한
  다
  – 단, 실시간 주기 쓰레드 관련 API는 새로 추가할 수 있다
• Critical section의 길이를 최소화한다
• Win32 프로그램 구조를 벗어나서는 안된다
  – 윈도우 생성 – WinMain()
  – 윈도우 메시지 처리 – WndProc()
          Threads design (1/3)
• 디자인할 Thread의 종류
  – Message-queue thread
     • Message queue를 가지고 있는 thread
     • GetMessage() 루프를 돌면서 메시지를 해당 윈도우 메시지 처
       리 프로시져로 보낸다
  – Non-message-queue thread
     • Message queue를 가지고 있지 않는 thread
     • 메시지 처리 프로시져가 처리하기에 시간이 걸리는 일을 처리한
       다




            Non-message-queue thread   Message-queue thread
         Threads design (2/3)
• Non-message-queue thread
  – 윈도우 메시지 프로시져 Callback 함수가 메시지를 처리할 경
    우 많은 시간이 걸려서 다른 윈도우가 많은 영향을 받을 때,
    background로 이 일을 처리하는 thread
  – Velos의 pthread또는 실시간 주기 쓰레드에 매핑
  – 한 프로그램에 1개 이상이 존재할 수 있다
• Message-queue thread
  – 메시지 큐로부터 메시지를 얻고 이를 윈도우 메시지 프로시져
    로 배분하는 일을 반복하는 쓰레드
  – Velos의 pthread에 매핑
  – 1개만 있으면 됨
     • WinMain()이 한 개일 수 밖에 없으므로
                Multi thread design models



                                 sem



                                                                                 sem




Single thread model      Multi thread model       Multi thread model       Multi thread model
                      Using global clip rects   Using local clip rects   Using local clip rects
                                                          (1)                      (2)
                                                (mWin uses this model)   (PEG uses this model)
       Multi thread model 1 (1/2)
• Thread를 사용할 경우 문제점
  – 하나의 윈도우 영역에 다른 윈도우의 컨텐츠가 그려질 수 있
    다 (M.T. safe 하지 않다)
  – 수시로 그림을 그릴 때마다 clip rectangle을 업데이트 해야하
    는 오버해드가 있다
  – 쓰래드 제어가 불가능 하다
• 장점
  – 구현이 매우 쉽다
              Multi thread model 1 (2/2)
     • 불가능한 Thread 제어


Game – Doom     X       Video – E.T.   X   Game – Doom     X       Video – E.T.   X




              Desired view                               Clipping problem
         Multi thread model 2
• Thread를 사용할 경우 문제점
  – M.T safe하나 수시로 그림을 그릴 때마다 clip rectangle을 업
    데이트 해야하는 오버해드가 있다
  – 한 윈도우가 한 frame을 다 그릴 동안 다른 윈도우는 그리지
    못한다
• 장점
  – 구현이 쉽다
  – 쓰래드 제어가 쉽다                           sem
       Multi thread model 3 (1/2)
• Thread를 사용할 경우 문제점
  – 윈도우의 위치가 바뀔 때마다 연관되지 않은 윈도우의 clip
    rectangle을 갱신해주어야 하는 오버해드가 있다
  – 쓰래드 제어가 힘들다
• 장점
  – 한윈도우가 그림을 그리고 있는 동안 동시에 다른 윈도우가
    그림을 그릴 수 있다
  – 응답속도가 빠르다
                   Multi thread model 3 (2/2)
      • Clip rectangles update




                  Clip rectangles                                            Clip rectangles
                                    Clip rectangles
Clip rectangles
                                                           Clip rectangles
                                                                               update

                                         Clip rectangles     update                Clip rectangles


                                                                                      update
                                                           Clip rectangles


                                                             update
        Multi thread model 4
• Thread를 사용할 경우 문제점
  – 다른 윈도우가 화면에 그림을 그릴 동안 다른 윈도우는 그림
    을 그릴 수 없다
  – 윈도우가 움직일 경우 다른 윈도우는 그림을 그릴 수 없다
  – Nonpreemptive하다
• 장점
  – Thread를 쉽게 제어할 수 있다



                           sem
        Win32 APIs design (1/4)
• Win32 thread prototype
   – 이름은 다르게 할 수 있으나, 아래의 syntax를 따라야 한다


      DWORD WINAPI ThreadProc(PVOID pParam);
        Win32 APIs design (2/4)
• Thread creation/destruction관련 APIs


    Win32 API        설명         관련 Velos API

  CreateThread()   Thread 생성   pthread_create()
                                thread_create()
  _beginthread()   Thread 생성   pthread_create()
                                thread_create()
   -endthread()    Thread 종료    pthread_exit()
               Win32 APIs design (3/4)
  • Thread synchronization관련 APIs

       Win32 API                   설명                관련 Velos API

InitializeCriticalSection()   mutex를 초기화한다        pthread_mutex_init()

 EnterCriticalSection()       mutex를 lock한다      pthread_mutex_lock()

 LeaveCriticalSection()       mutex를 unlock한다   pthread_mutex_unlock()

 DeleteCriticalSection()       mutex를 지운다       pthread_mutex_destroy()
             Win32 APIs design (4/4)
   • 기타

     Win32 API                설명           관련 Velos API

GetCurrentThreadId()   현재 수행 중인 Thread 자   pthread_self()
                        신의 ID를 얻어온다
Clip rectangles localization
              Window context (1/3)
• Clip rects와 single thread mode에서 사용되었던 전역
  변수의 묶음
/* window*/
struct hwnd {
    RECT            winrect;     /*   window rect in screen coords*/
    RECT            clirect;     /*   client rect in screen coords*/
    RECT            restorerc;   /*   restore rect from maximized*/
    DWORD           style;       /*   window style*/
    DWORD           exstyle;     /*   window extended style*/
    PWNDCLASS       pClass;      /*   window class*/
    struct hwnd     *parent;     /*   z-order parent window */
    struct hwnd     *owner;      /*   owner window*/
    struct hwnd     *children;   /*   first child window */
    struct hwnd     *siblings;   /*   next sibling window */
    struct hwnd     *next;       /*   next window in complete list */
    struct hcursor  *cursor;     /*   cursor for this window */
...
#ifdef MWIN_MULTITHREAD
    WINCTXT         winctxt;     /* local cliparea for multithreading */
    WINTHREAD       thlist;      /* window thread */
#endif /* MWIN_MULTITHREAD */
};
               Window context (2/3)
• Window context struct
typedef struct window_context {
   MWCOORD clipminx;       /* minimum x value of cache rectangle */
   MWCOORD clipminy;       /* minimum y value of cache rectangle */
   MWCOORD clipmaxx;       /* maximum x value of cache rectangle */
   MWCOORD clipmaxy;       /* maximum y value of cache rectangle */
   MWBOOL clipresult;      /* whether clip rectangle is plottable */
   int clipcount;          /* number of clip rectangles */
   MWCLIPRECT *cliprects; /* clip rectanbles */
   MWCLIPRECT wcliprects[MAX_CLIPRECTS]; /* window clip rectanbles */
   MWCLIPRECT ccliprects[MAX_CLIPRECTS]; /* client clip rectanbles */
   MWPIXELVAL gr_foreground;     /* current foreground color */
   MWPIXELVAL gr_background;     /* current background color */
   MWBOOL gr_usebg;              /* TRUE if background drawn in pixmap */
   int gr_mode;                  /* drawing mode */
   MWSCREENINFO gr_sinfo;        /* screen info for local routines */
   MWPALENTRY   gr_palette[256]; /* current pallete */
   int gr_firstuserpalentry;     /* first user-changable pallette entry */
   int gr_nextpalentry;          /* next available palette entry */
   int gr_portraitmode;          /* =1 for portrait mode */
   int updatecrflag;          /* if updating clip rect is needed, it is setted */
} WINCTXT, *PWINCTXT;
        Window context (3/3)
• 언제 갱신하는가?
 –   윈도우가 생성될 때
 –   윈도우의 위치가 바뀔 때
 –   윈도우의 모양이 바뀔 때
 –   윈도우의 순서가 바뀔 때
 –   윈도우가 파괴될 때

                               Update            Update



               Moving window




                                        Update
Control winthreads
           Winthread spec.
• 우선순위는 mWin thread보다 높거나 같아야 한다
• 스케쥴링 정책이 RR이어야 한다
• Velos 뿐만 아니라 다른 OS에도 쉽게 포팅하기 위해
  서 표준 pthread API로만 만들어야 한다
• 실시간 thread 도 생성할 수 있다
• Win32 API syntex 및 functionality가 호환되어야 한다
• 기존의 thread가 아닌 윈도우와 동시에 실행되어야 한
  다
                      Winthread states



                                                 Sates (TSTATE_*)           설명
            TSTATE_NORMAL_WORKING
                                                 NORMAL_WORKING      API를 제외한 루틴를 실행할 때

                                                        PAINTING         API를 실행할 때

                                               WAITING_MOVING_DONE      Window가 움직일 때




TSTATE_PAINTING            TSTATE_WAITING_MOVING_DONE
                        Winthread struct

typedef struct _WINTHREAD{
   struct _WINTHREAD *next;   /*   Next thread */
   struct _WINTHREAD *prev;   /*   Previous thread */
   struct _WINTHREAD *ncow;   /*   Next coworker thread who has same owner (window) */
   struct _WINTHREAD *pcow;   /*   Previous coworker thread who has same owner (window) */
   HWND hwnd;                 /*   thread owner window */
   pthread_t th;              /*   thread identificaion */
   sem_t sem;                 /*   Semaphore for api: it is waited in api context */
   volatile int state;        /*   thread state: TSTATE_(state) */
} WINTHREAD, *PWINTHREAD;
                   Winthread creation (1/5)
• Winthread management linked lists



      thlist         ncow     ncow     ncow      thlist   ncow
     HWND            pcow     pcow     pcow     HWND      pcow


                     State    State    State              State




                      next     next     next     next
                      prev     prev     prev     prev
  thread_list

 Global variable      State    State    State    State
    Winthread creation (2/5)
• 순서도
                 Start



                Mutex lock


            Winthread node 생성


            Winthread node 초기화


           Winthread lists에 추가


               Winthread 생성


               Mutex unlock


                   End
                  Winthread creation (3/5)
     • CreateThread()
HANDLE WINAPI
CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,
                    DWORD dwStackSize,
                    LPTHREAD_START_ROUTINE lpStartAddress,
                    LPVOID lpParameter,
                    DWORD dwCreationFlags,
                    LPWORD lpThreadID)
{
   WINTHREAD *pth;
   WINTHREAD *i;

   pthread_attr_t attr;

   /* Mutex locking because thread lists should be protected */    Thread list를 보호하기 위한
   pthread_mutex_lock(&mutex);                                            mutex lock

   /* Memory allocation for WINTHREAD ELEMENT */                      Thread list에 추가할
   pth = (WINTHREAD *)malloc(sizeof(WINTHREAD));                      winthread node 생성

   /* Owner hwnd setting */
   pth->hwnd = srvwp;                                             Thread owner window setting
                  Winthread creation (4/5)


/* Semaphore for stop waiting ,when moving window, setting */           Window가 움직일 경우,
  sem_init(&pth->sem, 0, 1);                                           Thread를 멈출 때 사용할
                                                                            세마포어 세팅
  /* Window thread is initially TSTATE_NORMAL_WORKING */
  pth->state = TSTATE_NORMAL_WORKING;                                      처음에 Thread는
                                                                       TSTATE_NORMAL_WORKING
  /* Thread's attribute setting */                                        state에 있게 된다
  pthread_attr_init(&attr);
  pthread_attr_setschedpolicy(&attr, SCHED_RR);                        쓰레드의 스케쥴링 정책은
                                                                            RR이다
  if(dwStackSize > 0)
     pthread_attr_setstacksize(&attr, (size_t)dwStackSize);
                                                                       쓰레드의 Stack size 세팅
  /* thread creating */
  pthread_create(&pth->th, &attr, (void *(*)(void *))lpStartAddress,
                 (void *)lpParameter);
                                                                            쓰레드 생성
                      Winthread creation (5/5)


 /* Insert element in thread lists */
   LIST_INSERT_HEAD(&pth->hwnd->thlist, pth, pcow, ncow);   Thread list의 해드에 node 저장
   LIST_INSERT_HEAD(&thread_list, pth, prev, next);

    if(lpThreadID){
       *lpThreadID = *((LPWORD)pth->th);
    }

    /* Mutex unlock */
    pthread_mutex_unlock(&mutex);                                 Mutex unlock

    return pth->th;
}
           Window moving (1/6)
• 윈도우를 움직일 때 thread 제어의 문제점
  – 윈도우를 움직일 때 thread를 그림그리기 직전에 멈추어야 한다
  – 그렇지 않으면…
      • Thread를 멈추지 않을 때
          – 윈도우를 움직여 local cliprects를 업데이트를 하는 도중에 thread
            가 멈추지 않고 그림을 그릴 경우 업데이트 되지 않은 local clip
            rects에 그림을 그릴 수 있다
      • Thread를 그림 그리기 직전에 멈추지 않을 경우
          – 만약 thread가 그림을 그릴 때, 그 영역이 그림을 그려도 된다고 판
            단하고 멈추었을 때, Local cliprects는 update되었지만, 나중에 재
            개된 thread는 update되지 않은 영역에 그림을 그린다
• 해결책
  – Spin lock (busy waiting), dont_paint Flag, sem_wait() 사용
                    Window moving (2/6)
      • Spin lock과 dont_paint 플래그를 사용
                         don’t paint flag
                                                                              WINAPI Rectangle()
                                                                              {
                                1/0                                             WaitPaintable();
                                                                                …
                                                                                PaintDone();
                                                                              }
MoveWindow()
{
  WaitMovable();
                                                                                        WINAPI LineTo()
  …
                                                                                        {
  WakeUpThread();
                                                                                          WaitPaintable();
}
                                                                                          …
                                                                                          PaintDone();
                                                                                        }



                         함수                            설명
                                                                                  WINAPI FillRect()
                     WaitMovable()          모든 Thread가 block될 때까지 기다린다
                                                                                  {
                                                                                    WaitPaintable();
                    WakeUpThread()          모든 block되어 있는 thread를 깨운다
                                                                                    …
                                                                                    paintDone();
                                          dont_paint 플래그가 on되어있으면                 }
                    WaitPaintable()   Thread 상태를 TSTATE_WAITING_MOVING_DONE
                                               으로 바꾸고 block 한다
                                       Thread의 상태를 TSTATE_NORMAL_WORKING
                      PaintDone()
                                                  으로 바꾼다
                    Window moving (3/6)
    • WaitMovable() – mWin context에서 수행


void WaitMovable(void)
{                                                       dont_flag on (Don’t paint)
   WINTHREAD *i;
   DONT_PAINT();
                                                        Thread가 API의 처음 위치에서 멈
   for(i=thread_list.next;i!=&thread_list;i=i->next){
                                                          출 때까지 Spin lock을 한다
      while(i->state==TSTATE_PAINTING){
      }
   }
}
                      Window moving (4/6)
     • WakeUpThread() – mWin context에서 수행

void WakeUpThread(void)
{                                                       모든 윈도우의 Clip rects를 업데
   WINTHREAD *i;                                               이트 한다
   UpdateAllWndClipArea();
   DO_PAINT();
                                                           dont_flag를 off 한다
   for(i=thread_list.next;i!=&thread_list;i=i->next){
      if(i->state == TSTATE_WAITING_MOVING_DONE){
         i->state = TSTATE_NORMAL_WORKING;               API 처음 위치에서 잠자고 있는
         sem_post(&i->sem);                                  Thread를 모드 깨운다
      }
   }
}
                       Window moving (5/6)
      • WaitPaintable() – mWin context 혹은 다른 winthread context에
        서 수행
int WaitPaintable(HDC hdc)
{
   HWND hwnd = hdc->hwnd;
   PWINTHREAD pwt;

    if(MwIsClientDC(hdc)) hwnd->winctxt.cliprects = hwnd->winctxt.ccliprects;
    else hwnd->winctxt.cliprects = hwnd->winctxt.wcliprects;

    if(pwt = FindMeInHwnd(hwnd)){
       if(!IS_PAINTABLE()){
          if(HAS_WINDOW_THREAD(hwnd)){
             pwt->state = TSTATE_WAITING_MOVING_DONE;
             sem_wait(&pwt->sem);                            Paintable하고 이 함수를 실행시키는 것
          }                                                   이 mWin 컨텍스트가 아닐 경우 잠잔다
       }
       pwt->state = TSTATE_PAINTING;
                                                             깨어나면 State를 TSTATE_PAINTING이라
       return 1;
                                                                        고 한다
    }
    return NULL;
}
                    Window moving (6/6)
    • PaintDone() – mWin context 혹은 다른 winthread context에서 수
      행

int PaintDone(HWND hwnd)
{
   PWINTHREAD pwt;
   if(pwt = FindMeInHwnd(hwnd)){                    Winthread 상태를
      pwt->state = TSTATE_NORMAL_WORKING;   TSTATE_NORMAL_WORKING이라고 한다
      return 1;
   }
   return NULL;
}
PEG Multithread mode
         VS
mWin Multithread mode
  PEG (Portable Embedded GUI)
• Swell soft에서 만든 Embedded system을 위한
  Window system이다
• 특징
  – 프로그래밍 모델
      • C++
      • Event driven
  –   작은 크기
  –   쉬운 포팅
  –   강력한 API
  –   다양한 개발환경 제공
      • Screen editor
      • Font capture
         PEG Execution model
• Singlethread mode




               M
                      M

           M



                          M M M
                   PEG Execution model
• Multithread mode


                   Clip rectangles

                                                                    Clock 1

                                       Semaphore
  Clock 1 Thread                                                                   Clock 3
                                                        Clock 2         00:01:24


                                                                                      00:01:39
                                                            00:04:59




                                                                          Screen
               Clip rectangles

  Clock 2 Thread
                                                  Clip rectangles
                                     Clock 3 Thread
           mWin Multithread model


                 Clip rectangles

                                                                  Clock 1


Clock 1 Thread                                                                   Clock 3
                                                      Clock 2         00:01:24


                                                                                    00:01:39
                                                          00:04:59




                                                                        Screen
             Clip rectangles

Clock 2 Thread
                                                Clip rectangles
                                   Clock 3 Thread
   mWin Multithread model VS
    PEG Multithread model
• PEG의 멀티쓰래딩 모델
 – 구현이 쉽다
 – 다른 윈도우 쓰래드가 그림을 그리고 있는 동안 다른 윈도우
   쓰래드는 블락된다 (Non-preemtive)
   • 느리다
• mWin의 멀티쓰래딩 모델
 – 구현이 다소 복잡하지만, 어렵지는 않다
 – 다른 윈도우 쓰래드가 그림을 그리고 있는 동안 다른 윈도우
   쓰래도 그림을 그릴 수 있다
   • 빠르다
                 결론
• mWin의 Multithreading 구조는 preemptive 하다
• mWin은 PEG 보다 멀티쓰래딩 구조에서 좋은 성능을
  보인다
               Future work
• Experiment (8월 31일)
• Documentation (9월 30일)
• Defense 준비 (10월 31일)

								
To top