int mm_buddy_alloc(Buddy *buddy, size_t page_nr) { int level = _mm_buddy_get_level(page_nr); if (!list_size(buddy->head + level)) { int t_level = level - 1; while (t_level && !list_size(buddy->head + t_level)) { --t_level; } if (!t_level && !list_size(buddy->head)) return MM_INVALID_PAGE; while (t_level != level) { LinkedNode *node = list_unlink(list_head(buddy->head + t_level)); BuddyNode *b_node = list_get(node, BuddyNode, _link); int index = b_node - buddy->tree; list_append(buddy->head + t_level + 1, &buddy->tree[(index << 1)]._link); list_append(buddy->head + t_level + 1, &buddy->tree[(index << 1) + 1]._link); ++t_level; } } LinkedNode *node = list_unlink(list_head(buddy->head + level)); BuddyNode *b_node = list_get(node, BuddyNode, _link); int index = b_node - buddy->tree; int page = _mm_buddy_get_page_from_index(index); buddy->tree[page + (1 << (MM_BUDDY_SHIFT))].padding = level; buddy->free_nr -= (1 << (MM_BUDDY_SHIFT - level)); return page; }
static bool rr_cache_handler(struct dnsrr *rr, void *arg) { struct sip_request *req = arg; switch (rr->type) { case DNS_TYPE_A: if (!sip_transp_supported(req->sip, req->tp, AF_INET)) break; list_unlink(&rr->le_priv); list_append(&req->cachel, &rr->le_priv, rr); break; #ifdef HAVE_INET6 case DNS_TYPE_AAAA: if (!sip_transp_supported(req->sip, req->tp, AF_INET6)) break; list_unlink(&rr->le_priv); list_append(&req->cachel, &rr->le_priv, rr); break; #endif case DNS_TYPE_CNAME: list_unlink(&rr->le_priv); list_append(&req->cachel, &rr->le_priv, rr); break; } return false; }
/** * Get a frame from the pool */ static void frame_alloc(struct jbuf *jb, struct frame **f) { struct le *le; le = jb->pooll.head; if (le) { list_unlink(le); ++jb->n; } else { struct frame *f0; /* Steal an old frame */ le = jb->framel.head; f0 = le->data; STAT_INC(n_overflow); DEBUG_INFO("drop 1 old frame seq=%u (total dropped %u)\n", f0->hdr.seq, jb->stat.n_overflow); f0->mem = mem_deref(f0->mem); list_unlink(le); } *f = le->data; }
void proc_schedule() { Process *proc_to_run = NULL; if (list_size(&proc_realtime_queue)) { proc_to_run = list_get(list_head(&proc_realtime_queue), Process, _link); } else if (list_size(&proc_normal_queue)) { if (list_from_node(¤t_process->_link) == &proc_normal_queue && list_next(¤t_process->_link)) { proc_to_run = list_get(list_next(¤t_process->_link), Process, _link); } else { proc_to_run = list_get(list_head(&proc_normal_queue), Process, _link); } // if process run out of ticks, move it to no-ticks queue if (!--(proc_to_run->ticks)) { list_append(&proc_normal_noticks_queue, list_unlink(&proc_to_run->_link)); } } else if (list_size(&proc_normal_noticks_queue)) { while (list_size(&proc_normal_noticks_queue)) { Process *proc = list_get(list_unlink(list_head(&proc_normal_noticks_queue)), Process, _link); proc->ticks = proc->priv_base + proc->priv_offset; list_append(&proc_normal_queue, &proc->_link); } proc_to_run = list_get(list_head(&proc_normal_queue), Process, _link); // if process run out of ticks, move it to no-ticks queue if (!--(proc_to_run->ticks)) { list_append(&proc_normal_noticks_queue, list_unlink(&proc_to_run->_link)); } } else { if (list_from_node(¤t_process->_link) == &proc_zero_queue && list_next(¤t_process->_link)) { proc_to_run = list_get(list_next(¤t_process->_link), Process, _link); } else { proc_to_run = list_get(list_head(&proc_zero_queue), Process, _link); } } assert(proc_to_run); if (current_process != proc_to_run) { kprintf("schedule to 0x%x %s\n", proc_to_run->id, proc_to_run->name); } if (current_process->state == PS_RUNNING) { current_process->state = PS_READY; } mm_set_page_table(&proc_to_run->mm); current_process = proc_to_run; current_process->state = PS_RUNNING; }
static int request_next(struct sip_request *req) { struct dnsrr *rr; struct sa dst; int err; again: rr = list_ledata(req->addrl.head); if (!rr) { rr = list_ledata(req->srvl.head); if (!rr) return ENOENT; req->port = rr->rdata.srv.port; dns_rrlist_apply2(&req->cachel, rr->rdata.srv.target, DNS_TYPE_A, DNS_TYPE_AAAA, DNS_CLASS_IN, true, rr_append_handler, &req->addrl); list_unlink(&rr->le); if (req->addrl.head) { mem_deref(rr); goto again; } err = addr_lookup(req, rr->rdata.srv.target); mem_deref(rr); return err; } switch (rr->type) { case DNS_TYPE_A: sa_set_in(&dst, rr->rdata.a.addr, req->port); break; case DNS_TYPE_AAAA: sa_set_in6(&dst, rr->rdata.aaaa.addr, req->port); break; default: return EINVAL; } list_unlink(&rr->le); mem_deref(rr); err = request(req, req->tp, &dst); if (err) { if (req->addrl.head || req->srvl.head) goto again; } return err; }
/** * Sort a linked list in an order defined by the sort handler * * @param list Linked list * @param sh Sort handler * @param arg Handler argument */ void list_sort(struct list *list, list_sort_h *sh, void *arg) { struct le *le; bool sort; if (!list || !sh) return; retry: le = list->head; sort = false; while (le && le->next) { if (sh(le, le->next, arg)) { le = le->next; } else { struct le *tle = le->next; list_unlink(le); list_insert_after(list, tle, le, le->data); sort = true; } } if (sort) { goto retry; } }
/** * Enable/disable vidmix source * * @param src Video mixer source * @param enable True to enable, false to disable */ void vidmix_source_enable(struct vidmix_source *src, bool enable) { if (!src) return; if (src->le.list && enable) return; if (!src->le.list && !enable) return; pthread_rwlock_wrlock(&src->mix->rwlock); if (enable) { if (src->frame_rx) clear_frame(src->frame_rx); list_append(&src->mix->srcl, &src->le, src); } else { list_unlink(&src->le); } clear_all(src->mix); pthread_rwlock_unlock(&src->mix->rwlock); }
static void destructor(void *arg) { struct bfcp_ctrans *ct = arg; list_unlink(&ct->le); tmr_cancel(&ct->tmr); }
static void qent_destructor(void *arg) { struct tcp_qent *qe = arg; list_unlink(&qe->le); mem_deref(qe->mb.buf); }
void location_commit(struct list *locl) { time_t now = time(NULL); struct le *le; if (!locl) return; for (le=locl->head; le; ) { struct location *loc = le->data; le = le->next; if (loc->rm) { list_unlink(&loc->le); mem_deref(loc); } else if (loc->tmp) { mem_deref(loc->uri); mem_deref(loc->callid); loc->uri = mem_ref(loc->tmp->uri); loc->callid = mem_ref(loc->tmp->callid); loc->duri = loc->tmp->duri; loc->cseq = loc->tmp->cseq; loc->expires = loc->tmp->expires + now; loc->src = loc->tmp->src; loc->q = loc->tmp->q; loc->tmp = mem_deref(loc->tmp); } } }
static void call_destructor(void *arg) { struct call *call = arg; if (call->state != STATE_IDLE) print_summary(call); call_stream_stop(call); list_unlink(&call->le); tmr_cancel(&call->tmr_dtmf); mem_deref(call->sess); mem_deref(call->local_uri); mem_deref(call->local_name); mem_deref(call->peer_uri); mem_deref(call->peer_name); mem_deref(call->audio); #ifdef USE_VIDEO mem_deref(call->video); mem_deref(call->bfcp); #endif mem_deref(call->sdp); mem_deref(call->mnats); mem_deref(call->mencs); mem_deref(call->sub); mem_deref(call->not); mem_deref(call->acc); }
static void sess_destructor(void *arg) { struct audiosess_st *st = arg; list_unlink(&st->le); mem_deref(st->as); }
/** * Dereference a reference-counted memory object. When the reference count * is zero, the destroy handler will be called (if present) and the memory * will be freed * * @param data Memory object * * @return Always NULL */ void *mem_deref(void *data) { struct mem *m; if (!data) return NULL; m = ((struct mem *)data) - 1; MAGIC_CHECK(m); if (--m->nrefs > 0) return NULL; if (m->dh) m->dh(data); if (m->nrefs > 0) return NULL; #if MEM_DEBUG mem_lock(); list_unlink(&m->le); mem_unlock(); #endif STAT_DEREF(m); free(m); return NULL; }
static void decode_destructor(void *arg) { struct selfview_dec *st = arg; list_unlink(&st->vf.le); mem_deref(st->selfview); }
/** * Release a frame, put it back in the pool */ static void frame_deref(struct jbuf *jb, struct frame *f) { f->mem = mem_deref(f->mem); list_unlink(&f->le); list_append(&jb->pooll, &f->le, f); --jb->n; }
static void dns_server_match(struct dns_server *srv, struct list *rrl, const char *name, uint16_t type) { struct dnsrr *rr0 = NULL; struct le *le; le = srv->rrl.head; while (le) { struct dnsrr *rr = le->data; le = le->next; if (type == rr->type && 0==str_casecmp(name, rr->name)) { if (!rr0) rr0 = rr; list_append(rrl, &rr->le_priv, rr); } } /* If rotation is enabled, then rotate multiple entries in a deterministic way (no randomness please) */ if (srv->rotate && rr0) { list_unlink(&rr0->le); list_append(&srv->rrl, &rr0->le, rr0); } }
static void dec_destructor(void *arg) { struct dec_st *st = arg; list_unlink(&st->af.le); mem_deref(st->st); }
static void destructor(void *arg) { struct mwi *mwi = arg; list_unlink(&mwi->le); mem_deref(mwi->sub); }
void xml_detach ( XML_ITEM *item) { item-> parent = NULL; list_unlink (item); }
/** * Unregister a Video Filter * * @param vf Video Filter to unregister */ void vidfilt_unregister(struct vidfilt *vf) { if (!vf) return; list_unlink(&vf->le); }
/* Return a thread structure to the global free list. Global lock must be held by caller. */ void __timer_thread_dealloc (struct thread_node *thread) { thread_deinit (thread); list_unlink (&thread->links); list_append (&thread_free_list, &thread->links); }
static void hdr_destructor(void *arg) { struct sip_hdr *hdr = arg; list_unlink(&hdr->le); hash_unlink(&hdr->he); }
static void destructor(void *arg) { struct sip_request *req = arg; if (req->reqp && req->stateful) { /* user does deref before request has completed */ *req->reqp = NULL; req->reqp = NULL; req->sendh = NULL; req->resph = NULL; sip_request_cancel(mem_ref(req)); return; } list_flush(&req->cachel); list_flush(&req->addrl); list_flush(&req->srvl); list_unlink(&req->le); mem_deref(req->dnsq); mem_deref(req->dnsq2); mem_deref(req->ct); mem_deref(req->met); mem_deref(req->uri); mem_deref(req->host); mem_deref(req->mb); }
static bool tcpconn_fail_handler(struct le *le, void *arg) { struct dns_query *q = le->data; int err = *((int *)arg); list_unlink(&q->le_tc); q->tc = mem_deref(q->tc); if (q->ntx >= *q->srvc) { DEBUG_WARNING("all servers failed, giving up!!\n"); err = err ? err : ECONNREFUSED; goto out; } /* try next server(s) */ err = send_tcp(q); if (err) { DEBUG_WARNING("all servers failed, giving up\n"); goto out; } out: if (err) { query_handler(q, err, NULL, NULL, NULL, NULL); mem_deref(q); } return false; }
static void flow_destructor(void *arg) { struct flow *flow = arg; struct call *call = flow->call; info("flowmgr(%p): call(%p): flow(%p -- %s) destructor\n", call->fm, call, flow, flow->flowid); flow->cp = mem_deref(flow->cp); call_remove_conf_part(call, flow); delete_flow(flow); list_unlink(&flow->le); release_mediaflow(flow); flow->flowid = mem_deref(flow->flowid); flow->remoteid = mem_deref(flow->remoteid); if (flow->userflow) { userflow_set_flow(flow->userflow, NULL); dict_remove(call->users, flow->userflow->userid); flow->userflow = mem_deref(flow->userflow); } list_flush(&flow->pendingl); }
static void destructor(void *arg) { struct udp_lstnr *ul = arg; list_unlink(&ul->le); mem_deref(ul->us); }
void restund_log_unregister_handler(struct restund_log *log) { if (!log) return; list_unlink(&log->le); }
unsigned int cron_add(CronTimeType type, double seconds, int (*handler)(void *data), void *data) { Job *j; List *id; if(type > 2) return 0; if(handler == NULL) return 0; j = memchunk_alloc(cron_info.chunk_job); if((id = cron_info.id_reuse) != NULL) { j->id = (unsigned int) list_data(id); cron_info.id_reuse = list_unlink(cron_info.id_reuse, cron_info.id_reuse); } else j->id = cron_info.id_next++; j->handler = handler; j->data = data; if(type == CRON_ONESHOT) { timeval_future(&j->when.oneshot, seconds); cron_info.oneshot = list_append(cron_info.oneshot, j); } else if(type == CRON_PERIODIC || type == CRON_PERIODIC_SOON) { j->id = PERIODIC_SET(j->id); j->when.periodic.period = seconds; j->when.periodic.bucket = type == CRON_PERIODIC_SOON ? seconds - 0.5 : 0.0; cron_info.periodic = list_append(cron_info.periodic, j); } return j->id; }
static void destructor(void *arg) { struct ausrc *as = arg; list_flush(&as->dev_list); list_unlink(&as->le); }
/** * Poll all timers in the current thread * * @param tmrl Timer list */ void tmr_poll(struct list *tmrl) { const uint64_t jfs = tmr_jiffies(); for (;;) { struct tmr *tmr; tmr_h *th; void *th_arg; tmr = list_ledata(tmrl->head); if (!tmr || (tmr->jfs > jfs)) { break; } th = tmr->th; th_arg = tmr->arg; tmr->th = NULL; list_unlink(&tmr->le); if (!th) continue; #if TMR_DEBUG call_handler(th, th_arg); #else th(th_arg); #endif } }