FreeBSD/Linux Kernel Cross Reference
sys/cam/cam_extend.c
1 /*
2 * Written by Julian Elischer (julian@tfs.com)
3 * for TRW Financial Systems for use under the MACH(2.5) operating system.
4 *
5 * TRW Financial Systems, in accordance with their agreement with Carnegie
6 * Mellon University, makes this software available to CMU to distribute
7 * or use in any manner that they see fit as long as this message is kept with
8 * the software. For this reason TFS also grants any other persons or
9 * organisations permission to use or modify this software.
10 *
11 * TFS supplies this software to be publicly redistributed
12 * on the understanding that TFS is not responsible for the correct
13 * functioning of this software in any circumstances.
14 *
15 * $FreeBSD$
16 */
17 /*
18 * XXX XXX XXX XXX We should get DEVFS working so that we
19 * don't have to do this, possibly sparse, array based junk.
20 * XXX: We can do this now with dev_t, that's even better.
21 */
22 /*
23 * Extensible arrays: Use a realloc like implementation to permit
24 * the arrays to be extend.
25 */
26 #include <sys/param.h>
27 #include <sys/systm.h>
28 #include <sys/kernel.h>
29 #include <sys/malloc.h>
30
31 #include <cam/cam_extend.h>
32
33 struct extend_array
34 {
35 int nelem;
36 void **ps;
37 };
38
39 static void *
40 cam_extend_alloc(size_t s)
41 {
42 void *p = malloc(s, M_DEVBUF, M_NOWAIT);
43 if (!p)
44 panic("extend_alloc: malloc failed.");
45 return p;
46 }
47
48 static void
49 cam_extend_free(void *p)
50 {
51 free(p, M_DEVBUF);
52 }
53
54 /* EXTEND_CHUNK: Number of extend slots to allocate whenever we need a new
55 * one.
56 */
57 #ifndef EXTEND_CHUNK
58 #define EXTEND_CHUNK 8
59 #endif
60
61 struct extend_array *
62 cam_extend_new(void)
63 {
64 struct extend_array *p = cam_extend_alloc(sizeof(*p));
65 if (p) {
66 p->nelem = 0;
67 p->ps = 0;
68 }
69
70 return p;
71 }
72
73 void *
74 cam_extend_set(struct extend_array *ea, int index, void *value)
75 {
76 if (index >= ea->nelem) {
77 void **space;
78 space = cam_extend_alloc(sizeof(void *) * (index + EXTEND_CHUNK));
79 bzero(space, sizeof(void *) * (index + EXTEND_CHUNK));
80
81 /* Make sure we have something to copy before we copy it */
82 if (ea->nelem) {
83 bcopy(ea->ps, space, sizeof(void *) * ea->nelem);
84 cam_extend_free(ea->ps);
85 }
86
87 ea->ps = space;
88 ea->nelem = index + EXTEND_CHUNK;
89 }
90 if (ea->ps[index]) {
91 printf("extend_set: entry %d already has storage.\n", index);
92 return 0;
93 }
94 else
95 ea->ps[index] = value;
96
97 return value;
98 }
99
100 void *
101 cam_extend_get(struct extend_array *ea,
102 int index)
103 {
104 if (ea == NULL || index >= ea->nelem || index < 0)
105 return NULL;
106 return ea->ps[index];
107 }
108
109 void
110 cam_extend_release(struct extend_array *ea, int index)
111 {
112 void *p = cam_extend_get(ea, index);
113 if (p) {
114 ea->ps[index] = 0;
115 }
116 }
Cache object: c72f401fdc4a02411407484b599c21d8
|