Exemplo n.º 1
0
void bufwrite_bufdel(caryll_Buffer *buf, caryll_Buffer *that) {
	if (!that) return;
	if (!that->data) {
		buffree(that);
		return;
	}
	size_t len = buflen(that);
	bufbeforewrite(buf, len);
	memcpy(buf->data + buf->cursor, that->data, len);
	buffree(that);
	buf->cursor += len;
}
Exemplo n.º 2
0
Arquivo: req.c Projeto: dolda2000/ashd
char *unquoteurl(char *in)
{
    struct charbuf buf;
    char *p;
    int c;
    
    bufinit(buf);
    p = in;
    while(*p) {
	if(*p == '%') {
	    if(!p[1] || !p[2])
		goto fail;
	    c = 0;
	    if((p[1] >= '0') && (p[1] <= '9'))          c |= (p[1] - '0') << 4;
	    else if((p[1] >= 'a') && (p[1] <= 'f'))     c |= (p[1] - 'a' + 10) << 4;
	    else if((p[1] >= 'A') && (p[1] <= 'F'))     c |= (p[1] - 'A' + 10) << 4;
	    else                                        goto fail;
	    if((p[2] >= '0') && (p[2] <= '9'))          c |= (p[2] - '0');
	    else if((p[2] >= 'a') && (p[2] <= 'f'))     c |= (p[2] - 'a' + 10);
	    else if((p[2] >= 'A') && (p[2] <= 'F'))     c |= (p[2] - 'A' + 10);
	    else                                        goto fail;
	    bufadd(buf, c);
	    p += 3;
	} else {
	    bufadd(buf, *(p++));
	}
    }
    bufadd(buf, 0);
    return(buf.b);
fail:
    buffree(buf);
    return(NULL);
}
Exemplo n.º 3
0
/**
 * @ingroup etherspecific
 *
 * Callback function executed with interrupts disabled when an asynchronous USB
 * bulk transfer to the Bulk OUT endpoint of the SMSC LAN9512 USB Ethernet
 * Adapter for the purpose of sending an Ethernet packet has successfully
 * completed or has failed.
 *
 * Currently all this function has to do is return the buffer to its pool.  This
 * may wake up a thread in etherWrite() that is waiting for a free buffer.
 *
 * @param req
 *      USB bulk OUT transfer request that has completed.
 */
void smsc9512_tx_complete(struct usb_xfer_request *req)
{
    struct ether *ethptr = req->private;

    ethptr->txirq++;
    usb_dev_debug(req->dev, "SMSC9512: Tx complete\n");
    buffree(req);
}
Exemplo n.º 4
0
/*
 * truncate d (in p) to zero length.
 * freeing blocks in reverse order is traditional, from Unix,
 * in an attempt to keep the free list contiguous.
 */
void
dtrunc(Iobuf *p, Dentry *d, int uid)
{
	int i;

	for (i = NIBLOCK-1; i >= 0; i--) {
		buffree(p->dev, d->iblocks[i], i+1, nil);
		d->iblocks[i] = 0;
	}
	for (i = NDBLOCK-1; i >= 0; i--) {
		buffree(p->dev, d->dblock[i], 0, nil);
		d->dblock[i] = 0;
	}
	d->size = 0;
	p->flags |= Bmod|Bimm;
	accessdir(p, d, FWRITE, uid);
}
Exemplo n.º 5
0
static void outplex(struct muth *muth, va_list args)
{
    vavar(FILE *, sk);
    struct {
	struct ch {
	    FILE *s;
	    int id;
	} *b;
	size_t s, d;
    } outs;
    int i;
    struct ch ch;
    int type, rid;
    char *data;
    size_t dlen;
    
    bufinit(outs);
    while((ch.s = va_arg(args, FILE *)) != NULL) {
	ch.id = va_arg(args, int);
	bufadd(outs, ch);
    }
    data = NULL;
    while(1) {
	if(recvrec(sk, &type, &rid, &data, &dlen))
	    goto out;
	if(rid != 1)
	    goto out;
	for(i = 0; i < outs.d; i++) {
	    if(outs.b[i].id == type) {
		if(outs.b[i].s != NULL) {
		    if(dlen == 0) {
			fclose(outs.b[i].s);
			outs.b[i].s = NULL;
		    } else {
			if(fwrite(data, 1, dlen, outs.b[i].s) != dlen)
			    goto out;
		    }
		}
		break;
	    }
	}
	free(data);
	data = NULL;
    }

out:
    if(data != NULL)
	free(data);
    for(i = 0; i < outs.d; i++) {
	if(outs.b[i].s != NULL)
	    fclose(outs.b[i].s);
    }
    buffree(outs);
    fclose(sk);
}
Exemplo n.º 6
0
Arquivo: sub.c Projeto: npe9/harvey
/*
 * free the block at `addr' on dev.
 * if it's an indirect block (d [depth] > 0),
 * first recursively free all the blocks it names.
 *
 * ts->relblk is the block number within the file of this
 * block (or the first data block eventually pointed to via
 * this indirect block).
 */
