int main(int argc, char *argv[]) { tdb_off_t off; struct tdb_context *tdb; struct tdb_layout *layout; TDB_DATA key, data; plan_tests(11); key.dptr = (unsigned char *)"Hello"; data.dptr = (unsigned char *)"world"; data.dsize = 5; key.dsize = 5; /* Create a TDB with three free tables. */ layout = new_tdb_layout(NULL); tdb_layout_add_freetable(layout); tdb_layout_add_freetable(layout); tdb_layout_add_freetable(layout); tdb_layout_add_free(layout, 80, 0); /* Used record prevent coalescing. */ tdb_layout_add_used(layout, key, data, 6); tdb_layout_add_free(layout, 160, 1); key.dsize--; tdb_layout_add_used(layout, key, data, 7); tdb_layout_add_free(layout, 320, 2); key.dsize--; tdb_layout_add_used(layout, key, data, 8); tdb_layout_add_free(layout, 40, 0); tdb = tdb_layout_get(layout); ok1(tdb_check(tdb, NULL, NULL) == 0); off = get_free(tdb, 0, 80 - sizeof(struct tdb_used_record), 0, TDB_USED_MAGIC, 0); ok1(off == layout->elem[3].base.off); ok1(tdb->ftable_off == layout->elem[0].base.off); off = get_free(tdb, 0, 160 - sizeof(struct tdb_used_record), 0, TDB_USED_MAGIC, 0); ok1(off == layout->elem[5].base.off); ok1(tdb->ftable_off == layout->elem[1].base.off); off = get_free(tdb, 0, 320 - sizeof(struct tdb_used_record), 0, TDB_USED_MAGIC, 0); ok1(off == layout->elem[7].base.off); ok1(tdb->ftable_off == layout->elem[2].base.off); off = get_free(tdb, 0, 40 - sizeof(struct tdb_used_record), 0, TDB_USED_MAGIC, 0); ok1(off == layout->elem[9].base.off); ok1(tdb->ftable_off == layout->elem[0].base.off); /* Now we fail. */ off = get_free(tdb, 0, 0, 1, TDB_USED_MAGIC, 0); ok1(off == 0); tdb_close(tdb); ok1(tap_log_messages == 0); return exit_status(); }
void generar_comparacion(Element *obj, char *etiqueta) { Element *operando1 = (Element *)malloc(sizeof(Element)); Element *operando2 = (Element *)malloc(sizeof(Element)); spop(&pila, (void *)&operando2); spop(&pila, (void *)&operando1); if (operando1->code == REGISTRO) { if (operando2->code == REGISTRO) { //Registro-Registro fprintf(output_fd, "\t\tCMP\t%s, %s\n", operando1->name, operando2->name); } else { //Registro-Operando if (operando2->code == IDENTIFICADOR) fprintf(output_fd, "\t\tCMP\t%s, _%s\n", operando1->name, operando2->name); else fprintf(output_fd, "\t\tCMP\t%s, %d\n", operando1->name, operando2->value); } } else { Element *op_aux2 = get_free(state); if (operando2->code == REGISTRO) { //Operando-Registro if (operando1->code == IDENTIFICADOR) { fprintf(output_fd, "\t\tMOV\t%s, _%s\n", op_aux2->name, operando1->name); fprintf(output_fd, "\t\tCMP\t%s, %s\n", operando2->name, op_aux2->name); } else { fprintf(output_fd, "\t\tMOV\t%s, %d\n", op_aux2->name, operando1->value); fprintf(output_fd, "\t\tCMP\t%s, %s\n", operando2->name, op_aux2->name); } } else { //Operando-Operando if (operando1->code == IDENTIFICADOR) { if (operando2->code == IDENTIFICADOR) { fprintf(output_fd, "\t\tMOV\t%s, _%s\n", op_aux2->name, operando1->name); fprintf(output_fd, "\t\tCMP\t%s, _%s\n", op_aux2->name, operando2->name); } else { fprintf(output_fd, "\t\tMOV\t%s, _%s\n", op_aux2->name, operando1->name); fprintf(output_fd, "\t\tCMP\t%s, %d\n", op_aux2->name, operando2->value); } } else { if (operando2->code == IDENTIFICADOR) { fprintf(output_fd, "\t\tMOV\t%s, %d\n", op_aux2->name, operando1->value); fprintf(output_fd, "\t\tCMP\t%s, _%s\n", op_aux2->name, operando2->name); } else { fprintf(output_fd, "\t\tMOV\t%s, %d\n", op_aux2->name, operando1->value); fprintf(output_fd, "\t\tCMP\t%s, %d\n", op_aux2->name, operando2->value); } } } } Element *op_aux = get_free(); state[op_aux->value] = 1; spush(&pila, (void *)op_aux); fprintf(output_fd, "\t\t%s\tLABEL00%d\n", etiqueta, labelnumber); fprintf(output_fd, "\t\tMOV\t%s, 0\n", op_aux->name); fprintf(output_fd, "\t\tJMP\tLABEL00%d\n", labelnumber+1); fprintf(output_fd, "\tLABEL00%d:\n\t\tMOV\t%s, 1\n", labelnumber, op_aux->name); labelnumber++; fprintf(output_fd, "\tLABEL00%d:\n", labelnumber); labelnumber++; }
/* Deze methode zet het blok op index op vrij, indien mogelijk fuseert het * met omringende vrije blokken. */ void free_block(long index){ long prev = get_prev(index); long next = get_next(index); if(!get_free(index)){ /* Zet het blok op vrij. */ set_free(index, 1); mem[0] -= get_length(index); } /* Voeg vorige blok samen met het huidige als deze vrij is als een groot * vrij blok. */ if(prev != 0 && get_free(prev)){ set_length(prev, get_length(prev) + get_length(index) + ADMIN_SIZE); set_next(prev, next); if(next != 0){ set_prev(next, prev); } mem[1] -= ADMIN_SIZE; } /* Voeg volgende blok samen met het huidige als deze vrij is als een * groot vrij blok. */ if(next != 0 && get_free(next)){ free_block(next); } }
void mem_available(long *empty, long *large, long *n_holes){ long idx = 2; long next; long prev; *empty = MEM_SIZE - mem[0] - mem[1]; *large = 0; *n_holes = 0; while(idx != 0){ next = get_next(idx); prev = get_prev(idx); /* Blok is een gat als het vrij is en de omringende blokken zijn * niet vrij of bestaan niet (als dit blok het eerste of laatste * blok is) */ if(get_free(idx) && ( (next && prev && !get_free(next) && !get_free(prev)) || (!prev && next && !get_free(next)) || (!next && prev && !get_free(prev)) || (!next && !prev) ) ){ if(get_length(idx) > *large){ /* Nieuw grootste gat gevonden. */ *large = get_length(idx); } *n_holes += 1; } idx = get_next(idx); } }
long mem_get(long request){ long l = request; long lidx = 0; long idx = 2; while(idx != 0){ if(get_length(idx) >= l && get_free(idx)){ /* Gat gevonden waar de aanvraag in past. */ lidx = idx; l = get_length(idx); break; } idx = get_next(idx); } if(lidx == 0){ /* Geen gat groot genoeg. */ return -1; }else if(l == request){ /* Gat precies groot genoeg. */ mem[0] += request; mem[1] += ADMIN_SIZE; set_free(lidx, 0); return lidx + ADMIN_SIZE; }else{ /* Alleen een gat > request. */ return split_block(lidx, request); } }
static void ins_level(int l, ENTRY *e) { int i; if ( l < 0) { for (i = 1; i < MAX_LEVELS; i++) { CO(MAX_LEVELS - i) = CO(MAX_LEVELS - i - 1); CB(MAX_LEVELS - i) = CB(MAX_LEVELS - i - 1); } memcpy(spare_block, &(pci->root), sizeof(BLOCK)); spare_block->brec = get_free(); write_if(pci->ixfile, spare_block->brec,(char *) spare_block, sizeof(BLOCK)); pci->root.p0 = spare_block->brec; copy_entry((ENTRY *) (pci->root.entries), e); pci->root.bend = ENT_SIZE(e); CO(0) = 0; pci->level = 0; (pci->dx.nl)++; update_root(&(pci->root)); } else { ins_block(block_ptr,e,CO(l)); } }
int get_next_line(const int fd, char **line) { static t_line *begin = NULL; t_line *elem; char buf[BUFF_SIZE + 1]; int ret; elem = NULL; if (fd < 0 || !line || read(fd, *line, 0) < 0) return (-1); if (!begin) begin = (t_line*)ft_memalloc(sizeof(t_line)); ft_bzero(buf, BUFF_SIZE + 1); if (fd >= 0 && (elem = get_fd(fd, &begin))) { !TMP ? TMP = ft_strnew(BUFF_SIZE) : 0; while ((ret = read(fd, buf, BUFF_SIZE)) > 0) { if (put_next_line(line, buf, elem, ret)) return (1); ft_bzero(buf, ft_strlen(buf)); } if (TMP && ret == 0) return (put_next_line(line, buf, elem, ret) ? 1 : 0); } get_free(begin, elem); return (0); }
EXPORT_C void free(void *ptr) { if (dlsym_nesting) { return; } deinit( ptr ); get_free() (ptr); }
EXPORT_C void __attribute__((constructor)) mdbg_init_mem_alloc(void) { get_malloc(); get_realloc(); get_free(); get_posix_memalign(); get_memalign(); get_valloc(); set_core_unlimited(); }
int AsebaUsbBulkRecv(unsigned char *data, unsigned char size) { size_t free = get_free(&AsebaUsb.rx); if(size >= free) return 1; memcpy_to_fifo(&AsebaUsb.rx, data, size); return 0; }
void generar_or(Element *obj) { Element *operando1 = (Element *)malloc(sizeof(Element)); Element *operando2 = (Element *)malloc(sizeof(Element)); spop(&pila, (void *)&operando2); spop(&pila, (void *)&operando1); if (operando1->code == REGISTRO) { if (operando2->code == REGISTRO) { //Registro-Registro fprintf(output_fd, "\t\tOR\t%s, %s\n", operando2->name, operando1->name); state[operando1->value] = 0; /*Libero el registro*/ spush(&pila, (void *)operando2); } else { //Registro-Operando if (operando2->code == IDENTIFICADOR) fprintf(output_fd, "\t\tOR\t%s, _%s\n", operando1->name, operando2->name); else fprintf(output_fd, "\t\tOR\t%s, %d\n", operando1->name, operando2->value); spush(&pila, (void *)operando1); } } else { if (operando2->code == REGISTRO) { //Operando-Registro if (operando1->code == IDENTIFICADOR) fprintf(output_fd, "\t\tOR\t%s, _%s\n", operando2->name, operando1->name); else fprintf(output_fd, "\t\tOR\t%s, %d\n", operando2->name, operando1->value); spush(&pila, (void *)operando2); } else { //Operando-Operando Element *op_aux = get_free(); if (operando1->code == IDENTIFICADOR) { if (operando2->code == IDENTIFICADOR) { fprintf(output_fd, "\t\tMOV\t%s, _%s\n", op_aux->name, operando1->name); fprintf(output_fd, "\t\tOR\t%s, _%s\n", op_aux->name, operando2->name); } else { fprintf(output_fd, "\t\tMOV\t%s, _%s\n", op_aux->name, operando1->name); fprintf(output_fd, "\t\tOR\t%s, %d\n", op_aux->name, operando2->value); } } else { if (operando2->code == IDENTIFICADOR) { fprintf(output_fd, "\t\tMOV\t%s, %d\n", op_aux->name, operando1->value); fprintf(output_fd, "\t\tOR\t%s, _%s\n", op_aux->name, operando2->name); } else { fprintf(output_fd, "\t\tMOV\t%s, %d\n", op_aux->name, operando1->value); fprintf(output_fd, "\t\tOR\t%s, %d\n", op_aux->name, operando2->value); } } spush(&pila, (void *)op_aux); state[op_aux->value] = 1; } } }
_Ty* acquire() { try_allocate(); _Ty* obj = get_free(); try { new (obj) _Ty(); } catch (...) { free(obj); throw; } return obj; }
_Ty* acquire(const ArgT0& arg0, const ArgT1& arg1, const ArgT2& arg2) { try_allocate(); _Ty* obj = get_free(); try { new (obj) _Ty(arg0, arg1, arg2); } catch (...) { free(obj); throw; } return obj; }
/* insert new entries into tree */ static bool split(int l, ENTRY *pe, ENTRY *e) { int half, ins_pos, size; ins_pos = CO(pci->level); half = scan_blk(block_ptr->bend / 2 + sizeof(RECPOS)); if (half == ins_pos) { *e = *pe; } else { copy_entry(e, ENT_ADR(block_ptr, half)); size = ENT_SIZE(e); movedown(block_ptr, half, size); block_ptr->bend -= size; update_root(block_ptr); } spare_block = &BUFBLOCK(new_cache()); memcpy(spare_block->entries, ENT_ADR(block_ptr,half), block_ptr->bend - half); spare_block->brec = get_free(); spare_block->bend = block_ptr->bend - half; spare_block->p0 = e->idxptr; block_ptr->bend = half; e->idxptr = spare_block->brec; if (ins_pos < half) { ins_block(block_ptr,pe,ins_pos); } else if (ins_pos > half) { ins_pos -= ENT_SIZE(e); ins_block(spare_block,pe,ins_pos - half); CB(l) = e->idxptr; CO(l) = CO(l) - half; } write_if(pci->ixfile, spare_block->brec,(char *) spare_block, sizeof(BLOCK)); return TRUE; }
void generar_not(Element *obj) { Element *operando = (Element *)malloc(sizeof(Element)); spop(&pila, (void *)&operando); if (operando->code == REGISTRO) { fprintf(output_fd, "\t\tNOT\t%s\n", operando->name); spush(&pila, (void *)operando); } else { Element *op_aux = get_free(); if (operando->code == IDENTIFICADOR) { fprintf(output_fd, "\t\tMOV\t%s, _%s\n", op_aux->name, operando->name); } else { fprintf(output_fd, "\t\tMOV\t%s, %d\n", op_aux->name, operando->value); } fprintf(output_fd, "\t\tNOT\t%s\n", op_aux->name); state[op_aux->value] = 1; spush(&pila, (void *)op_aux); } }
void AsebaSendBuffer(AsebaVMState *vm, const uint8_t *data, uint16_t length) { int flags; // Here we must loop until we can send the data. // BUT if the usb connection is not available, we drop the packet if(!usb_uart_serial_port_open()) return; // Sanity check, should never be true if (length < 2) return; do { USBMaskInterrupts(flags); if(get_free(&AsebaUsb.tx) > length + 4) { length -= 2; memcpy_to_fifo(&AsebaUsb.tx, (unsigned char *) &length, 2); memcpy_to_fifo(&AsebaUsb.tx, (unsigned char *) &vm->nodeId, 2); memcpy_to_fifo(&AsebaUsb.tx, (unsigned char *) data, length + 2); // Will callback AsebaUsbTxReady if (!tx_busy) { tx_busy = 1; USBCDCKickTx(); } length = 0; } // Usb can be disconnected while sending ... if(!usb_uart_serial_port_open()) { fifo_reset(&AsebaUsb.tx); USBUnmaskInterrupts(flags); break; } USBUnmaskInterrupts(flags); } while(length); }
void operator delete(void * p) { get_free()(p); }
int write_buffer(struct buffer_entity *be) { struct simplebuf *sbuf = (struct simplebuf *)be->opt; int ret; if (be->recer == NULL) { ret = 0; D("Getting rec entity for buffer: file %ld, filename %s", sbuf->fileid, sbuf->opt->filename); if (sbuf->opt->optbits & WRITE_TO_SINGLE_FILE) { pthread_mutex_lock(sbuf->opt->writequeue); while (sbuf->opt->next_fd_id_to_write < sbuf->fileid) { if (sbuf->opt->optbits & READMODE) D("Waiting for file seq %ld to come up for sending. Now %ld", sbuf->fileid, sbuf->opt->next_fd_id_to_write); else D("Waiting for file seq %ld to come up for recording. Now %ld", sbuf->fileid, sbuf->opt->next_fd_id_to_write); pthread_cond_wait(sbuf->opt->writequeue_signal, sbuf->opt->writequeue); } pthread_mutex_unlock(sbuf->opt->writequeue); if (sbuf->opt->optbits & READMODE) D("My turn to read %ld", sbuf->fileid); else D("My turn to write %ld", sbuf->fileid); } /* If we're reading, we need a specific recorder_entity */ if (sbuf->opt->optbits & READMODE) { size_t disk_id; /* First need to check that the file is already written or not */ ret = afi_wait_on_file(sbuf->fi, sbuf->fileid); if (ret != 0) { E("Error in waiting for file on disk"); return -1; } disk_id = afi_get_disk_id(sbuf->opt->fi, sbuf->fileid); D("Getting rec entity id %zu for file %lu", disk_id, sbuf->fileid); be->recer = (struct recording_entity *)get_specific(sbuf->opt->diskbranch, sbuf->opt, sbuf->fileid, sbuf->running, disk_id, &ret); /* TODO: This is a real bummer. Handle! */ if (be->recer == NULL || ret != 0) { E("Specific writer fails on acquired."); E("Shutting it down and removing from list"); E("Wanted %ld from %zu", sbuf->fileid, disk_id); if (be->recer == NULL) E("Recer was null"); else E("Ret wasnt zero"); /* Not thread safe atm */ //Let the one using it close it! if (be->recer != NULL) { close_recer(be, ret); } return -1; } be->recer->setshmid(be->recer, sbuf->shmid, be->buffer); D("Got rec entity %d to load %s file %lu!", be->recer->getid(be->recer), afi_get_filename(sbuf->opt->fi), sbuf->fileid); if (!(sbuf->opt->optbits & WRITE_TO_SINGLE_FILE)) { uint64_t rfilesize = be->recer->get_filesize(be->recer); if (sbuf->diff != rfilesize) { D("Adjusting filesize from %lu to %lu", sbuf->diff, rfilesize); sbuf->diff = rfilesize; } } } else { be->recer = (struct recording_entity *)get_free(sbuf->opt->diskbranch, sbuf->opt, ((void *)&(sbuf->fileid)), &ret, 0); if (be->recer == NULL) { E("Didn't get a recer. This is bad so exiting"); sbuf->running = 0; remove_from_branch(sbuf->opt->membranch, be->self, 0); return -1; } else if (ret != 0) { E("Error in acquired for random entity"); E("Shutting faulty writer down"); /* TODO: In daemonmode, the remove specific needs to exist also! */ close_recer(be, ret); /* The next round will get a new recer */ return -1; } else { be->recer->setshmid(be->recer, sbuf->shmid, be->buffer); D("Updating file_index %s on id %lu for in mem and busy ", afi_get_filename(sbuf->opt->fi), sbuf->fileid); afi_add_file(sbuf->opt->fi, sbuf->fileid, be->recer->getid(be->recer), FH_INMEM | FH_BUSY); if (!(sbuf->opt->optbits & DATATYPE_UNKNOWN)) { if (check_and_fill (be->buffer, sbuf->opt, sbuf->fileid, NULL) != 0) E("Error in check and fill for %s id %ld", sbuf->opt->filename, sbuf->fileid); } ASSERT(be->recer->getid(be->recer) < sbuf->opt->n_drives); //update_fileholder(sbuf->opt->fi, sbuf->fileid, FH_INMEM|FH_BUSY, AFI_ADD_TO_STATUS, be->recer->getid(be->recer)); } } //CHECK_AND_EXIT(be->recer); //D("Got rec entity"); } if (sbuf->opt->optbits & ASYNC_WRITE) { ret = sbuf_async_loop(be); } else { ret = sbuf_sync_loop(be); } if (ret != 0) { E("Faulty recer"); if (be->recer != NULL) close_recer(be, ret); return -1; } /* If we've succesfully written everything: set everything free etc */ if (sbuf->diff == 0) { if (sbuf->opt->optbits & READMODE) D("Operation complete for Reading file %ld of %s. Releasing recpoint", sbuf->fileid, sbuf->opt->filename); else D("Operation complete for Recording file %ld of %s. Releasing recpoint", sbuf->fileid, sbuf->opt->filename); /* Might have closed recer already */ if (sbuf->opt->optbits & READMODE) D("Recpoint released for reading of %ld filename %s", sbuf->fileid, sbuf->opt->filename); else D("Recpoint released for writing of %ld filename %s", sbuf->fileid, sbuf->opt->filename); } else { E("Diff not lowered to 0 on %s fileid %ld", sbuf->opt->filename, sbuf->fileid); } if (be->recer != NULL) set_free(sbuf->opt->diskbranch, be->recer->self); be->recer = NULL; return ret; }
static void read_files(metafile_t *m, queue_t *q, unsigned char *pos) { int fd; /* file descriptor */ flist_t *f; /* pointer to a place in the file list */ ssize_t r = 0; /* number of bytes read from file(s) into the read buffer */ #ifndef NO_HASH_CHECK off_t counter = 0; /* number of bytes hashed should match size when done */ #endif piece_t *p = get_free(q, m->piece_length); /* go through all the files in the file list */ for (f = m->file_list; f; f = f->next) { /* open the current file for reading */ if ((fd = open(f->path, OPENFLAGS)) == -1) { fprintf(stderr, "Error opening '%s' for reading: %s\n", f->path, strerror(errno)); exit(EXIT_FAILURE); } while (1) { ssize_t d = read(fd, p->data + r, m->piece_length - r); if (d < 0) { fprintf(stderr, "Error reading from '%s': %s\n", f->path, strerror(errno)); exit(EXIT_FAILURE); } if (d == 0) /* end of file */ break; r += d; if (r == m->piece_length) { p->dest = pos; p->len = m->piece_length; put_full(q, p); pos += SHA_DIGEST_LENGTH; #ifndef NO_HASH_CHECK counter += r; #endif r = 0; p = get_free(q, m->piece_length); } } /* now close the file */ if (close(fd)) { fprintf(stderr, "Error closing '%s': %s\n", f->path, strerror(errno)); exit(EXIT_FAILURE); } } /* finally append the hash of the last irregular piece to the hash string */ if (r) { p->dest = pos; p->len = r; put_full(q, p); } else put_free(q, p, 0); #ifndef NO_HASH_CHECK counter += r; if (counter != m->size) { fprintf(stderr, "Counted %" PRIoff " bytes, " "but hashed %" PRIoff " bytes. " "Something is wrong...\n", m->size, counter); exit(EXIT_FAILURE); } #endif }
int start_loading(struct opt_s *opt, struct buffer_entity *be, struct sender_tracking *st) { long nuf; int err; skip_missing(opt, st, SKIP_LOADED); D("Packets loaded is %lu, packet probed %ld", st->packets_loaded, st->n_packets_probed); if (st->files_loaded == st->n_files_probed) { D("Loaded up to n_files!"); return DONTRYLOADNOMORE; } err = afi_start_loading(opt->fi, st->files_loaded, st->files_in_loading > 0); if (err) { if (err == 1) { return DONTRYLOADNOMORE; } return err; } afi_update_metadata(opt->fi, &st->n_files_probed, &st->n_packets_probed, &st->status_probed); nuf = MIN((st->n_packets_probed - st->packets_loaded), ((unsigned long)opt->buf_num_elems)); if (nuf == 0) { E("Metadata error on recording %s. Cant load 0 packets", opt->filename); return DONTRYLOADNOMORE; } /* TODO: Not checking if FH_ONDISK is set */ D("Requested a load start on file %lu", st->files_loaded); if (be == NULL) { if (check_if_free(opt->membranch) != 0) { D("No more free buffers"); if (st->files_in_loading != 0) { D("wont loadup since no more free buffers and we have files in loading"); return DONTRYLOADNOMORE; } } be = get_free(opt->membranch, opt, (void *)(&(st->files_loaded)), NULL, 1); st->allocated_to_load--; } /* Reacquiring just updates the file number we want */ else { be->acquire((void *)be, opt, &(st->files_loaded)); } CHECK_AND_EXIT(be); st->files_in_loading++; D("Setting seqnum %lu to load %lu packets", st->files_loaded, nuf); LOCK(be->headlock); unsigned long *inc; be->simple_get_writebuf(be, &inc); *inc = nuf * (opt->packet_size); be->set_ready(be, 1); pthread_cond_signal(be->iosignal); UNLOCK(be->headlock); D("Loading request complete for id %lu", st->files_loaded); st->packets_loaded += nuf; st->files_loaded++; return 0; }
void operator delete[] (void *ptr) { deinit( ptr ); get_free() (ptr); }
int main(int argc, char *argv[]) { tdb_off_t off; struct tdb_context *tdb; struct tdb_layout *layout; TDB_DATA key, data; union tdb_attribute seed; /* This seed value previously tickled a layout.c bug. */ seed.base.attr = TDB_ATTRIBUTE_SEED; seed.seed.seed = 0xb1142bc054d035b4ULL; seed.base.next = &tap_log_attr; plan_tests(11); key = tdb_mkdata("Hello", 5); data = tdb_mkdata("world", 5); /* Create a TDB with three free tables. */ layout = new_tdb_layout(); tdb_layout_add_freetable(layout); tdb_layout_add_freetable(layout); tdb_layout_add_freetable(layout); tdb_layout_add_free(layout, 80, 0); /* Used record prevent coalescing. */ tdb_layout_add_used(layout, key, data, 6); tdb_layout_add_free(layout, 160, 1); key.dsize--; tdb_layout_add_used(layout, key, data, 7); tdb_layout_add_free(layout, 320, 2); key.dsize--; tdb_layout_add_used(layout, key, data, 8); tdb_layout_add_free(layout, 40, 0); tdb = tdb_layout_get(layout, free, &seed); ok1(tdb_check(tdb, NULL, NULL) == 0); off = get_free(tdb, 0, 80 - sizeof(struct tdb_used_record), 0, TDB_USED_MAGIC, 0); ok1(off == layout->elem[3].base.off); ok1(tdb->tdb2.ftable_off == layout->elem[0].base.off); off = get_free(tdb, 0, 160 - sizeof(struct tdb_used_record), 0, TDB_USED_MAGIC, 0); ok1(off == layout->elem[5].base.off); ok1(tdb->tdb2.ftable_off == layout->elem[1].base.off); off = get_free(tdb, 0, 320 - sizeof(struct tdb_used_record), 0, TDB_USED_MAGIC, 0); ok1(off == layout->elem[7].base.off); ok1(tdb->tdb2.ftable_off == layout->elem[2].base.off); off = get_free(tdb, 0, 40 - sizeof(struct tdb_used_record), 0, TDB_USED_MAGIC, 0); ok1(off == layout->elem[9].base.off); ok1(tdb->tdb2.ftable_off == layout->elem[0].base.off); /* Now we fail. */ off = get_free(tdb, 0, 0, 1, TDB_USED_MAGIC, 0); ok1(off == 0); tdb_close(tdb); tdb_layout_free(layout); ok1(tap_log_messages == 0); return exit_status(); }
void enqueue(QUEUE *q, Q_ELEMENT_WHAT *el, int n) { /* * insert n elements in array el into the priority queue q */ Q_ELEMENT *e, *where, *next; int i = 0, p; #ifndef QUEUE_MAIN if (q == NULL || el == NULL || n <= 0) ErrMsg(ER_NULL, "enqueue"); #endif /* * first sort array el */ qsort(el, (size_t) n, sizeof(Q_ELEMENT_WHAT), (int CDECL (*)(const void *,const void *)) q->cmp); /* * and then merge them with the priority queue q */ /* * find p, the number of elements in el[] that are smaller than * the first element in the queue, if any. * (Yes, we expect at least some of them to be closer than q->head) */ for (p = n; q->head != NULL && p > 0; p--) if (q->cmp(&(el[p-1]), &(q->head->el)) <= 0) break; /* out of this for loop */ /* * put these p elements in order at the queue head: */ for (i = p; i > 0; i--) { e = get_free(q); e->el = el[i-1]; e->next = q->head; q->head = e; } q->length += p; n -= p; /* * We might be done by now (n zero). * Process the remaining elements: */ where = q->head; /* starting point for insertion: */ next = where->next; /* the next element */ el += p; /* start of the remaining elements */ for (i = 0; i < n; i++) { e = get_free(q); /* get a free queue element */ e->el = el[i]; /* copy contents: */ /* * unless where is the last element, shift a position in the queue * when the element is larger than the insertion element e: */ while (next != NULL && q->cmp(&(e->el), &(next->el)) > 0) { where = next; next = where->next; } /* * now next points either to NULL or to the first element smaller * than or equal to e. So, insert e after where and before next: */ e->next = next; where->next = e; /* * the next element in el[] will should follow after e, * so shift where one position to start looking after e: */ where = e; } q->length += n; return; }