/* * Register a command. */ void db_command_register(struct command_table *list, struct command *cmd) { struct command *c, *last; last = NULL; LIST_FOREACH(c, list, next) { int n = strcmp(cmd->name, c->name); /* Check that the command is not already present. */ if (n == 0) { printf("%s: Warning, the command \"%s\" already exists;" " ignoring request\n", __func__, cmd->name); return; } if (n < 0) { /* NB: keep list sorted lexicographically */ LIST_INSERT_BEFORE(c, cmd, next); return; } last = c; }
void Row_mvcc::insert_history( ts_t ts, row_t * row) { MVHisEntry * new_entry = get_his_entry(); new_entry->ts = ts; new_entry->row = row; if (row != NULL) whis_len ++; else rhis_len ++; MVHisEntry ** queue = (row == NULL)? &(readhis) : &(writehis); MVHisEntry ** tail = (row == NULL)? &(readhistail) : &(writehistail); MVHisEntry * his = *queue; while (his != NULL && ts < his->ts) { his = his->next; } if (his) { LIST_INSERT_BEFORE(his, new_entry,(*queue)); //if (his == *queue) // *queue = new_entry; } else LIST_PUT_TAIL((*queue), (*tail), new_entry); }
struct intrhand * intr_establish(int vector, int type, int pri, hw_ifun_t ih_fun, void *ih_arg) { struct intrhand *ih, *cur_vec; ih_list_t *vec_list; u_long *hard_vec; int s; /* no point in sleeping unless someone can free memory. */ ih = malloc(sizeof *ih, M_DEVBUF, cold ? M_NOWAIT : M_WAITOK); if (ih == NULL) panic("intr_establish: can't malloc handler info"); /* * Initialize vector info */ ih->ih_fun = ih_fun; ih->ih_arg = ih_arg; ih->ih_type = type; ih->ih_pri = pri; ih->ih_vector = vector; /* * Do some validity checking on the 'vector' argument and determine * vector list this interrupt should be on. */ switch (type & (AUTO_VEC|USER_VEC)) { case AUTO_VEC: if (vector < AVEC_MIN || vector > AVEC_MAX) { free(ih, M_DEVBUF); return NULL; } vec_list = &autovec_list[vector-1]; hard_vec = &autovects[vector-1]; ih->ih_intrcnt = &intrcnt_auto[vector-1]; break; case USER_VEC: if (vector < UVEC_MIN || vector > UVEC_MAX) { free(ih, M_DEVBUF); return NULL; } vec_list = &uservec_list[vector]; hard_vec = &uservects[vector]; ih->ih_intrcnt = &intrcnt_user[vector]; break; default: printf("%s: bogus vector type\n", __func__); free(ih, M_DEVBUF); return NULL; } /* * If the vec_list is empty, we insert ourselves at the head of the * list and we re-route the 'hard-vector' to the appropriate handler. */ if (vec_list->lh_first == NULL) { s = splhigh(); LIST_INSERT_HEAD(vec_list, ih, ih_link); if (type & FAST_VEC) *hard_vec = (u_long)ih->ih_fun; else if (*hard_vec != (u_long)intr_glue) { /* * Normally, all settable vectors are already * re-routed to the intr_glue() function. The * marvelous exception to these are the HBL/VBL * interrupts. They happen *very* often and * can't be turned off on the Falcon. So they * are normally vectored to an 'rte' instruction. */ *hard_vec = (u_long)intr_glue; } splx(s); return ih; } /* * Check for FAST_VEC botches */ cur_vec = vec_list->lh_first; if (cur_vec->ih_type & FAST_VEC) { free(ih, M_DEVBUF); printf("intr_establish: vector cannot be shared\n"); return NULL; } /* * We traverse the list and place ourselves after any handlers with * our current (or higher) priority level. */ for (cur_vec = vec_list->lh_first; cur_vec->ih_link.le_next != NULL; cur_vec = cur_vec->ih_link.le_next) { if (ih->ih_pri > cur_vec->ih_pri) { s = splhigh(); LIST_INSERT_BEFORE(cur_vec, ih, ih_link); splx(s); return ih; } } /* * We're the least important entry, it seems. We just go * on the end. */ s = splhigh(); LIST_INSERT_AFTER(cur_vec, ih, ih_link); splx(s); return ih; }
/* * Establish an interrupt handler. * Called by driver attach functions. */ void * isrlink(int (*func)(void *), void *arg, int ipl, int priority) { struct isr *newisr, *curisr; isr_list_t *list; if ((ipl < 0) || (ipl >= NISR)) panic("isrlink: bad ipl %d", ipl); newisr = (struct isr *)malloc(sizeof(struct isr), M_DEVBUF, M_NOWAIT); if (newisr == NULL) panic("isrlink: can't allocate space for isr"); /* Fill in the new entry. */ newisr->isr_func = func; newisr->isr_arg = arg; newisr->isr_ipl = ipl; newisr->isr_priority = priority; /* * Some devices are particularly sensitive to interrupt * handling latency. The DCA, for example, can lose many * characters if its interrupt isn't handled with reasonable * speed. * * To work around this problem, each device can give itself a * "priority". An unbuffered DCA would give itself a higher * priority than a SCSI device, for example. * * This is necessary because of the flat spl scheme employed by * the hp300. Each device can be set from ipl 3 to ipl 5, which * in turn means that splbio, splnet, and spltty must all be at * spl5. * * Don't blame me...I just work here. */ /* * Get the appropriate ISR list. If the list is empty, no * additional work is necessary; we simply insert ourselves * at the head of the list. */ list = &isr_list[ipl]; if (list->lh_first == NULL) { LIST_INSERT_HEAD(list, newisr, isr_link); goto done; } /* * A little extra work is required. We traverse the list * and place ourselves after any ISRs with our current (or * higher) priority. */ for (curisr = list->lh_first; curisr->isr_link.le_next != NULL; curisr = curisr->isr_link.le_next) { if (newisr->isr_priority > curisr->isr_priority) { LIST_INSERT_BEFORE(curisr, newisr, isr_link); goto done; } } /* * We're the least important entry, it seems. We just go * on the end. */ LIST_INSERT_AFTER(curisr, newisr, isr_link); done: return (newisr); }
/* * Establish an autovectored interrupt handler. * Called by driver attach functions. */ void isrlink_autovec(int (*func)(void *), void *arg, int ipl, int priority, const char *name) { struct isr_autovec *newisr, *curisr; isr_autovec_list_t *list; #ifdef DIAGNOSTIC if (ipl < 0 || ipl >= NISRAUTOVEC) panic("isrlink_autovec: bad ipl %d", ipl); #endif newisr = (struct isr_autovec *)malloc(sizeof(struct isr_autovec), M_DEVBUF, M_NOWAIT); if (newisr == NULL) panic("isrlink_autovec: can't allocate space for isr"); /* Fill in the new entry. */ newisr->isr_func = func; newisr->isr_arg = arg; newisr->isr_ipl = ipl; newisr->isr_priority = priority; evcount_attach(&newisr->isr_count, name, (void *)&newisr->isr_ipl, &evcount_intr); /* * Some devices are particularly sensitive to interrupt * handling latency. The SCC, for example, can lose many * characters if its interrupt isn't handled with reasonable * speed. * * To work around this problem, each device can give itself a * "priority". An unbuffered SCC would give itself a higher * priority than a SCSI device, for example. * * This solution was originally developed for the hp300, which * has a flat spl scheme (by necessity). Thankfully, the * MVME systems don't have this problem, though this may serve * a useful purpose in any case. */ /* * Get the appropriate ISR list. If the list is empty, no * additional work is necessary; we simply insert ourselves * at the head of the list. */ list = &isr_autovec[ipl]; if (list->lh_first == NULL) { LIST_INSERT_HEAD(list, newisr, isr_link); return; } /* * A little extra work is required. We traverse the list * and place ourselves after any ISRs with our current (or * higher) priority. */ for (curisr = LIST_FIRST(list); LIST_NEXT(curisr, isr_link) != NULL; curisr = LIST_NEXT(curisr, isr_link)) { if (newisr->isr_priority > curisr->isr_priority) { LIST_INSERT_BEFORE(curisr, newisr, isr_link); return; } } /* * We're the least important entry, it seems. We just go * on the end. */ LIST_INSERT_AFTER(curisr, newisr, isr_link); }
/* * Establish an interrupt handler. * Called by driver attach functions. */ void * intr_establish(int (*func)(void *), void *arg, int ipl, int priority) { struct hp300_intrhand *newih, *curih; if ((ipl < 0) || (ipl >= NISR)) panic("intr_establish: bad ipl %d", ipl); newih = malloc(sizeof(struct hp300_intrhand), M_DEVBUF, M_NOWAIT); if (newih == NULL) panic("intr_establish: can't allocate space for handler"); /* Fill in the new entry. */ newih->ih_fn = func; newih->ih_arg = arg; newih->ih_ipl = ipl; newih->ih_priority = priority; /* * Some devices are particularly sensitive to interrupt * handling latency. The DCA, for example, can lose many * characters if its interrupt isn't handled with reasonable * speed. For this reason, we sort ISRs by IPL_* priority, * inserting higher priority interrupts before lower priority * interrupts. */ /* * Get the appropriate ISR list. If the list is empty, no * additional work is necessary; we simply insert ourselves * at the head of the list. */ if (LIST_FIRST(&hp300_intr_list[ipl].hi_q) == NULL) { LIST_INSERT_HEAD(&hp300_intr_list[ipl].hi_q, newih, ih_q); goto done; } /* * A little extra work is required. We traverse the list * and place ourselves after any ISRs with our current (or * higher) priority. */ for (curih = LIST_FIRST(&hp300_intr_list[ipl].hi_q); LIST_NEXT(curih,ih_q) != NULL; curih = LIST_NEXT(curih,ih_q)) { if (newih->ih_priority > curih->ih_priority) { LIST_INSERT_BEFORE(curih, newih, ih_q); goto done; } } /* * We're the least important entry, it seems. We just go * on the end. */ LIST_INSERT_AFTER(curih, newih, ih_q); done: return newih; }