/* Call scheduler to run the 'next' process */ void yield(void) { enter_critical(); current_running->yield_count++; scheduler_entry(); leave_critical(); }
void TASK_stop_timer(task_timer* timer) { #ifndef CONFIG_TASK_NONCRITICAL_TIMER enter_critical(); TQ_ENTER_CRITICAL; #endif if (!timer->alive) { #ifndef CONFIG_TASK_NONCRITICAL_TIMER TQ_EXIT_CRITICAL; exit_critical(); #endif return; } task_sys.tim_lock = TRUE; timer->alive = FALSE; // wipe all dead instances task_timer *cur_timer = task_sys.first_timer; task_timer *pre_timer = NULL; while (cur_timer) { if (cur_timer->alive == FALSE) { if (pre_timer == NULL) { task_sys.first_timer = timer->_next; } else { pre_timer->_next = timer->_next; } } pre_timer = cur_timer; cur_timer = cur_timer->_next; } task_sys.tim_lock = FALSE; #ifndef CONFIG_TASK_NONCRITICAL_TIMER TQ_EXIT_CRITICAL; exit_critical(); #endif }
/* Unblock all threads waiting on c */ void condition_broadcast(condition_t * c) { enter_critical(); ASSERT(disable_count); unblock_all( &c->wait_queue ); leave_critical(); }
/* Unblock the first thread waiting on c, if extant */ void condition_signal(condition_t * c) { enter_critical(); ASSERT(disable_count); unblock_one( &c->wait_queue ); leave_critical(); }
void do_exit() { enter_critical(); current_running->status = EXITED; scheduler_entry(); /* No need for leave_critical() since scheduler_entry() never returns */ }
/* * This routine creates a new partition map and sets it current. If there * was a current map, the new map starts out identical to it. Otherwise * the new map starts out all zeroes. */ void make_partition() { register struct partition_info *pptr, *parts; int i; /* * Lock out interrupts so the lists don't get mangled. */ enter_critical(); /* * Get space for for the new map and link it into the list * of maps for the current disk type. */ pptr = (struct partition_info *)zalloc(sizeof (struct partition_info)); parts = cur_dtype->dtype_plist; if (parts == NULL) { cur_dtype->dtype_plist = pptr; } else { while (parts->pinfo_next != NULL) { parts = parts->pinfo_next; } parts->pinfo_next = pptr; pptr->pinfo_next = NULL; } /* * If there was a current map, copy its values. */ if (cur_label == L_TYPE_EFI) { struct dk_gpt *map; int nparts; int size; nparts = cur_parts->etoc->efi_nparts; size = sizeof (struct dk_part) * nparts + sizeof (struct dk_gpt); map = zalloc(size); (void) memcpy(map, cur_parts->etoc, size); pptr->etoc = map; cur_disk->disk_parts = cur_parts = pptr; exit_critical(); return; } if (cur_parts != NULL) { for (i = 0; i < NDKMAP; i++) { pptr->pinfo_map[i] = cur_parts->pinfo_map[i]; } pptr->vtoc = cur_parts->vtoc; } else { /* * Otherwise set initial default vtoc values */ set_vtoc_defaults(pptr); } /* * Make the new one current. */ cur_disk->disk_parts = cur_parts = pptr; exit_critical(); }
void __assfail(const char *assertion, const char *filename, int line_num) { char buf[800]; /* no assert() message in the library is this long */ ulwp_t *self; lwpid_t lwpid; /* avoid recursion deadlock */ if ((self = __curthread()) != NULL) { if (assert_thread == self) _exit(127); enter_critical(self); (void) _lwp_mutex_lock(&assert_lock); assert_thread = self; lwpid = self->ul_lwpid; } else { self = NULL; (void) _lwp_mutex_lock(&assert_lock); lwpid = _lwp_self(); } /* * This is a hack, but since the Abort function isn't exported * to outside consumers, libzpool's vpanic() function calls * assfail() with a filename set to NULL. In that case, it'd be * best not to print "assertion failed" since it was a panic and * not an assertion failure. */ if (filename == NULL) { (void) strcpy(buf, "failure for thread "); } else { (void) strcpy(buf, "assertion failed for thread "); } ultos((uint64_t)(uintptr_t)self, 16, buf + strlen(buf)); (void) strcat(buf, ", thread-id "); ultos((uint64_t)lwpid, 10, buf + strlen(buf)); (void) strcat(buf, ": "); (void) strcat(buf, assertion); if (filename != NULL) { (void) strcat(buf, ", file "); (void) strcat(buf, filename); (void) strcat(buf, ", line "); ultos((uint64_t)line_num, 10, buf + strlen(buf)); } (void) strcat(buf, "\n"); (void) __write(2, buf, strlen(buf)); /* * We could replace the call to Abort() with the following code * if we want just to issue a warning message and not die. * assert_thread = NULL; * _lwp_mutex_unlock(&assert_lock); * if (self != NULL) * exit_critical(self); */ Abort(buf); }
// return 0 on success, 1 on failure (extra credit) int lock_acquire(lock_t * l) { enter_critical(); int result = lock_acquire_helper(l); leave_critical(); return result; }
/* TODO: Block until the semaphore value is greater than zero and decrement it */ void semaphore_down(semaphore_t * s){ enter_critical(); if (s->value > 0) --s->value; else block(&s->wait_queue); leave_critical(); }
bool TASK_mutex_lock(task_mutex *m) { task *t = task_sys.current; if (!m->taken) { m->entries = 1; task_take_lock(t, m); TRACE_TASK_MUTEX_ENTER(t->_ix); return TRUE; } if (m->reentrant && m->owner == t) { m->entries++; TRACE_TASK_MUTEX_ENTER_M(t->_ix); ASSERT(m->entries < 254); return TRUE; } // taken, mark task still allocated and insert into mutexq TRACE_TASK_MUTEX_WAIT(t->_ix); enter_critical(); TQ_ENTER_CRITICAL; t->wait_mutex = m; if ((t->flags & (TASK_STATIC | TASK_LOOP)) == 0) { task_pool.mask[t->_ix/32] &= ~(1<<(t->_ix & 0x1f)); } if ((t->flags & TASK_LOOP)) { // looped, remove us from end of queue ASSERT(task_sys.last == t); ASSERT(task_sys.head); if (task_sys.head == t) { // the only task in sched queue task_sys.head = NULL; task_sys.last = NULL; } else { // find the task pointing to the last task == current task task *ct = (task *)task_sys.head; while (ct->_next != t) { ct = ct->_next; ASSERT(ct); } // remove last task from queue ct->_next = NULL; task_sys.last = ct; } } TQ_EXIT_CRITICAL; exit_critical(); // insert into mutex queue if (m->last == 0) { m->head = t; } else { m->last->_next = t; } m->last = t; t->_next = NULL; t->flags &= ~TASK_RUN; t->flags |= TASK_WAIT; return FALSE; }
void do_setpriority(priority_t priority) { if( priority >= 1 ) { enter_critical(); current_running->priority = priority; leave_critical(); } }
void STMPE_req_read_int_sta(void) { enter_critical(); bool do_req = stmpe.req_mask == 0; stmpe.req_mask |= STMPE_REQ_INT_STA; if (do_req) { stmpe_exe_req(); } exit_critical(); }
void STMPE_req_read_temp(void) { enter_critical(); bool do_req = stmpe.req_mask == 0; stmpe.req_mask |= STMPE_REQ_TEMP; if (do_req) { stmpe_exe_req(); } exit_critical(); }
int thr_sigsetmask(int how, const sigset_t *set, sigset_t *oset) { ulwp_t *self = curthread; sigset_t saveset; if (set == NULL) { enter_critical(self); if (oset != NULL) *oset = self->ul_sigmask; exit_critical(self); } else { switch (how) { case SIG_BLOCK: case SIG_UNBLOCK: case SIG_SETMASK: break; default: return (EINVAL); } /* * The assignments to self->ul_sigmask must be protected from * signals. The nuances of this code are subtle. Be careful. */ block_all_signals(self); if (oset != NULL) saveset = self->ul_sigmask; switch (how) { case SIG_BLOCK: self->ul_sigmask.__sigbits[0] |= set->__sigbits[0]; self->ul_sigmask.__sigbits[1] |= set->__sigbits[1]; self->ul_sigmask.__sigbits[2] |= set->__sigbits[2]; self->ul_sigmask.__sigbits[3] |= set->__sigbits[3]; break; case SIG_UNBLOCK: self->ul_sigmask.__sigbits[0] &= ~set->__sigbits[0]; self->ul_sigmask.__sigbits[1] &= ~set->__sigbits[1]; self->ul_sigmask.__sigbits[2] &= ~set->__sigbits[2]; self->ul_sigmask.__sigbits[3] &= ~set->__sigbits[3]; break; case SIG_SETMASK: self->ul_sigmask.__sigbits[0] = set->__sigbits[0]; self->ul_sigmask.__sigbits[1] = set->__sigbits[1]; self->ul_sigmask.__sigbits[2] = set->__sigbits[2]; self->ul_sigmask.__sigbits[3] = set->__sigbits[3]; break; } delete_reserved_signals(&self->ul_sigmask); if (oset != NULL) *oset = saveset; restore_signals(self); } return (0); }
/* TODO: Unblock all threads waiting on c */ void condition_broadcast(condition_t * c){ // disable int enter_critical(); // wake up unblock_all(&c->blocked); // enable int leave_critical(); }
/* TODO: Block until all n threads have called barrier_wait */ void barrier_wait(barrier_t * b){ enter_critical(); if(--b->num_left == 0) { unblock_all(&b->wait_queue); b->num_left = b->num_start; } else block(&b->wait_queue); leave_critical(); }
pid_t do_getpid() { pid_t pid; enter_critical(); pid = current_running->pid; leave_critical(); return pid; }
priority_t do_getpriority() { priority_t priority; enter_critical(); priority = current_running->priority; leave_critical(); return priority; }
/* TODO: Unblock the first thread waiting on c, if it exists */ void condition_signal(condition_t * c){ // disable int enter_critical(); // wake up unblock_one(&c->blocked); // enable int leave_critical(); }
/* Block until the semaphore value is greater than zero and decrement it */ void semaphore_down(semaphore_t * s) { enter_critical(); if( s->value < 1 ) block( &s->wait_queue ); else s->value--; leave_critical(); }
/* Increment the semaphore value atomically */ void semaphore_up(semaphore_t * s) { enter_critical(); if(s->value < 1 && !queue_empty(&s->wait_queue)) unblock_one(&s->wait_queue); else s->value++; leave_critical(); }
void STMPE_req_read_adc(u8_t adc, adc_cb_f fn) { enter_critical(); bool do_req = stmpe.req_mask == 0; stmpe.adc_chan = adc; stmpe.req_mask |= STMPE_REQ_ADC; stmpe.adc_cb = fn; if (do_req) { stmpe_exe_req(); } exit_critical(); }
/* * Remove the current_running process from the linked list so it will * not be scheduled in the future */ void exit(void) { enter_critical(); current_running->status = EXITED; /* Removes job from ready queue, and dispatchs next job to run */ scheduler_entry(); /* * No leave_critical() needed, as we never return here. (The * process is exiting!) */ }
void STMPE_req_gpio_set(u8_t set, u8_t reset) { enter_critical(); bool do_req = stmpe.req_mask == 0; stmpe.gpio_set |= set; stmpe.gpio_reset |= reset; stmpe.req_mask |= STMPE_REQ_GPIO; if (do_req) { stmpe_exe_req(); } exit_critical(); }
/* TODO: Block until all n threads have called barrier_wait */ void barrier_wait(barrier_t * b){ enter_critical(); if (++b->curr < b->n) { block(&b->wait_queue); } else { unblock_all(&b->wait_queue); b->curr = 0; } leave_critical(); }
/* Change current_running to the next task */ void scheduler(){ ASSERT(disable_count); check_sleeping(); // wake up sleeping processes while (is_empty(&ready_queue)){ leave_critical(); enter_critical(); check_sleeping(); } current_running = (pcb_t *) dequeue(&ready_queue); ASSERT(NULL != current_running); ++current_running->entry_count; }
/**********************************************************************//** * \brief MCLK, SMCLK, and ACLK Init Routine * * This function uses REFO (the internal reference oscillator) to initialize * the DCO to the value targetFreq * * \retval -1 The clock initialization failed * \retval 0 The clock initialization was successful * *************************************************************************/ int clkInit(void) { unsigned int state; long retval; enter_critical(state); retval = setFLL(DCO_FREQ); exit_critical(state); if(retval != -1) retval = 0; return (int)retval; }
/* Release m and block the thread (enqueued on c). When unblocked, reacquire m */ void condition_wait(lock_t * m, condition_t * c) { enter_critical(); lock_release_helper(m); ASSERT(disable_count); block( &c->wait_queue ); lock_acquire_helper(m); leave_critical(); }
/*********************************************************** *功能: 初始化调试功能 *形参: * 无 *返回: * 无 */ void InitDebug(void) { //Initbutten(); //按键 //oled enter_critical(); OLED_Init(); exit_critical(); //串口 uart_init(Debug_UARTx, 115200); uart_irq_EN(Debug_UARTx); gpio_Interrupt_init(DEBUG_PIN, GPI_UP_PF, GPI_DISAB); }
void spin_lock_irqsave(spin_lock_t *lock, unsigned long *flags) { enter_critical(flags); #ifdef CONFIG_SMP do { if (!lock->value) { lock->value = 1; lock->cpu = get_cpu_id(); break; } } while (1); #endif }