|
|
1.1 root 1: /*
2: * C H A L L O C
3: *
4: * Memory allocation/deallocation routines for Chaosnet line discipline.
5: *
6: *
7: * (c) Copyright 1984 Nirvonics, Inc.
8: *
9: * Written by Kurt Gollhardt
10: * Last update Mon Nov 12 16:27:57 1984
11: *
12: * This software is the property of Nirvonics, Inc.
13: * All rights reserved.
14: *
15: */
16:
17: #include "ch.h"
18: #if NCH > 0
19: #include "../h/param.h"
20: #include "../h/stream.h"
21: #include "../h/conf.h"
22: #include "../h/buf.h"
23: #include "../chaosld/constants.h"
24: #include "../chaosld/types.h"
25: #include "../chaosld/globals.h"
26:
27: #define CHBLKSIZE BSIZE(0)
28:
29: static caddr_t ch_alloc();
30: static ch_free();
31:
32:
33: static struct buf *pkhead;
34:
35: struct packet *pkalloc()
36: {
37: return (struct packet *)ch_alloc(sizeof(struct packet), &pkhead);
38: }
39:
40: pkfree(pkt)
41: struct packet *pkt;
42: {
43: ch_free((caddr_t)pkt, sizeof(struct packet), &pkhead);
44: }
45:
46:
47: static struct buf *cnhead;
48:
49: struct connection *cnalloc()
50: {
51: return (struct connection *)ch_alloc(sizeof(struct connection), &cnhead);
52: }
53:
54: cnfree(conn)
55: struct connection *conn;
56: {
57: ch_free((caddr_t)conn, sizeof(struct connection), &cnhead);
58: }
59:
60:
61: #define NOBUF (struct buf *)0
62: #define ALIGN(n) (((n) + sizeof(int) - 1) & ~(sizeof(int) - 1))
63:
64: static caddr_t ch_alloc(size, head)
65: struct buf **head;
66: {
67: register struct buf *bufp;
68: register int i;
69: int ps = spl6();
70:
71: debug(DALLOC,printf("ch_alloc: size=0x%lx ", size));
72:
73: for (bufp = *head; bufp != NOBUF;) {
74: if (bufp->b_resid > 0)
75: break;
76: if ((bufp = bufp->av_forw) == *head)
77: bufp = NOBUF;
78: }
79: debug(DALLOC,printf("bufp=0x%lx ", bufp));
80:
81: if (bufp == NOBUF) {
82: if ((bufp = geteblk()) == NOBUF) {
83: debug(DALLOC|DABNOR,printf("No more buffers available\n"));
84: return NOBUF;
85: }
86: if (*head == NOBUF)
87: *head = bufp->av_forw = bufp->av_back = bufp;
88: else {
89: bufp->av_forw = (*head)->av_forw;
90: bufp->av_back = (*head)->av_back;
91: bufp->av_forw->av_back = bufp->av_back->av_forw = bufp;
92: }
93: bufp->b_bcount = CHBLKSIZE / (size + 1);
94: if (ALIGN(bufp->b_bcount) + size * bufp->b_bcount > CHBLKSIZE)
95: bufp->b_bcount--;
96: bfill(bufp->b_un.b_addr, bufp->b_resid = bufp->b_bcount, 0);
97: debug(DALLOC,printf("new bufp=0x%lx bcount=%d ", bufp, bufp->b_bcount));
98: }
99:
100: for (i = 0; i < bufp->b_bcount; ++i)
101: if (bufp->b_un.b_addr[i] == 0)
102: break;
103: debug(DALLOC,printf("i = %d\n", i));
104:
105: bufp->b_un.b_addr[i] = 1;
106: bufp->b_resid--;
107:
108: splx(ps);
109: return bufp->b_un.b_addr + ALIGN(bufp->b_bcount) + i * size;
110: }
111:
112:
113: static ch_free(addr, size, head)
114: caddr_t addr;
115: struct buf **head;
116: {
117: register struct buf *bufp;
118: register int i;
119: int ps = spl6();
120:
121: debug(DALLOC,printf("ch_free: addr=0x%lx size=0x%lx ", addr, size));
122:
123: for (bufp = *head; bufp != NOBUF;) {
124: i = (addr - bufp->b_un.b_addr - ALIGN(bufp->b_bcount)) / size;
125: if (i >= 0 && i < bufp->b_bcount)
126: break;
127: if ((bufp = bufp->av_forw) == *head)
128: bufp = NOBUF;
129: }
130: debug(DALLOC,printf("bufp=0x%lx i=%d\n", bufp, i));
131:
132: if (bufp == NOBUF || bufp->b_un.b_addr[i] == 0) {
133: splx(ps);
134: printf("CHAOS: freeing un-allocated object %x (ch_free)\n", addr);
135: return;
136: }
137:
138: bufp->b_un.b_addr[i] = 0;
139: if (++bufp->b_resid == bufp->b_bcount) {
140: if (bufp->av_forw == bufp)
141: *head = NOBUF;
142: else {
143: bufp->av_forw->av_back = bufp->av_back;
144: bufp->av_back->av_forw = bufp->av_forw;
145: if (*head == bufp)
146: *head = bufp->av_forw;
147: }
148: brelse(bufp);
149: debug(DALLOC,printf("ch_free: released buf 0x%lx\n", bufp));
150: }
151:
152: splx(ps);
153: }
154:
155: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.