void
buffree(Device *dev, Off addr, int d, Truncstate *ts)
{
	Iobuf *p;
	Off a;
	int i, pastlast;

	if(!addr)
		return;
	pastlast = (ts == nil? 1: ts->pastlast);
	/*
	 * if this is an indirect block, recurse and free any
	 * suitable blocks within it (possibly via further indirect blocks).
	 */
	if(d > 0) {
		d--;
		p = getbuf(dev, addr, Brd);
		if(p) {
			if (ts == nil)		/* common case: create */
				for(i=INDPERBUF-1; i>=0; i--) {
					a = ((Off *)p->iobuf)[i];
					buffree(dev, a, d, nil);
				}
			else			/* wstat truncation */
				for (i = 0; i < INDPERBUF; i++)
					truncfree(ts, dev, d, p, i);
			putbuf(p);
		}
	}
	if (!pastlast)
		return;
	/*
	 * having zeroed the pointer to this block, add it to the free list.
	 * stop outstanding i/o
	 */
	p = getbuf(dev, addr, Bprobe);
	if(p) {
		p->flags &= ~(Bmod|Bimm);
		putbuf(p);
	}
	/*
	 * dont put written worm
	 * blocks into free list
	 */
	if(dev->type == Devcw) {
		i = cwfree(dev, addr);
		if(i)
			return;
	}
	p = getbuf(dev, superaddr(dev), Brd|Bmod);
	if(!p || checktag(p, Tsuper, QPSUPER))
		panic("buffree: super block");
	addfree(dev, addr, (Superb*)p->iobuf);
	putbuf(p);
}
Exemplo n.º 7
0
/*
 * truncate d (in p) to length `newsize'.
 * if larger, just increase size.
 * if smaller, deallocate blocks after last one
 * still in file at new size.  last byte to keep
 * is newsize-1, due to zero origin.
 * we free in forward order because it's simpler to get right.
 * if the final block at the new size is partially-filled,
 * zero the remainder.
 */
