
1. Creation
text, data, bss, stack area 만들어짐 (initial context)
: process가 실행할 수 있는 환경 만들어 주는 것
🤔 suspend 되는 경우 3가지?
✔ resumption을 해줘야 풀림
Resumption
ready-list로 불러들여서 실행 가능한 상태로 만들어 주는 것
Termination
다 끝난 것
현재 process가 차지하고 있는 resouce를 free시켜줌 (proc 엔트리 등등)
user가 부를 수 있는 kernal function
: information hiding! user가 복잡한 구조를 알 필요가 없다!
syscall function_name(args) {
intmask mask; /* 현재 인터럽트가 enable인지, disable인지 구분해 주는 bit */
mask = disable( ); /* 여러 개의 user가 하나의 kernal을 공유하므로, 한 user가 API 사용할거면, 이런식으로 인터럽트 diable을 걸어서, 자기가 다 사용한 다음에 다른 user에게 kernal 사용권을 넘겨줘야 = kernal protection */
/* 에러났어 */
if ( args are incorrect ) {
restore(mask); /* 인터럽트 어떤 상태인지 저장부터 */
return(SYSERR);
}
...other processing...
if ( an error occurs ) {
restore(mask);
return(SYSERR);
}
... more processing...
/* 마지막 */
restore(mask); /* return 하기 전에 인터럽트 어떤 상태인지 저장부터 */
return( appropriate value );
}
return from exception에 도달하면 다시 main program으로 돌아옴 (즉, main문 코드 안에서 machine instruction (= function)의 바로 다음 줄 실행), return from exception하기 바로 전에서 꼭 interrupt enable해줘서 main아래 다른 instruction들도 실행 가능하도록 만들기!ex) file read syscall()
어떤 block data를 가져오라고 명령하면 3ms 정도 걸림
➡ 자기 자신을 I/O wait Q 안에 집어 넣음
➡ 이 사이 쯤에서 만약 global data를 수정했다면, 수정한거는 다 끝내고 다음 step 밟기
➡ resched()
➡ 다른 process가 run
🤞 1. 초기 n=0. prod2를 통해 n을 1로 증가시키고, cons2로 가서 n출력, prod2를 통해 n을 2로 증가시키고, 다시 cons2로 가서 n출력 ... 2000번 반복이 목적인 코드

#include <xinu.h>
void prod2(sid32, sid32), cons2(sid32, sid32);
int32 n = 0; /* n 0으로 전역에 설정 */
/*------------------------------------------------------------------------
* main -- producer and consumer processes synchronized with semaphores
*------------------------------------------------------------------------
*/
void main(void)
{
sid32 produced, consumed;
consumed = semcreate(0);
produced = semcreate(1);
/* create(process, stksize, priority, process이름, ...) */
resume( create(cons2, 1024, 20, "cons", 2, consumed, produced) ); /* 소비하는 process */
resume( create(prod2, 1024, 20, "prod", 2, consumed, produced) );
} /* 무언가를 생성하는 process */
/*------------------------------------------------------------------------
* prod2 -- increment n 2000 times, waiting for it to be consumed
*------------------------------------------------------------------------
*/
void prod2(
sid32 consumed,
sid32 produced
)
{
int32 i;
for( i=1 ; i<=2000 ; i++ ) {
wait(consumed);
n++;
signal(produced);
}
}
/*------------------------------------------------------------------------
* cons2 -- print n 2000 times, waiting for it to be produced
*------------------------------------------------------------------------
*/
void cons2(
sid32 consumed,
sid32 produced
)
{
int32 i;
for( i=1 ; i<=2000 ; i++ ) {
wait(produced);
printf("n is %d \n", n);
signal(consumed);
}
}
🤞 2. 100개 길이짜리 배열 만들어서 절반은 한 process담고, 절반은 다른 process담아서 순차적으로 process가 일어나게 만들자

void main(void){
resume(create(additem, 1024, 20, "A", 1, 777));
resume(create(additem, 1024, 20, "B", 1, 333));
}
#include <xinu.h>
sid32 mutex;
int32 shared[100]; /* an array shared by many processes */
int32 n = 0; /* count of items in the array */
/*------------------------------------------------------------------------
* additem -- obtain exclusive access to array ary and add an item to it
*------------------------------------------------------------------------
*/
void additem(
int32 item /* item to add to array ary */
)
{
wait(mutex);
shared[n++] = item;
signal(mutex);
}


🤞🤞 1. semaphore.h
#ifndef NSEM
#define NSEM 45 /* number of semaphores, if not defined */
#endif
/* Semaphore state definitions */
#define S_FREE 0 /* semaphore table entry is available */
#define S_USED 1 /* semaphore table entry is in use */
/* Semaphore table entry */
struct sentry {
byte sstate; /* 세마포어가 사용되고 있는지 아닌지 S_FREE or S_USED */
int32 scount; /* 😍차단기 역할. 현재 바로 critical section 사용 가능한 세마포어 개수😍 */
qid16 squeue; /* Q에서 기다리고 있는 process 개수 */
};
extern struct sentry semtab[];
/* s는 semtab안에 할당 되는 세마포어 id */
#define isbadsem(s) ((int32)(s) < 0 || (s) >= NSEM)
🤞🤞 1. wait
#include <xinu.h>
syscall wait(
sid32 sem /* semaphore on which to wait */
)
{
intmask mask;
struct procent *prptr; /* ptr to process’ table entry */
struct sentry *semptr; /* ptr to sempahore table entry */
mask = disable(); /* 인터럽트 disable (이 뒤부터 user가 사용하는 API라는 뜻) */
if (isbadsem(sem)) { /* 제대로 된 세마포어 num이 아닐 때 에러❗ */
restore(mask);
return SYSERR;
}
semptr = &semtab[sem];
if (semptr->sstate == S_FREE) { /* 아무도 사용하지 않는 세마포어일때 에러❗ */
restore(mask);
return SYSERR;
}
if (--(semptr->scount) < 0) { /* 😍scount는 기본적으로 1. 하나 줄였더니 0보다 작더라 = 원래 1보다 작았다 = 이미 critical section에 누가 들어와 있어서 바로 세마포어 사용 불가능하다😍 */
prptr = &proctab[currpid];
prptr->prstate = PR_WAIT; /* wait하도록 만들어줌 */
prptr->prsem = sem; /* semaphore ID 기록 */
enqueue(currpid,semptr->squeue);/* semaphore의 FIFO Q에 enqueue */
resched(); /* 😍reschedule - 반드시 콘텍스트 스위치 불러서 current가 outgoing context됨😍 */
}
restore(mask);
return OK;
}
🤞🤞 2. signal
#include <xinu.h>
syscall signal(
sid32 sem /* signal할 semaphore ID */
)
{
intmask mask;
struct sentry *semptr; /* ptr to sempahore table entry */
mask = disable(); /* 인터럽트 disable */
if (isbadsem(sem)) { /* 제대로 된 세마포어 num이 아닐 때 에러❗ */
restore(mask);
return SYSERR;
}
semptr= &semtab[sem];
if (semptr->sstate == S_FREE) { /* 아무도 사용하지 않는 세마포어일때 에러❗ */
restore(mask);
return SYSERR;
}
if ((semptr->scount++) < 0) { /* 우선 scount가 0보다 작다 */
ready(dequeue(semptr->squeue), RESCHED_YES);
}
restore(mask);
return OK;
}