]> git.ipfire.org Git - thirdparty/bash.git/blob - include/ocache.h
Imported from ../bash-4.0-rc1.tar.gz.
[thirdparty/bash.git] / include / ocache.h
1 /* ocache.h -- a minimal object caching implementation. */
2
3 /* Copyright (C) 2002 Free Software Foundation, Inc.
4
5 This file is part of GNU Bash, the Bourne Again SHell.
6
7 Bash is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 Bash is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Bash. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #if !defined (_OCACHE_H_)
22 #define _OCACHE_H_ 1
23
24 #ifndef PTR_T
25
26 #if defined (__STDC__)
27 # define PTR_T void *
28 #else
29 # define PTR_T char *
30 #endif
31
32 #endif /* PTR_T */
33
34 #define OC_MEMSET(memp, xch, nbytes) \
35 do { \
36 if ((nbytes) <= 32) { \
37 register char * mzp = (char *)(memp); \
38 unsigned long mctmp = (nbytes); \
39 register long mcn; \
40 if (mctmp < 8) mcn = 0; else { mcn = (mctmp-1)/8; mctmp &= 7; } \
41 switch (mctmp) { \
42 case 0: for(;;) { *mzp++ = xch; \
43 case 7: *mzp++ = xch; \
44 case 6: *mzp++ = xch; \
45 case 5: *mzp++ = xch; \
46 case 4: *mzp++ = xch; \
47 case 3: *mzp++ = xch; \
48 case 2: *mzp++ = xch; \
49 case 1: *mzp++ = xch; if(mcn <= 0) break; mcn--; } \
50 } \
51 } else \
52 memset ((memp), (xch), (nbytes)); \
53 } while(0)
54
55 typedef struct objcache {
56 PTR_T data;
57 int cs; /* cache size, number of objects */
58 int nc; /* number of cache entries */
59 } sh_obj_cache_t;
60
61 /* Create an object cache C of N pointers to OTYPE. */
62 #define ocache_create(c, otype, n) \
63 do { \
64 (c).data = xmalloc((n) * sizeof (otype *)); \
65 (c).cs = (n); \
66 (c).nc = 0; \
67 } while (0)
68
69 /* Destroy an object cache C. */
70 #define ocache_destroy(c) \
71 do { \
72 if ((c).data) \
73 xfree ((c).data); \
74 (c).data = 0; \
75 (c).cs = (c).nc = 0; \
76 } while (0)
77
78 /* Free all cached items, which are pointers to OTYPE, in object cache C. */
79 #define ocache_flush(c, otype) \
80 do { \
81 while ((c).nc > 0) \
82 xfree (((otype **)((c).data))[--(c).nc]); \
83 } while (0)
84
85 /*
86 * Allocate a new item of type pointer to OTYPE, using data from object
87 * cache C if any cached items exist, otherwise calling xmalloc. Return
88 * the object in R.
89 */
90 #define ocache_alloc(c, otype, r) \
91 do { \
92 if ((c).nc > 0) { \
93 (r) = (otype *)((otype **)((c).data))[--(c).nc]; \
94 } else \
95 (r) = (otype *)xmalloc (sizeof (otype)); \
96 } while (0)
97
98 /*
99 * Free an item R of type pointer to OTYPE, adding to object cache C if
100 * there is room and calling xfree if the cache is full. If R is added
101 * to the object cache, the contents are scrambled.
102 */
103 #define ocache_free(c, otype, r) \
104 do { \
105 if ((c).nc < (c).cs) { \
106 OC_MEMSET ((r), 0xdf, sizeof(otype)); \
107 ((otype **)((c).data))[(c).nc++] = (r); \
108 } else \
109 xfree (r); \
110 } while (0)
111
112 /*
113 * One may declare and use an object cache as (for instance):
114 *
115 * sh_obj_cache_t wdcache = {0, 0, 0};
116 * sh_obj_cache_t wlcache = {0, 0, 0};
117 *
118 * ocache_create(wdcache, WORD_DESC, 30);
119 * ocache_create(wlcache, WORD_LIST, 30);
120 *
121 * WORD_DESC *wd;
122 * ocache_alloc (wdcache, WORD_DESC, wd);
123 *
124 * WORD_LIST *wl;
125 * ocache_alloc (wlcache, WORD_LIST, wl);
126 *
127 * ocache_free(wdcache, WORD_DESC, wd);
128 * ocache_free(wlcache, WORD_LIST, wl);
129 *
130 * The use is almost arbitrary.
131 */
132
133 #endif /* _OCACHE_H */