void exit_kitchen() { // Reacquire entrance lock lock_acquire(k->kitchen_lock); // Decrement count k->creature_count--; /* * If there are no creatures left, let in the next group waiting. * If there is no other group waiting, reset the switch that * indicates which creature type currently owns the kitchen. */ if (!q_empty(k->group_list) && k->creature_count == 0) { // Dequeue first group in line struct kgroup *g = q_remhead(k->group_list); int i; // Signal every member of that group for (i = 0; i < g->amount; i++) { cv_signal(k->kitchen_cv, k->kitchen_lock); } // Destroy the group struct kfree(g); } else if (q_empty(k->group_list) && k->creature_count == 0) { // 2 is the "unset" value for k->current_creature k->current_creature = 2; } // Release enter lock and exit lock_release(k->kitchen_lock); }
static void testq(struct queue *q, int n) { int i, result, *x, *r; x = kmalloc(n * sizeof(int)); for (i=0; i<n; i++) { x[i] = i; } assert(q_empty(q)); for (i=0; i<n; i++) { kprintf("queue: adding %d\n", i); result = q_addtail(q, &x[i]); assert(result==0); } for (i=0; i<n; i++) { r = q_remhead(q); assert(r != NULL); kprintf("queue: got %d, should be %d\n", *r, i); assert(*r == i); } assert(q_empty(q)); kfree(x); }
/* Finite bounded queue management functions q_get, q_put timeouts (max_wait) are in ms - convert to sec, rounding up */ unsigned int q_get (queue_t *q, void * msg, unsigned int msize, unsigned int MaxWait) { int tstatus = 0, got_msg = 0, time_inc = (MaxWait + 999) /1000; struct timespec timeout; timeout.tv_nsec = 0; if (q_destroyed(q)) return 1; pthread_mutex_lock (&q->q_guard); while (q_empty (q) && 0 == tstatus) { if (MaxWait != INFINITE) { timeout.tv_sec = time(NULL) + time_inc; tstatus = pthread_cond_timedwait (&q->q_ne, &q->q_guard, &timeout); } else { tstatus = pthread_cond_wait (&q->q_ne, &q->q_guard); } } /* remove the message, if any, from the queue */ if (0 == tstatus && !q_empty (q)) { q_remove (q, msg, msize); got_msg = 1; /* Signal that the queue is not full as we've removed a message */ pthread_cond_broadcast (&q->q_nf); } pthread_mutex_unlock (&q->q_guard); return (0 == tstatus && got_msg == 1 ? 0 : max(1, tstatus)); /* 0 indicates success */ }
void kitchen_destroy(struct kitchen *k) { int i; // Destroy the queue elements while (!q_empty(k->group_list)) { kfree(q_remhead(k->group_list)); } // Destroy the queue q_destroy(k->group_list); // Destroy the cv cv_destroy(k->kitchen_cv); // Destroy the entrance lock lock_destroy(k->kitchen_lock); // Destroy the bowl locks for (i = 0; i < NumBowls; i++) { lock_destroy(k->bowl_locks[i]); } // Destroy the bowl lock array kfree(k->bowl_locks); // Destroy the kitchen kfree(k); // Clear the pointer k = NULL; }
void mpipe_rxndef(ot_u8* data, ot_bool blocking, mpipe_priority data_priority) { #if (MPIPE_USE_ACKS) if (data_priority == MPIPE_Ack) { mpipe.priority = data_priority; goto mpipe_rxndef_SETUP; } #endif if (blocking) { mpipe_wait(); } if (mpipe.state == MPIPE_Idle) { //mpipe.state = MPIPE_Idle; mpipe_rxndef_SETUP: MPIPE_DMAEN(OFF); # if (MPIPE_DMANUM == 0) DMA->CTL0 |= MPIPE_UART_RXTRIG; # elif (MPIPE_DMANUM == 1) DMA->CTL0 |= (MPIPE_UART_RXTRIG << 8); # elif (MPIPE_DMANUM == 2) DMA->CTL1 = MPIPE_UART_RXTRIG; # endif DMA->CTL4 = ( DMA_Options_RMWDisable | \ DMA_Options_RoundRobinDisable | \ DMA_Options_ENMIEnable ); q_empty(mpipe_alp.inq); MPIPE_DMA_RXCONFIG(mpipe_alp.inq->front, 10, ON); UART_OPEN(); UART_CLEAR_RXIFG(); } }
void cv_signal(struct cv *cv, struct lock *lock) { #if opt_A1 // validate parameter assert (cv != NULL); assert (lock != NULL); // others assert (lock_do_i_hold(lock) == 1); // disable interrupts int spl = splhigh(); if (q_empty(cv->sleeping_list)) goto done; // signal must be called after wait! // pick one thread and wake it up thread_wakeup((struct thread*) q_remhead(cv->sleeping_list)); // enable interrupts done: splx(spl); #else (void) cv; (void) lock; #endif }
void q_destroy(struct queue *q) { assert(q_empty(q)); kfree(q->data); kfree(q); }
void print_oplist (void) { int i; struct q_elem *qe; // traverse through every table for(i=0; i<__TABLE_SIZE; ++i) { printf("%d : ", i); if (!q_empty(&oplist[i])) { qe = q_begin (&oplist[i]); struct op_elem *oe = q_entry (qe, struct op_elem, elem); printf ("[%s:%02X] ", oe->opcode, oe->code); for(qe = q_next(qe); qe != q_end(&oplist[i]); qe = q_next(qe)) { oe = q_entry (qe, struct op_elem, elem); printf ("-> [%s:%02X] ", oe->opcode, oe->code); } } puts(""); }
void mpipe_rxndef(ot_u8* data, ot_bool blocking, mpipe_priority data_priority) { #if (MPIPE_USE_ACKS) if (data_priority == MPIPE_Ack) { mpipe.priority = data_priority; goto mpipe_rxndef_SETUP; } #endif if (blocking) { mpipe_wait(); } if (mpipe.state == MPIPE_Idle) { //mpipe.state = MPIPE_Idle; mpipe_rxndef_SETUP: MPIPE_DMAEN(OFF); # if (MPIPE_DMANUM == 0) DMA->CTL0 |= MPIPE_UART_RXTRIG; # elif (MPIPE_DMANUM == 1) DMA->CTL0 |= (MPIPE_UART_RXTRIG << 8); # elif (MPIPE_DMANUM == 2) DMA->CTL1 = MPIPE_UART_RXTRIG; # endif q_empty(mpipe_alp.inq); //mpipe_alp.inq->back -=10; MPIPE_DMA_RXCONFIG(mpipe_alp.inq->front, 6, ON); UART_OPEN(); UART_CLEAR_RXIFG(); } }
void q_destroy(struct queue *q) { KASSERT(q_empty(q)); kfree(q->data); kfree(q); }
// removes all trailing whitespaces struct queue * save_file (const char *filename) { if (!is_file(filename)) return NULL; struct queue *q = malloc (sizeof (struct queue)); if (q == NULL) return NULL; q_init (q); FILE *fp = fopen(filename, "r"); char buf[128]; int i; while (fgets(buf, 128, fp) != NULL) { // cut all trailing whitespace for (i=strlen(buf) - 1; i >= 0; --i) { if (buf[i] == ' ' || buf[i] == '\t' || buf[i] == '\n') buf[i] = '\0'; else break; } // do not save empty line when whitespace is deleted if (strlen(buf) == 0) continue; struct str_elem *se = malloc (sizeof(struct str_elem)); char *line = malloc ((strlen(buf)+1) * sizeof(char)); if (se == NULL || line == NULL) { if (se != NULL) free (se); if (line != NULL) free (line); while (!q_empty (q)) { struct q_elem *e = q_delete(q); se = q_entry (e, struct str_elem, elem); if (se->line != NULL) free(se->line); free(se); } free (q); puts("[FILEIO] MEMORY INSUFFICIENT"); return NULL; } strcpy (line, buf); se->line = line; q_insert (q, &se->elem); } fclose(fp); return q; }
void free_oplist (void) { if (oplist == NULL) return; int i = 0; for(i=0; i<__TABLE_SIZE; ++i) { while(!q_empty(&oplist[i])) { struct q_elem *e = q_delete(&oplist[i]); struct op_elem *oe = q_entry(e, struct op_elem, elem); if (oe->opcode != NULL) free(oe->opcode); free(oe); } } free (oplist); oplist = NULL; if (optype != NULL) { free (optype); optype = NULL; } }
int kframe_alloc(int *frame, int frames_wanted) { int rv, id; static int id_cur = 0; // only acquire lock and initialize idgen AFTER booting -- due to kmalloc if (booting){ id = id_cur++; } else { lock_acquire(coremap_lock); if (!q_empty(id_not_used)){ id = (int) q_remhead(id_not_used); } else { id = id_cur++; } } rv = frame_alloc_continuous(frame, KERNEL, 0, id, frames_wanted); if (rv && id_not_used != NULL) { q_addtail(id_not_used, (void*)id); } if (!booting) lock_release(coremap_lock); return rv; }
void logger_header(ot_u8 id_subcode, ot_int payload_length) { ot_u8 header[] = { 0xDD, 0x00, 0, 0x02, 0x04, 0 }; header[2] = (ot_u8)payload_length; header[5] = id_subcode; q_empty(&otmpout); // output buffer q_writestring(&otmpout, header, 6); }
/* * This is called during panic shutdown to dispose of threads other * than the one invoking panic. We drop them on the floor instead of * cleaning them up properly; since we're about to go down it doesn't * really matter, and freeing everything might cause further panics. */ void scheduler_killall(void) { assert(curspl>0); while (!q_empty(runqueue)) { struct thread *t = q_remhead(runqueue); kprintf("scheduler: Dropping thread %s.\n", t->t_name); } }
/* * This is called during panic shutdown to dispose of threads other * than the one invoking panic. We drop them on the floor instead of * cleaning them up properly; since we're about to go down it doesn't * really matter, and freeing everything might cause further panics. */ void scheduler_killall(void) { // panic("not used."); assert(curspl>0); while (!q_empty(runqueue)) { struct thread *t = q_remhead(runqueue); kprintf("scheduler: Dropping thread.\n"); } }
void * q_remhead(struct queue *q) { void *ret; KASSERT(q->size > 0); KASSERT(!q_empty(q)); ret = q->data[q->nextread]; q->nextread = (q->nextread+1)%q->size; return ret; }
uint8_t* q_start(ot_queue* q, int offset, uint16_t options) { q_empty(q); if (offset >= q->alloc) return NULL; q->options = options; //#q->length = offset; q->putcursor += offset; q->getcursor += offset; return q->getcursor; }
ot_u8* q_start(ot_queue* q, ot_uint offset, ot_u16 options) { q_empty(q); if (offset >= q->alloc) return NULL; q->length = offset; q->options.ushort = options; q->putcursor += offset; q->getcursor += offset; return q->getcursor; }
void* consumer() { int res; pthread_mutex_lock(&m); while(!over || ! q_empty()) { pthread_mutex_unlock(&m); // ... pthread_mutex_lock(&m); while(q_empty()) { pthread_cond_wait(&c, &m); } res = dequeue(); pthread_mutex_unlock(&m); // do something with the result printf("res : %d\n", res); } }
void mpipedrv_rxndef(ot_bool blocking, mpipe_priority data_priority) { /// @note Using blocking: OpenTag currently does not implement blocking for RX. /// However, RX typically is called automatically after TX, so the system /// goes into RX (listening) whenever it is not in TX. if (blocking) { mpipedrv_wait(); } if (mpipe.state == MPIPE_Idle) { q_empty(mpipe.alp.inq); usbcdc_rxdata(mpipe.alp.inq->front, 6, CDC0_INTFNUM); } }
/* Pair : row,column */ int lee_algo(Pair* source, Pair* target){ int i, j, v1, v2; Pair p, v, step[4] = {{1,0},{0,1},{-1,0},{0,-1}}; /* initialize all cells like unvisited */ for(i=0; i<sz.r; ++i){ for(j=0; j<sz.c; ++j){ W[i][j] = -1; } } q_clear(); p_set(W,source,0); q_push(source); while(!q_empty()){ p = q_pop(); for(i=0; i<4; ++i){ v = p_sum(step+i,&p); v1 = p_get(Z,&p); v2 = p_get(Z,&v); #ifdef DEBUG printf("try: %d,%d\n",v.r,v.c); #endif if(p_in(&v) && p_get(W,&v)==-1 && (v1-v2 <= 3) && (v1-v2 >= -1) && can_go(&v)){ #ifdef DEBUG printf("from: %d,%d go: %d,%d\n",p.r,p.c,v.r,v.c); #endif p_set(W,&v,p_get(W,&p)+1); q_push(&v); if(p_eq(&v,target)) break; } } if(p_eq(&v,target)) break; } #ifdef DEBUG printf("q: %d\n",q_empty()); #endif return p_get(W,target); }
void scheduler_killall(void) { int i; assert(curspl>0); for(i = 0; i < NUM_PRIORITIES; i++) { while (!q_empty(runqueue[i])) { struct thread *t = q_remhead(runqueue[i]); kprintf("scheduler: Dropping thread %s.\n", t->t_name); } } }
QUEUE_BASE_T q_pop(queue_t *q) { // take the last thing that was put on if (q_empty(q)) { return NULL; } else { QUEUE_BASE_T old = q->buffer[q->last]; q->ct--; q->last--; if ( q->last > 0) q->last = q->len; return old; } }
void free_file (struct queue *file) { if (file == NULL) return; while (!q_empty (file)) { struct q_elem *e = q_delete (file); struct str_elem *se = q_entry (e, struct str_elem, elem); if (se->line != NULL) free (se->line); free (se); } free (file); }
void cv_broadcast(struct cv *cv, struct lock *lock) { #if OPT_A1 // validate parameter assert (cv != NULL); assert (lock != NULL); // others assert (lock_do_i_hold(lock) == 1); // disable interrupts int spl = splhigh(); // test if (q_empty(cv->sleeping_list)) goto done; // wake up all threads while (!q_empty(cv->sleeping_list)) { thread_wakeup((struct thread*) q_remhead(cv->sleeping_list)); } // enable interrupts done: splx(spl); #else (void) cv; (void) lock; #endif }
void * q_peek(struct queue *q) { void *ret; KASSERT(q); KASSERT(q->size > 0); if (q_empty(q)) { ret = 0; } else { ret = q->data[q->nextread]; } return ret; }
/* User calls this to put something on the queue */ void put_on_queue(QUEUE *queue, void *value) { #ifdef SYNCHRONISE primitive_wait_for_simple_lock(&queue->lock); if (q_empty(queue)) { primitive_release_all_notification(&queue->notification, &queue->lock); } #endif q_push(queue, value); #ifdef SYNCHRONISE primitive_release_simple_lock(&queue->lock); #endif }
} END_TEST START_TEST (multiple_items) { Job job1, job2; Queue *q = new_queue(); assert_not_null(q); q_enqueue(q, &job1); q_enqueue(q, &job2); assert_false(q_empty(q)); Job *d_job1 = q_dequeue(q); Job *d_job2 = q_dequeue(q); assert_equal(&job1, d_job1); assert_equal(&job2, d_job2); free_queue(q); } END_TEST
void cv_destroy(struct cv *cv) { assert(cv != NULL); //Like locks, before we destroy, we want to ensure there is no one waiting or in the queue. assert(cv->count == 0); // no resources left! assert(q_empty(cv->thread_queue)); //make sure the queue is empty //If those pass, we destroy the queue! q_destroy(cv->thread_queue); kfree(cv->name); kfree(cv); cv = NULL; //set the pointer to null just in case }