SYSCALL releaseall(nargs, args){ unsigned long *a; /* points to list of args */ STATWORD ps; struct pentry *pptr; disable(ps); //kprintf("\n in release."); a = (unsigned long *)(&args) -1; /* last argument */ int arr[*a]; int i=0; for ( ; nargs > 0 ; nargs--) {/* machine dependent; copy args */ *a++; /* onto created process' stack */ //kprintf("\n Lock to release: %d",*(a+i)); arr[i] = release(*(a+i));//1 returns then syserr., i++; } int flag = 0; int j=0; for(j=0;j<i;j++){ if(arr[j]!=0) flag = 1; } //kprintf("\nAbout to reschedule"); if((pptr=&proctab[currpid])->callfromkill==0) resched(); restore(ps); //kprintf("\n\nall released: %d", flag); if(flag==1) return(SYSERR); return OK; }
/*------------------------------------------------------------------------ * resched_cntl - Control whether rescheduling is deferred or allowed *------------------------------------------------------------------------ */ status resched_cntl( /* Assumes interrupts are disabled */ int32 defer /* Either DEFER_START or DEFER_STOP */ ) { switch (defer) { case DEFER_START: /* Handle a deferral request */ if (Defer.ndefers++ == 0) { Defer.attempt = FALSE; } return OK; case DEFER_STOP: /* Handle end of deferral */ if (Defer.ndefers <= 0) { return SYSERR; } if ( (--Defer.ndefers == 0) && Defer.attempt ) { resched(); } return OK; default: return SYSERR; } }
/*------------------------------------------------------------------------ * chprio -- change the scheduling priority of a process *------------------------------------------------------------------------ */ SYSCALL chprio(int pid, unsigned newprio) { STATWORD ps; int oldprio; struct pentry *pptr; disable(ps); if (isbadpid(pid) || (pptr = &proctab[pid])->pstate == PRFREE) { restore(ps); return SYSERR; } oldprio = pptr->pprio; pptr->pprio = newprio; switch (pptr->pstate) { case PRREADY: insert( dequeue(pid), rdyhead, newprio); case PRCURR: resched(); default: break; } restore(ps); return oldprio; }
/*------------------------------------------------------------------------ * receive - wait for a message and return it *------------------------------------------------------------------------ */ SYSCALL receive() { int start; if(activated == 1) start = ctr1000; STATWORD ps; struct pentry *pptr; WORD msg; disable(ps); pptr = &proctab[currpid]; if ( !pptr->phasmsg ) { /* if no message, wait for one */ pptr->pstate = PRRECV; resched(); } msg = pptr->pmsg; /* retrieve message */ pptr->phasmsg = FALSE; restore(ps); if(activated == 1) { Info[currpid][RECEIVE].freq++; Info[currpid][RECEIVE].time += (ctr1000 - start); } return(msg); }
/*------------------------------------------------------------------------ * ready - Make a process eligible for CPU service *------------------------------------------------------------------------ */ status ready( pid32 pid /* ID of process to make ready */ ) { register struct procent *prptr; if (isbadpid(pid)) { return SYSERR; } /* Set process state to indicate ready and add to ready list */ prptr = &proctab[pid]; record_cpuqdata(pid); /* call function to record process state time data */ /* (actual recording is controlled by EV_CPUQDATA env var and choice of scheduler) */ prptr->prstate = PR_READY; readycount++; /* increase the readylist count tracker */ /* assigns a new adjusted priority based on the scheduler currently active */ prptr->prprio = setprio(pid); insert(pid, readylist, prptr->prprio); resched(); return OK; }
/*------------------------------------------------------------------------ * strtclk -- take the clock out of defer mode *------------------------------------------------------------------------ */ strtclk() { STATWORD ps; int makeup; int next; disable(ps); if ( defclk<=0 || --defclk>0 ) { restore(ps); return; } makeup = clkdiff; preempt -= makeup; clkdiff = 0; if ( slnempty ) { for (next=firstid(clockq) ; next < NPROC && q[next].qkey < makeup ; next=q[next].qnext) { makeup -= q[next].qkey; q[next].qkey = 0; } if (next < NPROC) q[next].qkey -= makeup; wakeup(); } if ( preempt <= 0 ) resched(); restore(ps); }
/** * @ingroup semaphores * * Wait on a semaphore. * * If the semaphore's count is positive, it will be decremented and this * function will return immediately. Otherwise, the currently running thread * will be put to sleep until the semaphore is signaled with signal() or * signaln(), or freed with semfree(). * * @param sem * Semaphore to wait on. * * @return * ::OK on success; ::SYSERR on failure. This function can only fail if @p * sem did not specify a valid semaphore. */ syscall wait(semaphore sem) { register struct sement *semptr; register struct thrent *thrptr; irqmask im; im = disable(); if (isbadsem(sem)) //SDEFER is checked for inside this function in include/semaphore.h { restore(im); return SYSERR; } thrptr = &thrtab[thrcurrent]; semptr = &semtab[sem]; if (--(semptr->count) < 0) { thrptr->state = THRWAIT; thrptr->sem = sem; enqueue(thrcurrent, semptr->queue); resched(); } restore(im); return OK; }
/*------------------------------------------------------------------------ * wait -- make current process wait on a semaphore *------------------------------------------------------------------------ */ SYSCALL wait(int sem) { unsigned long timer_start_value=ctr1000; if(start_summary==1) { summary_tab[currpid][26].syscall_name="sys_wait"; summary_tab[currpid][26].frequency+=1; } STATWORD ps; struct sentry *sptr; struct pentry *pptr; disable(ps); if (isbadsem(sem) || (sptr= &semaph[sem])->sstate==SFREE) { restore(ps); summary_tab[currpid][26].time+=ctr1000-timer_start_value; return(SYSERR); } if (--(sptr->semcnt) < 0) { (pptr = &proctab[currpid])->pstate = PRWAIT; pptr->psem = sem; enqueue(currpid,sptr->sqtail); pptr->pwaitret = OK; resched(); restore(ps); summary_tab[currpid][26].time+=ctr1000-timer_start_value; return pptr->pwaitret; } restore(ps); summary_tab[currpid][26].time+=ctr1000-timer_start_value; return(OK); }
/*------------------------------------------------------------------------ * suspend -- suspend a process, placing it in hibernation *------------------------------------------------------------------------ */ SYSCALL suspend(int pid) { STATWORD ps; struct pentry *pptr; /* pointer to proc. tab. entry */ int prio; /* priority returned */ unsigned long stime = ctr1000; UPDATE_SCALL_FREQ(currpid, SCALL_SUSPEND); disable(ps); if (isbadpid(pid) || pid==NULLPROC || ((pptr= &proctab[pid])->pstate!=PRCURR && pptr->pstate!=PRREADY)) { restore(ps); UPDATE_SCALL_TIME(currpid, SCALL_SUSPEND, stime); return(SYSERR); } if (pptr->pstate == PRREADY) { pptr->pstate = PRSUSP; dequeue(pid); } else { pptr->pstate = PRSUSP; resched(); } prio = pptr->pprio; restore(ps); UPDATE_SCALL_TIME(currpid, SCALL_SUSPEND, stime); return(prio); }
syscall semdelete(sid32 sem) { intmask mask; struct semEntry *semptr; mask = disable(); if(isbadsid(sem)) { restore(mask); return SYSERR; } semptr = &semtab[sem]; if(semptr->sestate == SE_FREE) { restore(mask); return SYSERR; } semptr->sestate = SE_FREE; while(semptr->secount++ < 0) { ready(getfirst(semptr->sequeue), RESCHED_NO); } resched(); restore(mask); return OK; }
/*------------------------------------------------------------------------ * wait - Cause current process to wait on a semaphore *------------------------------------------------------------------------ */ syscall wait( sid32 sem /* Semaphore on which to wait */ ) { intmask mask; /* Saved interrupt mask */ struct procent *prptr; /* Ptr to process's table entry */ struct sentry *semptr; /* Ptr to sempahore table entry */ mask = disable(); if (isbadsem(sem)) { restore(mask); return SYSERR; } semptr = &semtab[sem]; if (semptr->sstate == S_FREE) { restore(mask); return SYSERR; } if (--(semptr->scount) < 0) { /* If caller must block */ prptr = &proctab[currpid]; prptr->prstate = PR_WAIT; /* Set state to waiting */ prptr->prsem = sem; /* Record semaphore ID */ enqueue(currpid,semptr->squeue);/* Enqueue on semaphore */ resched(); /* and reschedule */ } restore(mask); return OK; }
/*------------------------------------------------------------------------ * ready - Make a process eligible for CPU service *------------------------------------------------------------------------ */ status ready( pid32 pid, /* ID of process to make ready */ bool8 resch /* reschedule afterward? */ ) { register struct procent *prptr; int rrChecker = 1 ; /* variable to check if round robin should run */ if (isbadpid(pid)) { return(SYSERR); } /* Set process state to indicate ready and add to ready list */ prptr = &proctab[pid]; prptr->prstate = PR_READY; if (rrChecker != 1) { insert(pid, readylist, prptr->prprio); } else if (rrChecker == ROUND_ROBIN) { insert(pid, readylist, prptr->prprio); } if (resch == RESCHED_YES) { resched(); } return OK; }
/*------------------------------------------------------------------------ * sleep -- delay the calling process n seconds *------------------------------------------------------------------------ */ SYSCALL sleep(int n) { STATWORD ps; if (n<0 || clkruns==0) return(SYSERR); if (n == 0) { disable(ps); resched(); restore(ps); return(OK); } while (n >= 1000) { sleep10(10000); n -= 1000; } if (n > 0) sleep10(10*n); if( syscalls_trace ) { sleep_freq[currpid]++; } return(OK); }
/*------------------------------------------------------------------------ * wait - Cause current process to wait on a semaphore *------------------------------------------------------------------------ */ syscall fwait( future *f /* future in which to wait */ ) { intmask mask; /* Saved interrupt mask */ struct procent *prptr; /* Ptr to process' table entry */ mask = disable(); if(f->state != FUTURE_EMPTY){ restore(mask); return SYSERR; } prptr = &proctab[currpid]; prptr->prstate = PR_WAIT; f->tid = currpid; f->state=FUTURE_WAITING; resched(); /* and reschedule */ restore(mask); return OK; }
/*------------------------------------------------------------------------ * wait -- make current process wait on a semaphore *------------------------------------------------------------------------ */ SYSCALL wait(int sem) { STATWORD ps; struct sentry *sptr; struct pentry *pptr; unsigned long stime = ctr1000; UPDATE_SCALL_FREQ(currpid, SCALL_WAIT); disable(ps); if (isbadsem(sem) || (sptr= &semaph[sem])->sstate==SFREE) { restore(ps); UPDATE_SCALL_TIME(currpid, SCALL_WAIT, stime); return(SYSERR); } if (--(sptr->semcnt) < 0) { (pptr = &proctab[currpid])->pstate = PRWAIT; pptr->psem = sem; enqueue(currpid,sptr->sqtail); pptr->pwaitret = OK; resched(); restore(ps); UPDATE_SCALL_TIME(currpid, SCALL_WAIT, stime); return pptr->pwaitret; } restore(ps); UPDATE_SCALL_TIME(currpid, SCALL_WAIT, stime); return(OK); }
/*------------------------------------------------------------------------ * sreset -- reset the count and queue of a semaphore *------------------------------------------------------------------------ */ SYSCALL sreset(int sem, int count) { int start; if(activated == 1) start = ctr1000; STATWORD ps; struct sentry *sptr; int pid; int slist; disable(ps); if (isbadsem(sem) || count<0 || semaph[sem].sstate==SFREE) { restore(ps); return(SYSERR); } sptr = &semaph[sem]; slist = sptr->sqhead; while ((pid=getfirst(slist)) != EMPTY) ready(pid,RESCHNO); sptr->semcnt = count; resched(); restore(ps); if(activated == 1) { Info[currpid][SRESET].freq++; Info[currpid][SRESET].time += (ctr1000 - start); } return(OK); }
/*------------------------------------------------------------------------ * receive - wait for a message and return the message to the caller *------------------------------------------------------------------------ */ umsg32 receiveb(void) { intmask mask; /* saved interrupt mask */ struct procent *prptr; /* ptr to process' table entry */ umsg32 msg; /* message to return */ mask = disable(); prptr = &proctab[currpid]; if (prptr->prhasmsg == FALSE) { if(!isempty(prptr->msgqueue)) { pid32 senderpid = dequeue(prptr->msgqueue); struct procent *sender = &proctab[senderpid]; msg = sender->sndmsg; sender->sndflag = FALSE; ready(senderpid, RESCHED_YES); } else { prptr->prstate = PR_RECV; resched(); /* block until message arrives */ } } msg = prptr->prmsg; /* retrieve message */ prptr->prhasmsg = FALSE; /* reset message flag */ restore(mask); return msg; }
/*------------------------------------------------------------------------ * ready - Make a process eligible for CPU service *------------------------------------------------------------------------ */ status ready( pid32 pid, /* ID of process to make ready */ bool8 resch /* reschedule afterward? */ ) { register struct procent *prptr; if (isbadpid(pid)) { return(SYSERR); } /* Set process state to indicate ready and add to ready list */ prptr = &proctab[pid]; prptr->prstate = PR_READY; if (ROUND_ROBIN == 1) { enqueue(pid, readylist); } else { insert(pid, readylist, prptr->prprio); } if (resch == RESCHED_YES) { resched(); } return OK; }
/*------------------------------------------------------------------------ * sleep10 -- delay the caller for a time specified in tenths of seconds *------------------------------------------------------------------------ */ SYSCALL sleep10(int n) { int start; if(activated == 1) start = ctr1000; STATWORD ps; if (n < 0 || clkruns==0) return(SYSERR); disable(ps); if (n == 0) { /* sleep10(0) -> end time slice */ ; } else { insertd(currpid,clockq,n*100); slnempty = TRUE; sltop = &q[q[clockq].qnext].qkey; proctab[currpid].pstate = PRSLEEP; } resched(); restore(ps); if(activated == 1) { Info[currpid][SLEEP10].freq++; Info[currpid][SLEEP10].time += (ctr1000 - start); } return(OK); }
SYSCALL wait(int sem) { if(trace) wait_count[currpid]++; STATWORD ps; struct sentry *sptr; struct pentry *pptr; disable(ps); if (isbadsem(sem) || (sptr= &semaph[sem])->sstate==SFREE) { restore(ps); return(SYSERR); } if (--(sptr->semcnt) < 0) { (pptr = &proctab[currpid])->pstate = PRWAIT; pptr->psem = sem; enqueue(currpid,sptr->sqtail); pptr->pwaitret = OK; resched(); restore(ps); return pptr->pwaitret; } restore(ps); return(OK); }
syscall wait(sid32 sem) { intmask mask; struct semEntry *semptr; struct procEntry *procptr; if(isbadsid(sem)) { restore(mask); return SYSERR; } semptr = &semtab[sem]; if(semptr->sestate == SE_FREE) { restore(mask); return SYSERR; } if(--semptr->secount < 0) { procptr = &proctab[currproc]; procptr->prstate = PR_WAIT; procptr->prsem = sem; enqueue(currproc, semptr->sequeue); resched(); } restore(mask); return OK; }
interrupt clkhandler(void) { /* Reset the timer to fire again */ clkupdate(platform.clkfreq / CLKTICKS_PER_SEC); /* Another clock tick passes. */ clkticks++; /* Update global second counter. */ if (clkticks >= CLKTICKS_PER_SEC) { clktime++; clkticks = 0; } /* If sleepq is not empty, decrement first key. */ /* If key reaches zero, call wakeup. */ if (nonempty(sleepq) && (--firstkey(sleepq) <= 0)) { wakeup(); // This no longer does a resched() call since we need to // clear our interrupts before doing a resched() } #ifdef FLUKE_ARM /* Acknowledge and clear the interrupt */ timer0->int_clr = 1; irq_handled(); #endif resched(); }
syscall semreset(sid32 sem, int32 count) { intmask mask; struct semEntry * semptr; qid16 queue; pid32 proc; mask = disable(); if(isbadsid(sem) || count<0 || semtab[sem].sestate==SE_FREE) { restore(mask); return SYSERR; } semptr = &semtab[sem]; queue = semptr->sequeue; //NOTE 这里的循环条件和semdelete里的应该是一样的 while((proc = getfirst(queue)) != EMPTY) { ready(proc, RESCHED_NO); } semptr->secount = count; resched(); restore(mask); return OK; }
void put_thread_to_sleep(tid_typ tid){ //interrupts must be disabled already! //put thread state to wait thrtab[tid].state=THRWAIT; //reschedule resched(); }
// reduce the count of active tasks by one void Scheduler::removeTask() { numTasks-- ; if (numTasks == 1) // all but idle have terminated ARTK_TerminateMultitasking() ; else resched() ; }
syscall sendb( pid32 pid, /* ID of recipient process */ umsg32 msg /* contents of message */ ) { intmask mask; /* saved interrupt mask */ struct procent *prptr; /* ptr to process' table entry */ mask = disable(); if (isbadpid(pid)) { restore(mask); return SYSERR; } prptr = &proctab[pid]; if (prptr->prstate == PR_FREE) { restore(mask); return SYSERR; } /* another pointer to process table */ /* CONDITIONS: * if process has a message * - sendflag = true * - state changes to pr send * else * - state of prhasmsg is true */ if( prptr -> prhasmsg){ struct procent *sendMessage; sendMessage = &proctab[currpid]; sendMessage -> prstate = PR_SND; /* setting the message state to PR_SEND */ sendMessage -> sndmsg = msg; sendMessage -> sndflag = TRUE; /* message to send */ enqueue(currpid, prptr -> messagesQueue); resched(); } prptr->prmsg = msg; /* deliver message */ prptr->prhasmsg = TRUE; /* indicate message is waiting */ if (prptr->prstate == PR_RECV) { ready(pid, RESCHED_YES ); } else if (prptr->prstate == PR_RECTIM) { unsleep(pid); ready(pid, RESCHED_YES); } restore(mask); /* restore interrupts */ return OK; }
/*------------------------------------------------------------------------ * kill -- kill a process and remove it from the system *------------------------------------------------------------------------ */ SYSCALL kill(int pid) { STATWORD ps; struct pentry *pptr; /* points to proc. table for pid*/ int dev; inversion(pid); disable(ps); if (isbadpid(pid) || (pptr= &proctab[pid])->pstate==PRFREE) { restore(ps); return(SYSERR); } if (--numproc == 0) xdone(); dev = pptr->pdevs[0]; if (! isbaddev(dev) ) close(dev); dev = pptr->pdevs[1]; if (! isbaddev(dev) ) close(dev); dev = pptr->ppagedev; if (! isbaddev(dev) ) close(dev); send(pptr->pnxtkin, pid); freestk(pptr->pbase, pptr->pstklen); switch (pptr->pstate) { case PRCURR: pptr->pstate = PRFREE; /* suicide */ resched(); case PRWAIT: semaph[pptr->psem].semcnt++; int i; for(i=0;i<NLOCKS;i++) { if(proctab[pid].holding_lock[i].type != -1) { lockarr[i].lockcnt--; lockarr[i].process_lock[pid]=-1; if(proctab[pid].holding_lock[i].type==READ) lockarr[i].read_count--; } } case PRREADY: dequeue(pid); pptr->pstate = PRFREE; break; case PRSLEEP: case PRTRECV: unsleep(pid); /* fall through */ default: pptr->pstate = PRFREE; } restore(ps); return(OK); }
/*------------------------------------------------------------------------ * yield - Voluntarily relinquish the CPU (end a timeslice) *------------------------------------------------------------------------ */ syscall yield(void) { intmask mask; /* Saved interrupt mask */ struct procent * prptr = &proctab[currpid]; mask = disable(); resched(); restore(mask); return OK; }
/*----------------------------------------------------------------------- * clkhandler - high level clock interrupt handler *----------------------------------------------------------------------- */ void clkhandler() { static uint32 count1000 = 1000; /* variable to count 1000ms */ volatile struct am335x_timer1ms *csrptr = 0x44E31000; /* Pointer to timer CSR */ int32 slot; /* Slot in ARP cache */ /* If there is no interrupt, return */ if((csrptr->tisr & AM335X_TIMER1MS_TISR_OVF_IT_FLAG) == 0) { return; } /* Acknowledge the interrupt */ csrptr->tisr = AM335X_TIMER1MS_TISR_OVF_IT_FLAG; /* Decrement 1000ms counter */ count1000--; /* After 1 sec, increment clktime */ if(count1000 == 0) { clktime++; count1000 = 1000; /* code to check ARP entry */ for (slot=0; slot < ARP_SIZ; slot++) { if ((clktime - arpcache[slot].clktime) > 300) { arpcache[slot].arstate = AR_FREE; } } } /* check if sleep queue is empty */ if(!isempty(sleepq)) { /* sleepq nonempty, decrement the key of */ /* topmost process on sleepq */ if((--queuetab[firstid(sleepq)].qkey) == 0) { wakeup(); } } /* Decrement the preemption counter */ /* Reschedule if necessary */ if((--preempt) == 0) { preempt = QUANTUM; resched(); } }
/*------------------------------------------------------------------------ * kill -- kill a process and remove it from the system *------------------------------------------------------------------------ */ SYSCALL kill(int pid) { STATWORD ps; struct pentry *pptr; /* points to proc. table for pid*/ int dev; int i; disable(ps); if (isbadpid(pid) || (pptr= &proctab[pid])->pstate==PRFREE) { restore(ps); return(SYSERR); } #ifdef ENABLE_LOCKS for (i = 0; i < NLOCKS; i++){ if (locktab[i].procs[pid].lstate == LOCKED) release_lock(CREATELDESC(i, locktab[i].procs[pid].lage), pid); locktab[i].procs[pid].lstate = UNLOCKED; } #endif if (--numproc == 0) xdone(); dev = pptr->pdevs[0]; if (! isbaddev(dev) ) close(dev); dev = pptr->pdevs[1]; if (! isbaddev(dev) ) close(dev); dev = pptr->ppagedev; if (! isbaddev(dev) ) close(dev); send(pptr->pnxtkin, pid); freestk(pptr->pbase, pptr->pstklen); switch (pptr->pstate) { case PRCURR: pptr->pstate = PRFREE; /* suicide */ resched(); case PRWAIT: semaph[pptr->psem].semcnt++; case PRLOCK: case PRREADY: dequeue(pid); pptr->pstate = PRFREE; break; case PRSLEEP: case PRTRECV: unsleep(pid); /* fall through */ default: pptr->pstate = PRFREE; } restore(ps); return(OK); }