int
dtrunclen(Iobuf *p, Dentry *d, Off newsize, int uid)
{
	int i, pastlast;
	Truncstate trunc;

	if (newsize <= 0) {
		dtrunc(p, d, uid);
		return 0;
	}
	memset(&trunc, 0, sizeof trunc);
	trunc.d = d;
	trunc.p = p;
	trunc.uid = uid;
	trunc.newsize = newsize;
	trunc.lastblk = newsize/BUFSIZE;
	if (newsize % BUFSIZE == 0)
		trunc.lastblk--;
	else
		trunczero(&trunc);
	for (i = 0; i < NDBLOCK; i++)
		if (trunc.pastlast) {
			trunc.relblk = i;
			buffree(p->dev, d->dblock[i], 0, &trunc);
			d->dblock[i] = 0;
		} else if (i == trunc.lastblk)
			trunc.pastlast = 1;
	trunc.relblk = NDBLOCK;
	for (i = 0; i < NIBLOCK; i++) {
		pastlast = trunc.pastlast;
		buffree(p->dev, d->iblocks[i], i+1, &trunc);
		if (pastlast)
			d->iblocks[i] = 0;
	}

	d->size = newsize;
	p->flags |= Bmod|Bimm;
	accessdir(p, d, FWRITE, uid);
	return trunc.err;
}
Exemplo n.º 8
0
int memory::switchbuf(unsigned int i)  // creates a new buffer with size >= i 
{
	bufcount++;		// the new buffer has number bufcount
	if (bufcount == BUFPOS) 
	{ 
		buffree(); bufcount--; 
		printf("The blocks are used up.\n");
		delete this;
		exit(0);

  //		freebuf(); 
	}
	if (bufcount < BUFSBSWITCH) rest[bufcount] = BUFS_SMALL;
	else{
		int j = BUFPOS/(BUFPOS-bufcount);
		if(j<12)
			rest[bufcount] = power2[j-1]*BUFS_BIG;
		else 
			rest[bufcount] = power2[11]*BUFS_BIG;
	}

	if (rest[bufcount] < i) rest[bufcount] = i;
	restsize[bufcount] = rest[bufcount];

	buffer[bufcount] = new char[rest[bufcount]];
	if (buffer[bufcount] == NULL) {
#ifdef DEBUG
		perror("switchbuf 1");
#endif
		buffree(); 
		printf("Not enough memory!\n");
		delete this;
//		freebuf(); 
	}
	start[bufcount] = buffer[bufcount]; 
	return bufcount;
} // switchbuf 
Exemplo n.º 9
0
Arquivo: sub.c Projeto: npe9/harvey
/* truncating to length > 0 */
static void
truncfree(Truncstate *ts, Device *dev, int d, Iobuf *p, int i)
{
	int pastlast;
	Off a;

	pastlast = ts->pastlast;
	a = ((Off *)p->iobuf)[i];
	if (d > 0 || pastlast)
		buffree(dev, a, d, ts);
	if (pastlast) {
		((Off *)p->iobuf)[i] = 0;
		p->flags |= Bmod|Bimm;
	} else if (d == 0 && ts->relblk == ts->lastblk)
		ts->pastlast = 1;
	if (d == 0)
		ts->relblk++;
}
Exemplo n.º 10
0
Arquivo: req.c Projeto: dolda2000/ashd
int recvreq(int sock, struct hthead **reqp)
{
    int fd;
    struct charbuf buf;
    char *p;
    size_t l;
    char *name, *val;
    struct hthead *req;
    
    if((fd = recvfd(sock, &buf.b, &buf.d)) < 0) {
	return(-1);
    }
    fcntl(fd, F_SETFD, FD_CLOEXEC);
    buf.s = buf.d;
    p = buf.b;
    l = buf.d;
    
    *reqp = omalloc(req);
    if((req->method = sstrdup(decstr(&p, &l))) == NULL)
	goto fail;
    if((req->url = sstrdup(decstr(&p, &l))) == NULL)
	goto fail;
    if((req->ver = sstrdup(decstr(&p, &l))) == NULL)
	goto fail;
    if((req->rest = sstrdup(decstr(&p, &l))) == NULL)
	goto fail;
    
    while(1) {
	if(!*(name = decstr(&p, &l)))
	    break;
	val = decstr(&p, &l);
	headappheader(req, name, val);
    }
    
    buffree(buf);
    return(fd);
    
fail:
    close(fd);
    freehthead(req);
    errno = EPROTO;
    return(-1);
}
Exemplo n.º 11
0
Arquivo: req.c Projeto: dolda2000/ashd
int sendreq2(int sock, struct hthead *req, int fd, int flags)
{
    int ret, i;
    struct charbuf buf;
    
    bufinit(buf);
    bufcatstr2(buf, req->method);
    bufcatstr2(buf, req->url);
    bufcatstr2(buf, req->ver);
    bufcatstr2(buf, req->rest);
    for(i = 0; i < req->noheaders; i++) {
	bufcatstr2(buf, req->headers[i][0]);
	bufcatstr2(buf, req->headers[i][1]);
    }
    bufcatstr2(buf, "");
    ret = sendfd2(sock, fd, buf.b, buf.d, flags);
    buffree(buf);
    if(ret < 0)
	return(-1);
    else
	return(0);
}
Exemplo n.º 12
0
/**
 * Transmit packet interrupt handler
 */
