aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/venti/srv/zblock.c
blob: 80b240647114d26d1e1fb2e8633b0bc394dcd627 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include "stdinc.h"
#include "dat.h"
#include "fns.h"

void
fmtzbinit(Fmt *f, ZBlock *b)
{
	memset(f, 0, sizeof *f);
#ifdef PLAN9PORT
	fmtlocaleinit(f, nil, nil, nil);
#endif
	f->start = b->data;
	f->to = f->start;
	f->stop = (char*)f->start + b->len;
}

#define ROUNDUP(p, n) ((void*)(((uintptr)(p)+(n)-1)&~(uintptr)((n)-1)))

enum {
	OverflowCheck = 32
};
static char zmagic[] = "1234567890abcdefghijklmnopqrstuvxyz";

ZBlock *
alloczblock(u32int size, int zeroed, uint blocksize)
{
	uchar *p, *data;
	ZBlock *b;
	static ZBlock z;
	int n;

	if(blocksize == 0)
		blocksize = 32;	/* try for cache line alignment */

	n = size+OverflowCheck+sizeof(ZBlock)+blocksize+8;
	p = malloc(n);
	if(p == nil){
		seterr(EOk, "out of memory");
		return nil;
	}

	data = ROUNDUP(p, blocksize);
	b = ROUNDUP(data+size+OverflowCheck, 8);
	if(0) fprint(2, "alloc %p-%p data %p-%p b %p-%p\n",
		p, p+n, data, data+size, b, b+1);
	*b = z;
	b->data = data;
	b->free = p;
	b->len = size;
	b->_size = size;
	if(zeroed)
		memset(b->data, 0, size);
	memmove(b->data+size, zmagic, OverflowCheck);
	return b;
}

void
freezblock(ZBlock *b)
{
	if(b){
		if(memcmp(b->data+b->_size, zmagic, OverflowCheck) != 0)
			abort();
		memset(b->data+b->_size, 0, OverflowCheck);
		free(b->free);
	}
}

ZBlock*
packet2zblock(Packet *p, u32int size)
{
	ZBlock *b;

	if(p == nil)
		return nil;
	b = alloczblock(size, 0, 0);
	if(b == nil)
		return nil;
	if(packetcopy(p, b->data, 0, size) < 0){
		freezblock(b);
		return nil;
	}
	return b;
}

Packet*
zblock2packet(ZBlock *zb, u32int size)
{
	Packet *p;

	if(zb == nil)
		return nil;
	p = packetalloc();
	packetappend(p, zb->data, size);
	return p;
}