예제 #1
0
파일: mutex.c 프로젝트: dns/ArdOS
void OSCreateMutex(OSMutex *mutex)
{
	OSMakeAtomic();
	mutex->val=1;
	initQ(mutex->procList, OSMAX_TASKS, &mutex->blocked);
	OSExitAtomic();
}
예제 #2
0
void OSCreateMutex(OSMutex *mutex)
{
	unsigned char sreg;
	OSMakeAtomic(&sreg);
	mutex->val=1;
	initQ(mutex->procList, _maxTasks, &mutex->blocked);
	OSExitAtomic(sreg);
}
예제 #3
0
파일: task.c 프로젝트: dns/ArdOS
void enq(int pid, tQueue *q)
{
	OSMakeAtomic();
	if(q->ctr >= q->len)
		return;
			
	q->qptr[q->tail]=pid;
	q->ctr++;
	q->tail = (q->tail+1) % q->len;
	OSExitAtomic();
}
예제 #4
0
파일: mutex.c 프로젝트: dns/ArdOS
// Can only be used by one process.
void OSWait(OSCond *cond, OSMutex *mutex)
{
	OSMakeAtomic();
	if(!cond->pendingWake)
	{
		cond->blockedProcess=_running;
		_tasks[_running].status |= _OS_BLOCKED;
		OSGiveMutex(mutex);
		OSMakeAtomic();
		// If val is 1 it means no swap took place.
		if(mutex->val)
		OSSwap();
	
		// Retake the mutex when we resume
		OSTakeMutex(mutex);		
	}
	else
		cond->pendingWake=0;
		
	OSExitAtomic();
}
예제 #5
0
파일: task.c 프로젝트: dns/ArdOS
unsigned char procDeq(tQueue *q)
{
	unsigned char ret=255;
	OSMakeAtomic();
	if(q->ctr>0)
	{
		ret=q->qptr[q->head];
		q->head=(q->head+1)%q->len;
		q->ctr--;
	}				
	OSExitAtomic();
	return ret;
}
예제 #6
0
파일: mutex.c 프로젝트: dns/ArdOS
void OSSignal(OSCond *cond)
{
	OSMakeAtomic();
	if(cond->blockedProcess != 255)
	{
		_tasks[cond->blockedProcess].status &= ~_OS_BLOCKED;
		procEnq(cond->blockedProcess, _tasks, &_ready);
		cond->blockedProcess=255;
		cond->pendingWake=0;
		OSPrioSwap();
	}
	else
		cond->pendingWake=1;
	OSExitAtomic();
}
예제 #7
0
파일: mutex.c 프로젝트: dns/ArdOS
void OSTakeMutex(OSMutex *mutex)
{
	OSMakeAtomic();
	if(!mutex->val)
	{
		procEnq(_running, _tasks, &mutex->blocked);
		_tasks[_running].status |= _OS_BLOCKED;
		OSExitAtomic();
		OSSwap();
	}		
	else
		mutex->val=0;
		
	OSExitAtomic();
}
예제 #8
0
파일: task.c 프로젝트: dns/ArdOS
void initQ(unsigned char *qbuf, unsigned char len, tQueue *q)
{
	unsigned char i;
		
	OSMakeAtomic();
	q->head=0;
	q->tail=0;
	q->qptr=qbuf;
	q->len=len;
	q->ctr=0;

	for(i=0; i<len; i++)
		q->qptr[i]=255;
	OSExitAtomic();
}
예제 #9
0
파일: mutex.c 프로젝트: dns/ArdOS
void OSGiveMutex(OSMutex *mutex)
{
	OSMakeAtomic();
	unsigned char wakeProc=procDeq(&mutex->blocked);
	
	if(wakeProc!=255)
	{
		_tasks[wakeProc].status &= ~_OS_BLOCKED;
		procEnq(wakeProc, _tasks, &_ready);
		OSExitAtomic();
		OSPrioSwap();	
	}	
	else
		mutex->val=1;
	
	OSExitAtomic();
}
예제 #10
0
void OSCreateSema(TOSSema *sema, unsigned int initval, unsigned char isBinary)
{
	unsigned char sreg;
	OSMakeAtomic(&sreg);
	sema->isBinary=isBinary;
	
	if(!isBinary)
		sema->semaval=initval;
	else
		if(initval)
			sema->semaval=1;
		else
			sema->semaval=0;
			
	initQ(sema->tasklist, _maxTasks, &sema->taskQ);
	OSExitAtomic(sreg);
}
예제 #11
0
파일: task.c 프로젝트: dns/ArdOS
// Priority queue routines
void prioEnq(int pid, tTCB *tasklist, tQueue *q)
{
	unsigned char i;
	unsigned int iter=q->head;
	unsigned char flag=0;
	
	OSMakeAtomic();	
	if(q->ctr >= q->len)
		return;
		
	while(iter != q->tail && !flag)
	{
		flag=(tasklist[q->qptr[iter]].prio > tasklist[pid].prio);
			
		if(!flag)
			iter=(iter+1) % q->len;
	}		
		

	// If we have found our spot, shift the rest down and insert. Otherwise insert at the end
	if(flag)
	{
		if(q->tail > q->head)
			for(i=q->tail-1; i>=iter && i != 255; i--)
				q->qptr[(i+1)%q->len]=q->qptr[i];
		else
		{
				for(i=(q->tail > 0 ? q->tail-1 : q->len-1); i!=iter; i=(i>0 ? i-1 : q->len-1))
					q->qptr[(i+1)%q->len]=q->qptr[i];

				// Last case
				q->qptr[(i+1)%q->len]=q->qptr[i];
		}
	}
	else
		iter=q->tail;
		
	q->tail=(q->tail+1)%q->len;	
	q->qptr[iter]=pid;
	q->ctr++;
	OSExitAtomic();
}
예제 #12
0
void OSTakeSema(TOSSema *sema)
{
	unsigned char sreg;
	
	OSMakeAtomic(&sreg);
	if(sema->semaval>0)
		sema->semaval--;
	else
	{
		// Block current process
		_tasks[_running].status |= _OS_BLOCKED;
		
		// Enqueue this task
		prioEnq(_running, _tasks, &sema->taskQ);
		OSExitAtomic(sreg);

		// Call scheduler.
		OSSwap();
	}
	OSExitAtomic(sreg);
}
예제 #13
0
void OSGiveSema(TOSSema *sema)
{
	unsigned char sreg;
	OSMakeAtomic(&sreg);

	unsigned char tsk=procDeq(&sema->taskQ);
	
	if(tsk != 255)
	{
		// Removed blocked flag
		_tasks[tsk].status &= ~(_OS_BLOCKED);
		procEnq(tsk, _tasks, &_ready);
		
		// Call scheduler
		OSExitAtomic(sreg);
		OSPrioSwap();
	}
	else
		if(sema->isBinary)
			sema->semaval=1;
		else
			sema->semaval++;
	OSExitAtomic(sreg);
}