void txPackets(struct ether *ethptr, struct ag71xx *nicptr)
{
    struct dmaDescriptor *dmaptr;
    struct ethPktBuffer **epb = NULL;
    struct ethPktBuffer *pkt = NULL;
    ulong head = 0;

    // kprintf("txS=0x%08X\r\n", nicptr->txStatus);
    if (ethptr->txHead == ethptr->txTail)
    {
        nicptr->txStatus = TX_STAT_SENT;
        return;
    }

    while (ethptr->txHead != ethptr->txTail)
    {
        head = ethptr->txHead % ETH_TX_RING_ENTRIES;
        dmaptr = &ethptr->txRing[head];
        if (!(dmaptr->control & ETH_DESC_CTRL_EMPTY))
        {
            break;
        }

        epb = &ethptr->txBufs[head];

        // Clear Tx interrupt.
        nicptr->txStatus = TX_STAT_SENT;

        ethptr->txHead++;
        pkt = *epb;
        if (NULL == pkt)
        {
            continue;
        }
        buffree((void *)((ulong)pkt & (PMEM_MASK | KSEG0_BASE)));
        *epb = NULL;
    }
}
Exemplo n.º 13
0
static struct hthead *parsereq(struct bufio *in)
{
    struct hthead *req;
    struct charbuf method, url, ver;
    int c;
    
    req = NULL;
    bufinit(method);
    bufinit(url);
    bufinit(ver);
    while(1) {
	c = biogetc(in);
	if(c == ' ') {
	    break;
	} else if((c == EOF) || (c < 32) || (c >= 128)) {
	    goto fail;
	} else {
	    bufadd(method, c);
	    if(method.d >= 128)
		goto fail;
	}
    }
    while(1) {
	c = biogetc(in);
	if(c == ' ') {
	    break;
	} else if((c == EOF) || (c < 32)) {
	    goto fail;
	} else {
	    bufadd(url, c);
	    if(url.d >= 65536)
		goto fail;
	}
    }
    while(1) {
	c = biogetc(in);
	if(c == 10) {
	    break;
	} else if(c == 13) {
	} else if((c == EOF) || (c < 32) || (c >= 128)) {
	    goto fail;
	} else {
	    bufadd(ver, c);
	    if(ver.d >= 128)
		goto fail;
	}
    }
    bufadd(method, 0);
    bufadd(url, 0);
    bufadd(ver, 0);
    req = mkreq(method.b, url.b, ver.b);
    if(parseheadersb(req, in))
	goto fail;
    trimx(req);
    goto out;
    
fail:
    if(req != NULL) {
	freehthead(req);
	req = NULL;
    }
out:
    buffree(method);
    buffree(url);
    buffree(ver);
    return(req);
}
Exemplo n.º 14
0
/**
 * Control function for ethloop devices.
 * @param devptr ethloop device table entry
 * @param func control function to execute
 * @param arg1 first argument for the control function
 * @param arg2 second argument for the control function
 * @return the result of the control function
 */
