Semaphore

공부기록·2023년 10월 15일
0
post-thumbnail

관련 함수


  • OSSemCreate() : 세마포어 생성

  • OSSemPost()

    • 이벤트 발생을 알리는 함수 (signal)
    • semaphore++
  • OSSemPend()

    • 이벤트 발생을 기다리는 함수
    • semaphore--;
    • timeout값을 지정하면 그때까지만 대기상태를 유지하고 그 시간이 지나면 에러값을 가지고 리턴한다.
  • OSSemAccept()

    • semaphore가 사용불가 상태여도 대기하지 않는다.
  • OSSemQuery()

    • semaphore의 상태를 알 수 있다.
  • semaphore가 0이하일 경우 대기상태에 빠진다.


공유변수 접근

	OS_EVENT* sem;
    sem = OSSemCreate(1);
    
    OSSemPend(sem, 0, &err);
    /*
    	critical section
    */
    OSSemPost(sem);

기타 동기화

	OS_EVENT* sem;
    sem = OSSemCreate(0); //생성부터 waiting
  • task1이 OSSemPend(sem, 0, &err)함수 실행시 바로 block되고 특정 task(task2)가 OSSemPost(sem)함수를 실행해야 task1도 실행되는 형태이다.
	OS_EVNET *OSSemCreate(INT16U cnt){
        OS_EVENT *pevent;
        OS_ENTER_CRITICAL();
        /*FreeList로 부터 ECB 하나를 얻는다.*/
        pevent = OSEventFreeList;
        if (OSEventFreeList != (OS_EVENT *) 0) {
        	OSEventFreeList = (OS_EVENT *) OSEventFreeList->OSEventPtr;
          	//FreeList의 다음 포인터가 다음 ECB를 가르키도록 한다.
        }
        OS_EXIT_CRITICAL();
        if (pevent != (OS_EVENT *) 0) {
            pevent->OSEventType = OS_EVENT_TYPE_SEM;
            pevent->OSEventCnt = cnt;
            OSEventWaitListInit(pevent);
        }
        return (pevent);
    }



void OSSemPend(OS_EVENT pevent, INT16U timeout, INT8U err)


  1. pevent가 가리키는 ECB가 세마포어인지 검사한다. (pevent->OSEvenType)
  2. 세마포어가 사용가능한 경우 (cnt>0( count를 1 감소시키고 리턴
  3. 세마포어가 사용가능하지 않은 겅우(cnt = 0)
    다른 task가 세마포어에 시그널을 보낼 때까지 sleep
    3.1 sleep하도록 하기 위해 task의 TCB상태를 OS_STAT_SEM으로 만든다.
    3.2 timeout값의 지정 (OSTCBCur -> OSTCBDly = timeout)
    3.3 task를 sleep 상태로 만든다. (OS_EventTaskWait())
  4. OS_Sched() 호출하여 우선 순위 높은 task를 실행시킨다.
  5. 다시 task가 실행될 때 timeout이 발생하며 OSEventTO()함수가 호출되고, ECB링크가 끊어진다.

OSSemPend() 관련함수

  • OS_EventTaskWait() : task를 wait상태로 변경한다.
    : task를 준비리스트에서 삭제하고 대기리스트에 넣는다. (ready->wait)
  • OSEventTO() : OSXXXXPend에서 호출, 설정한 시간이 오버되었을 때 Ready로 이동하게 한다.
  • OS_Sched() : 우선순위 높은 task를 실행시키는 함수
   wait(S){
      while(S <= 0) {S--;}
   }
   signal(S){
      S++;
   }



void OSSemPOST(OS_EVENT *pevent)

  1. pevent가 가리키는 ECB가 세마포어인지 검사한다. (pevent->OSEventType)
  2. 세마포어를 기다리는 task가 있다면
    2.1 그 중 우선순위가 가장 높은 task를 ECB 대기리스트에서 제거하고 실행상태로 만든다. (OS_EventTaskRdy())
    2.2 OS_Sched()함수를 호출한다.
  3. 세마포어를 기다리는 task가 없다면 세마포어 counter를 1 증가시킨다.

OSSemPost() 관련함수

  • OS_EventTaskRdy() : wait상태에 있는 task 중에 가장 우선순위가 높은 task를 ready 상태로 바꾼다.



INT16U OSSemAccept(OS_EVENT *pevent)

  1. 세마포어 count가 0보다 클 때만 1감소되고 return한다.
  2. OSSemAccept()를 호출한 부분에서는 return값을 확인하여, 0이 아닌 경우와 0인 경우를 구분해서 수행한다.

0개의 댓글

관련 채용 정보