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 */
21 /*
22 * Extensible arrays: Use a realloc like implementation to permit
23 * the arrays to be extend.
24 */
25 #include <sys/param.h>
26 #include <sys/systm.h>
27 #include <sys/kernel.h>
28 #include <sys/malloc.h>
29
30 #include <cam/cam_extend.h>
31
32 struct extend_array
33 {
34 int nelem;
35 void **ps;
36 };
37
38 static void *
39 cam_extend_alloc(size_t s)
40 {
41 void *p = malloc(s, M_DEVBUF, M_NOWAIT);
42 if (!p)
43 panic("extend_alloc: malloc failed.");
44 return p;
45 }
46
47 static void
48 cam_extend_free(void *p)
49 {
50 free(p, M_DEVBUF);
51 }
52
53 /* EXTEND_CHUNK: Number of extend slots to allocate whenever we need a new
54 * one.
55 */
56 #ifndef EXTEND_CHUNK
57 #define EXTEND_CHUNK 8
58 #endif
59
60 struct extend_array *
61 cam_extend_new(void)
62 {
63 struct extend_array *p = cam_extend_alloc(sizeof(*p));
64 if (p) {
65 p->nelem = 0;
66 p->ps = 0;
67 }
68
69 return p;
70 }
71
72 void *
73 cam_extend_set(struct extend_array *ea, int index, void *value)
74 {
75 if (index >= ea->nelem) {
76 void **space;
77 space = cam_extend_alloc(sizeof(void *) * (index + EXTEND_CHUNK));
78 bzero(space, sizeof(void *) * (index + EXTEND_CHUNK));
79
80 /* Make sure we have something to copy before we copy it */
81 if (ea->nelem) {
82 bcopy(ea->ps, space, sizeof(void *) * ea->nelem);
83 cam_extend_free(ea->ps);
84 }
85
86 ea->ps = space;
87 ea->nelem = index + EXTEND_CHUNK;
88 }
89 if (ea->ps[index]) {
90 printf("extend_set: entry %d already has storage.\n", index);
91 return 0;
92 }
93 else
94 ea->ps[index] = value;
95
96 return value;
97 }
98
99 void *
100 cam_extend_get(struct extend_array *ea,
101 int index)
102 {
103 if (ea == NULL || index >= ea->nelem || index < 0)
104 return NULL;
105 return ea->ps[index];
106 }
107
108 void
109 cam_extend_release(struct extend_array *ea, int index)
110 {
111 void *p = cam_extend_get(ea, index);
112 if (p) {
113 ea->ps[index] = 0;
114 }
115 }
Cache object: 3a75f4158e4bf8e7bb7a541a2978c011
|