devcall ethloopControl(device *devptr, int func, long arg1, long arg2)
{
    struct ethloop *elpptr;
    struct netaddr *addr;
    uchar old;
    irqmask im;
    char *buf;
    char *hold;
    int holdlen;

    elpptr = &elooptab[devptr->minor];

    im = disable();
    if (ELOOP_STATE_ALLOC != elpptr->state)
    {
        restore(im);
        return SYSERR;
    }

    switch (func)
    {
/* Get link header length. */
    case NET_GET_LINKHDRLEN:
        restore(im);
        return ETH_HDR_LEN;

/* Get MAC address from card. */
    case NET_GET_HWADDR:
        restore(im);
        addr = (struct netaddr *)arg1;
        addr->type = NETADDR_ETHERNET;
        addr->len = ETH_ADDR_LEN;
        addr->addr[0] = 0xAA;
        addr->addr[1] = 0xBB;
        addr->addr[2] = 0xCC;
        addr->addr[3] = 0xDD;
        addr->addr[4] = 0xEE;
        addr->addr[5] = 0xFF;
        break;

/* Get broadcast MAC address. */
    case NET_GET_HWBRC:
        restore(im);
        addr = (struct netaddr *)arg1;
        addr->type = NETADDR_ETHERNET;
        addr->len = ETH_ADDR_LEN;
        addr->addr[0] = 0xFF;
        addr->addr[1] = 0xFF;
        addr->addr[2] = 0xFF;
        addr->addr[3] = 0xFF;
        addr->addr[4] = 0xFF;
        addr->addr[5] = 0xFF;
        break;

/* Get MTU. */
    case NET_GET_MTU:
        restore(im);
        return ELOOP_MTU;

/* Get next packet off hold queue */
    case ELOOP_CTRL_GETHOLD:
        buf = (char *)arg1;
        /* Wait for held packet */
        wait(elpptr->hsem);
        /* Get and clear held packet */
        hold = elpptr->hold;
        holdlen = elpptr->holdlen;
        elpptr->hold = NULL;
        elpptr->holdlen = 0;
        restore(im);
        /* Copy held packet to buffer */
        if (arg2 < holdlen)
        {
            holdlen = arg2;
        }
        memcpy(buf, hold, holdlen);
        /* Free hold buffer */
        buffree(hold);
        return holdlen;

/* Set flags */
    case ELOOP_CTRL_SETFLAG:
        old = elpptr->flags & arg1;
        elpptr->flags |= (arg1);
        restore(im);
        return old;

/* Clear flags */
    case ELOOP_CTRL_CLRFLAG:
        old = elpptr->flags & arg1;
        elpptr->flags &= ~(arg1);
        restore(im);
        return old;

    default:
        restore(im);
        return SYSERR;
    }
    restore(im);
    return OK;
}
Exemplo n.º 15
0
int
main(int argc, char **argv)
{
    if (argc < 2 || argc > 4)
        usage("pattern_file target_file [[-]expected]\ne.g. acism_x patts act.txt -5");

    MEMBUF patt = chomp(slurp(argv[1]));
    if (!patt.ptr)
        die("cannot read %s", argv[1]);

    int npatts;
    MEMREF *pattv = refsplit(patt.ptr, '\n', &npatts);

    double t = tick();
    ACISM *psp = acism_create(pattv, npatts);
    t = tick() - t;

    plan_tests(argc < 3 ? 1 : 3);

    ok(psp, "acism_create(pattv[%d]) compiled, in %.3f secs", npatts, t);
    acism_dump(psp, PS_ALL, stderr, pattv);
#ifdef ACISM_STATS
    {
    int i;
    for (i = 1; i < (int)psstat[0].val; ++i)
        if (psstat[i].val)
            fprintf(stderr, "%11llu %s\n", psstat[i].val, psstat[i].name);
    }
#endif//ACISM_STATS

    diag("state machine saved as acism.tmp");
    FILE *fp = FOPEN("acism.tmp", "w");
    acism_save(fp, psp);
    fclose(fp);

    if (argc > 2) {
        // Negative count => print match details
        int expected = argc > 3 ? atoi(argv[3]) : 0;
        int details = expected < 0;
        if (details) expected = -expected;
        FILE*	textfp = FOPEN(argv[2], "r");		// REUSE PATTERN FILE AS A TARGET
        if (!fp) die("cannot open %s", argv[2]);
        static char buf[1024*1024];
        MEMREF		text = {buf, 0};
        int			state = 0;
        double		elapsed = 0, start = tick();
        while (0 < (text.len = fread(buf, sizeof*buf, sizeof buf, textfp))) {
            t = tick();
            (void)acism_more(psp, text, (ACISM_ACTION*)on_match, pattv, &state);
            elapsed += tick() - t;
            putc('.', stderr);
        }
        putc('\n', stderr);
        fclose(textfp);
        ok(text.len == 0, "text_file scanned in 1M blocks; read(s) took %.3f secs", tick() - start - elapsed);

        if (!ok(actual == expected || expected == 0, "%d matches found, in %.3f secs", actual, elapsed))
            diag("actual: %d\n", actual);
    }

    buffree(patt);
    free(pattv);
    acism_destroy(psp);

    return exit_status();
}
Exemplo n.º 16
0
syscall rtpFreebuf(struct rtpPkt *rtppkt)
{
    return buffree(rtppkt);
}
Exemplo n.º 17
0
static void serve(struct muth *muth, va_list args)
{
    vavar(struct hthead *, req);
    vavar(int, fd);
    vavar(int, sfd);
    FILE *is, *os, *outi, *outo, *erri, *erro;
    struct charbuf head;
    struct hthead *resp;
    size_t read;
    char buf[8192];
    
    sfd = reconn();
    is = mtstdopen(fd, 1, 60, "r+", NULL);
    os = mtstdopen(sfd, 1, 600, "r+", NULL);
    
    outi = NULL;
    mtiopipe(&outi, &outo); mtiopipe(&erri, &erro);
    mustart(outplex, mtstdopen(dup(sfd), 1, 600, "r+", NULL), outo, FCGI_STDOUT, erro, FCGI_STDERR, NULL);
    mustart(errhandler, erri);
    
    if(begreq(os, 1))
	goto out;
    bufinit(head);
    mkcgienv(req, &head);
    if(sendrec(os, FCGI_PARAMS, 1, head.b, head.d))
	goto out;
    if(sendrec(os, FCGI_PARAMS, 1, NULL, 0))
	goto out;
    buffree(head);
    if(fflush(os))
	goto out;
    
    while(!feof(is)) {
	read = fread(buf, 1, sizeof(buf), is);
	if(ferror(is))
	    goto out;
	if(sendrec(os, FCGI_STDIN, 1, buf, read))
	    goto out;
    }
    if(sendrec(os, FCGI_STDIN, 1, NULL, 0))
	goto out;
    if(fflush(os))
	goto out;
    
    if((resp = parseresp(outi)) == NULL)
	goto out;
    writeresp(is, resp);
    freehthead(resp);
    fputc('\n', is);
    if(passdata(outi, is) < 0)
	goto out;
    
out:
    freehthead(req);
    buffree(head);
    shutdown(sfd, SHUT_RDWR);
    if(outi != NULL)
	fclose(outi);
    fclose(is);
    fclose(os);
}
Exemplo n.º 18
0
Arquivo: req.c Projeto: dolda2000/ashd
int parseheadersb(struct hthead *head, struct bufio *in)
{
    int c, state;
    struct charbuf name, val;
    size_t tsz;
    
    bufinit(name);
    bufinit(val);
    state = 0;
    tsz = 0;
    while(1) {
	c = biogetc(in);
	if(++tsz >= 65536)
	    goto fail;
    again:
	if(state == 0) {
	    if(c == '\r') {
	    } else if(c == '\n') {
		break;
	    } else if(c == EOF) {
		goto fail;
	    } else {
		state = 1;
		goto again;
	    }
	} else if(state == 1) {
	    if(c == ':') {
		trim(&name);
		bufadd(name, 0);
		state = 2;
	    } else if(c == '\r') {
	    } else if(c == '\n') {
		goto fail;
	    } else if(c == EOF) {
		goto fail;
	    } else {
		bufadd(name, c);
	    }
	} else if(state == 2) {
	    if(c == '\r') {
	    } else if(c == '\n') {
		trim(&val);
		bufadd(val, 0);
		headappheader(head, name.b, val.b);
		buffree(name);
		buffree(val);
		state = 0;
	    } else if(c == EOF) {
		goto fail;
	    } else {
		bufadd(val, c);
	    }
	}
    }
    return(0);
    
fail:
    buffree(name);
    buffree(val);
    return(-1);
}
Exemplo n.º 19
0
Arquivo: req.c Projeto: dolda2000/ashd
struct hthead *parseresponseb(struct bufio *in)
{
    struct hthead *req;
    int code;
    struct charbuf ver, msg;
    int c;
    
