static void test_queue_remove_last_item(void) { TEST_ASSERT_EQUAL(QUEUE_SUCESS, queue_last(priv_test_queue)); TEST_ASSERT_EQUAL(QUEUE_SUCESS, queue_remove_current(priv_test_queue)); TEST_ASSERT_EQUAL(QUEUE_EMPTY, queue_last(priv_test_queue)); TEST_ASSERT_EQUAL(QUEUE_EMPTY, queue_remove_current(priv_test_queue)); }
static void test_queue_empty(void) { TEST_ASSERT_EQUAL(QUEUE_EMPTY, queue_first(priv_test_queue)); TEST_ASSERT_EQUAL(QUEUE_LAST, queue_next(priv_test_queue)); TEST_ASSERT_EQUAL(QUEUE_EMPTY, queue_last(priv_test_queue)); TEST_ASSERT_EQUAL(QUEUE_LAST, queue_previous(priv_test_queue)); }
static void test_queue_not_null(void) { TEST_ASSERT_NOT_EQUAL(QUEUE_NULL, queue_first(priv_test_queue)); TEST_ASSERT_NOT_EQUAL(QUEUE_NULL, queue_next(priv_test_queue)); TEST_ASSERT_NOT_EQUAL(QUEUE_NULL, queue_last(priv_test_queue)); TEST_ASSERT_NOT_EQUAL(QUEUE_NULL, queue_previous(priv_test_queue)); }
static void test_queue_null(void) { TEST_ASSERT_EQUAL(QUEUE_NULL, queue_first(priv_test_queue)); TEST_ASSERT_EQUAL(QUEUE_NULL, queue_next(priv_test_queue)); TEST_ASSERT_EQUAL(QUEUE_NULL, queue_last(priv_test_queue)); TEST_ASSERT_EQUAL(QUEUE_NULL, queue_previous(priv_test_queue)); TEST_ASSERT_EQUAL(QUEUE_NULL, queue_push(priv_test_queue, (void*) 1001u)); TEST_ASSERT_EQUAL(NULL, queue_pop(priv_test_queue)); TEST_ASSERT_EQUAL(NULL, queue_get_current(priv_test_queue)); TEST_ASSERT_EQUAL(QUEUE_NULL, queue_remove_current(priv_test_queue)); }
/* some diagnostics */ static void jb_dbginfo(jitterbuf *jb) { if (dbgf == NULL) return; jb_dbg("\njb info: fin=%ld fout=%ld flate=%ld flost=%ld fdrop=%ld fcur=%ld\n", jb->info.frames_in, jb->info.frames_out, jb->info.frames_late, jb->info.frames_lost, jb->info.frames_dropped, jb->info.frames_cur); jb_dbg("jitter=%ld current=%ld target=%ld min=%ld sil=%d len=%d len/fcur=%ld\n", jb->info.jitter, jb->info.current, jb->info.target, jb->info.min, jb->info.silence_begin_ts, jb->info.current - jb->info.min, jb->info.frames_cur ? (jb->info.current - jb->info.min)/jb->info.frames_cur : -8); if (jb->info.frames_in > 0) jb_dbg("jb info: Loss PCT = %ld%%, Late PCT = %ld%%\n", jb->info.frames_lost * 100/(jb->info.frames_in + jb->info.frames_lost), jb->info.frames_late * 100/jb->info.frames_in); jb_dbg("jb info: queue %d -> %d. last_ts %d (queue len: %d) last_ms %d\n", queue_next(jb), queue_last(jb), jb->info.next_voice_ts, queue_last(jb) - queue_next(jb), jb->info.last_voice_ms); }
static uvc_ctx *channel_queue_get(queue_t *q){ queue_t *node = NULL; node = queue_last(q); queue_remove(node); /*is selected*/ if (node->ext == NULL){ return queue_data(node, uvc_ctx, i_node); } else{ return (uvc_ctx *)node->ext; } }
/*! * Internal function which searches for an data item from the queue. * * \param this_ptr - A pointer to the queue. * \param key - A unique key which identifies the data item. * * \return If it was successful return the data item, * otherwise return \c NULL. */ static void * hash_lookup_queue_find(queue_t *this_ptr, unsigned int key) { hash_data_t *current; data_t *data = NULL; queue_first(this_ptr); while ((current = queue_get_current(this_ptr)) != NULL) { if (current->key == key) { data = current->data; queue_last(this_ptr); } queue_next(this_ptr); } return data; }
//! Place data to cache - find or reuse entry as needed static errno_t cache_do_write( cache_t *c, long blk, const void *data ) { assert(!queue_empty(&c->lru)); errno_t ret = 0; hal_mutex_lock( &c->lock ); cache_el_t * el = cache_do_find( c, blk ); if( el == 0 ) { el = (cache_el_t *)queue_last(&c->lru); // if valid and dirty - must flush! hash_remove( c->hash, el ); el->valid = 1; el->blk = blk; assert(!hash_insert( c->hash, el)); SHOW_FLOW( 10, "Cache w miss blk %ld", blk ); } else { assert(el->valid); assert(el->blk == blk); SHOW_FLOW( 9, "Cache w _HIT_ blk %ld", blk ); } el->dirty = 1; // remove queue_remove( &c->lru, el, cache_el_t *, lru ); // insert at start queue_enter_first( &c->lru, el, cache_el_t *, lru ); memcpy( el->data, data, c->page_size ); //done: hal_mutex_unlock( &c->lock ); return ret; }
void uvc_schedule(){ uvc_ctx *ctx; queue_t *node; uvc_thread_env *env; env = uvc_get_env(); for (;;){ if (!queue_empty(&env->ready_queue) ){ node = queue_last(&env->ready_queue); queue_remove( node); ctx = queue_data(node, uvc_ctx, task_node); } else{ //只有当没有ready任务时才运行uvloop if (env->uv_task){ ctx = env->uv_task; } else{ printf("no task need run ,exit\n"); exit(0); } } if (ctx != NULL){ env->runing_task = ctx; ctx->status = UVC_STATUS_RUNING; //printf("task[%s] runing\n",ctx->name); uvc_resume(ctx); //printf("task[%s] stoping\n",ctx->name); } if (ctx->status == UVC_STATUS_DIE){ coro_stack_free(&ctx->stack); free(ctx); }else{ ctx->status = UVC_STATUS_PENDING; } } }
int httproute_call(HttpSession *session) { queue_t *route_queue=&session->server->routes; char *path=session->request.path; queue_t *q=NULL; HttpRoute *route; //printf("httproute_call in !\n"); if(queue_empty(route_queue))return 404; for(q = queue_prev(route_queue); q != queue_sentinel(route_queue); q = queue_last(q) ) { route = queue_data(q, HttpRoute, node); if(strcmp(path,route->path)==0 ) { TraceInfo("route callback found!\n"); return route->func(session,route->arg); } } TraceInfo("route callback not found!\n"); return 404; }
static int _jb_get(jitterbuf *jb, jb_frame *frameout, long now, long interpl) { jb_frame *frame; long diff; static int dbg_cnt = 0; /*if ((now - jb_next(jb)) > 2 * jb->info.last_voice_ms) jb_warn("SCHED: %ld", (now - jb_next(jb))); */ /* get jitter info */ history_get(jb); if (dbg_cnt && dbg_cnt % 50 == 0) { jb_dbg("\n"); } dbg_cnt++; /* target */ jb->info.target = jb->info.jitter + jb->info.min + JB_TARGET_EXTRA; /* if a hard clamp was requested, use it */ if ((jb->conf.max_jitterbuf) && ((jb->info.target - jb->info.min) > jb->conf.max_jitterbuf)) { jb_dbg("clamping target from %d to %d\n", (jb->info.target - jb->info.min), jb->conf.max_jitterbuf); jb->info.target = jb->info.min + jb->conf.max_jitterbuf; } diff = jb->info.target - jb->info.current; /* jb_warn("diff = %d lms=%d last = %d now = %d\n", diff, */ /* jb->info.last_voice_ms, jb->info.last_adjustment, now); */ /* let's work on non-silent case first */ if (!jb->info.silence_begin_ts) { /* we want to grow */ if ((diff > 0) && /* we haven't grown in the delay length */ (((jb->info.last_adjustment + JB_ADJUST_DELAY) < now) || /* we need to grow more than the "length" we have left */ (diff > queue_last(jb) - queue_next(jb)) ) ) { /* grow by interp frame length */ jb->info.current += interpl; jb->info.next_voice_ts += interpl; jb->info.last_voice_ms = interpl; jb->info.last_adjustment = now; jb->info.cnt_contig_interp++; if (jb->conf.max_contig_interp && jb->info.cnt_contig_interp >= jb->conf.max_contig_interp) { jb->info.silence_begin_ts = jb->info.next_voice_ts - jb->info.current; } jb_dbg("G"); return JB_INTERP; } frame = queue_get(jb, jb->info.next_voice_ts - jb->info.current); /* not a voice frame; just return it. */ if (frame && frame->type != JB_TYPE_VOICE) { if (frame->type == JB_TYPE_SILENCE) { jb->info.silence_begin_ts = frame->ts; jb->info.cnt_contig_interp = 0; } *frameout = *frame; jb->info.frames_out++; jb_dbg("o"); return JB_OK; } /* voice frame is later than expected */ if (frame && frame->ts + jb->info.current < jb->info.next_voice_ts) { if (frame->ts + jb->info.current > jb->info.next_voice_ts - jb->info.last_voice_ms) { /* either we interpolated past this frame in the last jb_get */ /* or the frame is still in order, but came a little too quick */ *frameout = *frame; /* reset expectation for next frame */ jb->info.next_voice_ts = frame->ts + jb->info.current + frame->ms; jb->info.frames_out++; decrement_losspct(jb); jb->info.cnt_contig_interp = 0; jb_dbg("v"); return JB_OK; } else { /* voice frame is late */ *frameout = *frame; jb->info.frames_out++; decrement_losspct(jb); jb->info.frames_late++; jb->info.frames_lost--; jb_dbg("l"); /*jb_warn("\nlate: wanted=%ld, this=%ld, next=%ld\n", jb->info.next_voice_ts - jb->info.current, frame->ts, queue_next(jb)); jb_warninfo(jb); */ return JB_DROP; } } /* keep track of frame sizes, to allow for variable sized-frames */ if (frame && frame->ms > 0) { jb->info.last_voice_ms = frame->ms; } /* we want to shrink; shrink at 1 frame / 500ms */ /* unless we don't have a frame, then shrink 1 frame */ /* every 80ms (though perhaps we can shrink even faster */ /* in this case) */ if (diff < -JB_TARGET_EXTRA && ((!frame && jb->info.last_adjustment + 80 < now) || (jb->info.last_adjustment + 500 < now))) { jb->info.last_adjustment = now; jb->info.cnt_contig_interp = 0; if (frame) { *frameout = *frame; /* shrink by frame size we're throwing out */ jb->info.current -= frame->ms; jb->info.frames_out++; decrement_losspct(jb); jb->info.frames_dropped++; jb_dbg("s"); return JB_DROP; } else { /* shrink by last_voice_ms */ jb->info.current -= jb->info.last_voice_ms; jb->info.frames_lost++; increment_losspct(jb); jb_dbg("S"); return JB_NOFRAME; } } /* lost frame */ if (!frame) { /* this is a bit of a hack for now, but if we're close to * target, and we find a missing frame, it makes sense to * grow, because the frame might just be a bit late; * otherwise, we presently get into a pattern where we return * INTERP for the lost frame, then it shows up next, and we * throw it away because it's late */ /* I've recently only been able to replicate this using * iaxclient talking to app_echo on callweaver. In this case, * my outgoing packets go through callweaver's (old) * jitterbuffer, and then might get an unusual increasing delay * there if it decides to grow?? */ /* Update: that might have been a different bug, that has been fixed.. * But, this still seemed like a good idea, except that it ended up making a single actual * lost frame get interpolated two or more times, when there was "room" to grow, so it might * be a bit of a bad idea overall */ /*if (diff > -1 * jb->info.last_voice_ms) { jb->info.current += jb->info.last_voice_ms; jb->info.last_adjustment = now; jb_warn("g"); return JB_INTERP; } */ jb->info.frames_lost++; increment_losspct(jb); jb->info.next_voice_ts += interpl; jb->info.last_voice_ms = interpl; jb->info.cnt_contig_interp++; if (jb->conf.max_contig_interp && jb->info.cnt_contig_interp >= jb->conf.max_contig_interp) { jb->info.silence_begin_ts = jb->info.next_voice_ts - jb->info.current; } jb_dbg("L"); return JB_INTERP; } /* normal case; return the frame, increment stuff */ *frameout = *frame; jb->info.next_voice_ts += frame->ms; jb->info.frames_out++; jb->info.cnt_contig_interp = 0; decrement_losspct(jb); jb_dbg("v"); return JB_OK; } else { /* TODO: after we get the non-silent case down, we'll make the * silent case -- basically, we'll just grow and shrink faster * here, plus handle next_voice_ts a bit differently */ /* to disable silent special case altogether, just uncomment this: */ /* jb->info.silence_begin_ts = 0; */ /* shrink interpl len every 10ms during silence */ if (diff < -JB_TARGET_EXTRA && jb->info.last_adjustment + 10 <= now) { jb->info.current -= interpl; jb->info.last_adjustment = now; } frame = queue_get(jb, now - jb->info.current); if (!frame) { jb_dbg("Didn't get a frame from queue\n"); return JB_NOFRAME; } else if (frame->type != JB_TYPE_VOICE) { /* normal case; in silent mode, got a non-voice frame */ *frameout = *frame; jb->info.frames_out++; return JB_OK; } if (frame->ts < jb->info.silence_begin_ts) { /* voice frame is late */ *frameout = *frame; jb->info.frames_out++; decrement_losspct(jb); jb->info.frames_late++; jb->info.frames_lost--; jb_dbg("l"); /*jb_warn("\nlate: wanted=%ld, this=%ld, next=%ld\n", jb->info.next_voice_ts - jb->info.current, frame->ts, queue_next(jb)); jb_warninfo(jb); */ return JB_DROP; } else { /* voice frame */ /* try setting current to target right away here */ jb->info.current = jb->info.target; jb->info.silence_begin_ts = 0; jb->info.next_voice_ts = frame->ts + jb->info.current + frame->ms; jb->info.last_voice_ms = frame->ms; jb->info.frames_out++; decrement_losspct(jb); *frameout = *frame; jb_dbg("V"); return JB_OK; } } }