    req = NULL;
    bufinit(ver);
    bufinit(msg);
    code = 0;
    while(1) {
	c = biogetc(in);
	if(c == ' ') {
	    break;
	} else if((c == EOF) || (c < 32) || (c >= 128)) {
	    goto fail;
	} else {
	    bufadd(ver, c);
	    if(ver.d >= 128)
		goto fail;
	}
    }
    while(1) {
	c = biogetc(in);
	if(c == ' ') {
	    break;
	} else if((c == EOF) || (c < '0') || (c > '9')) {
	    goto fail;
	} else {
	    code = (code * 10) + (c - '0');
	    if(code >= 10000)
		goto fail;
	}
    }
    while(1) {
	c = biogetc(in);
	if(c == 10) {
	    break;
	} else if(c == 13) {
	} else if((c == EOF) || (c < 32)) {
	    goto fail;
	} else {
	    bufadd(msg, c);
	    if(msg.d >= 512)
		goto fail;
	}
    }
    bufadd(msg, 0);
    bufadd(ver, 0);
    req = mkresp(code, msg.b, ver.b);
    if(parseheadersb(req, in))
	goto fail;
    goto out;
    
fail:
    if(req != NULL) {
	freehthead(req);
	req = NULL;
    }
out:
    buffree(msg);
    buffree(ver);
    return(req);
}
Exemplo n.º 20
0
thread test_bufpool(bool verbose)
{
    bool passed = TRUE;
    int id, i;
    void *pbuf;
    void *chain[TBUFNUM];
    irqmask im;
    ulong memsize;
    char datums[] = { "abcdefghijklmnopqrstuvwxyz1234567" };

    /* Create buffer pool */
    testPrint(verbose, "Create buffer pool");
    im = disable();
    memsize = memlist.length;
    id = bfpalloc(TBUFSIZE, TBUFNUM);
    if (memlist.length !=
        memsize - ((TBUFSIZE + sizeof(struct poolbuf)) * TBUFNUM))
    {
        restore(im);
        testFail(verbose,
                 "\nmemlist.length reduction does not match pool size");
        return OK;
    }
    else
    {
        restore(im);
        testPass(verbose, "");
    }

    /* Allocate single buffer */
    testPrint(verbose, "Allocate single buffer");
    pbuf = bufget(id);
    if (SYSERR == (ulong)pbuf)
    {
        passed = FALSE;
        testFail(verbose, "\nbufget() returns SYSERR");
    }
    else
    {
        testPass(verbose, "");
        /* Return single buffer */
        testPrint(verbose, "Return single buffer");
        if (SYSERR == buffree(pbuf))
        {
            passed = FALSE;
            testFail(verbose, "\nbuffree() returns SYSERR");
        }
        else
        {
            testPass(verbose, "");
        }
    }

    /* Allocate and fill all buffers in pool */
    testPrint(verbose, "Allocate and fill all buffers");
    for (i = 0; i < TBUFNUM; i++)
    {
        pbuf = bufget(id);
        chain[i] = pbuf;
        if (SYSERR == (ulong)pbuf)
        {
            break;
        }
        memcpy(pbuf, datums, TBUFSIZE);
    }
    if (TBUFNUM != i)
    {
        passed = FALSE;
        testFail(verbose, "\ngetbuf() returns SYSERR");
    }
    else
    {
        for (i = 0; i < TBUFNUM; i++)
        {
            pbuf = chain[i];
            if (0 != memcmp(pbuf, datums, TBUFSIZE))
            {
                break;
            }
        }
        if (TBUFNUM != i)
        {
            passed = FALSE;
            testFail(verbose, "\nbuffer data does not match source");
        }
        else
        {
            testPass(verbose, "");
            /* Free all buffers in pool */
            testPrint(verbose, "Free all buffers");
            for (i = 0; i < TBUFNUM; i++)
            {
                pbuf = chain[i];
                if (SYSERR == buffree(pbuf))
                {
                    break;
                }
            }
            if (TBUFNUM != i)
            {
                passed = FALSE;
                testFail(verbose, "\nbuffree() returns SYSERR");
            }
            else
            {
                testPass(verbose, "");
            }
        }
    }

    /* Release pool */
    testPrint(verbose, "Free buffer pool");
    im = disable();
    memsize = memlist.length;
    bfpfree(id);
    if (memlist.length !=
        memsize + ((TBUFSIZE + sizeof(struct poolbuf)) * TBUFNUM))
    {
        restore(im);
        passed = FALSE;
        testFail(verbose,
                 "\nmemlist.length increase does not match pool size");
    }
    else
    {
        restore(im);
        testPass(verbose, "");
    }

    /* Final report */
    if (TRUE == passed)
    {
        testPass(TRUE, "");
    }
    else
    {
        testFail(TRUE, "");
    }

    return OK;
}