Remove the RCSID macro
[openafs.git] / src / afs / afs_osi_alloc.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #include <afsconfig.h>
11 #include "afs/param.h"
12
13
14
15
16 #include "afs/sysincludes.h"    /* Standard vendor system headers */
17 #include "afsincludes.h"        /* Afs-based standard headers */
18 #include "afs/afs_stats.h"      /* afs statistics */
19
20
21
22 #ifdef AFS_AIX41_ENV
23 #include "sys/lockl.h"
24 #include "sys/sleep.h"
25 #include "sys/syspest.h"
26 #include "sys/lock_def.h"
27 /*lock_t osi_fsplock = LOCK_AVAIL;*/
28 #endif
29
30 afs_lock_t osi_fsplock;
31
32
33
34 static struct osi_packet {
35     struct osi_packet *next;
36 } *freePacketList = NULL, *freeSmallList;
37 afs_lock_t osi_flplock;
38
39 static char memZero;            /* address of 0 bytes for kmem_alloc */
40
41 struct osimem {
42     struct osimem *next;
43 };
44
45
46 void *
47 afs_osi_Alloc(size_t x)
48 {
49 #if !defined(AFS_LINUX20_ENV) && !defined(AFS_FBSD_ENV)
50     register struct osimem *tm = NULL;
51     register int size;
52 #endif
53
54     AFS_STATCNT(osi_Alloc);
55     /* 0-length allocs may return NULL ptr from AFS_KALLOC, so we special-case
56      * things so that NULL returned iff an error occurred */
57     if (x == 0)
58         return &memZero;
59
60     AFS_STATS(afs_stats_cmperf.OutStandingAllocs++);
61     AFS_STATS(afs_stats_cmperf.OutStandingMemUsage += x);
62 #ifdef AFS_LINUX20_ENV
63     return osi_linux_alloc(x, 1);
64 #elif defined(AFS_FBSD_ENV)
65     return osi_fbsd_alloc(x, 1);
66 #else
67     size = x;
68     tm = (struct osimem *)AFS_KALLOC(size);
69 #ifdef  AFS_SUN5_ENV
70     if (!tm)
71         osi_Panic("osi_Alloc: Couldn't allocate %d bytes; out of memory!\n",
72                   size);
73 #endif
74     return (void *)tm;
75 #endif
76 }
77
78 #if     defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV)
79
80 void *
81 afs_osi_Alloc_NoSleep(size_t x)
82 {
83     register struct osimem *tm;
84     register int size;
85
86     AFS_STATCNT(osi_Alloc);
87     /* 0-length allocs may return NULL ptr from AFS_KALLOC, so we special-case
88      * things so that NULL returned iff an error occurred */
89     if (x == 0)
90         return &memZero;
91
92     size = x;
93     AFS_STATS(afs_stats_cmperf.OutStandingAllocs++);
94     AFS_STATS(afs_stats_cmperf.OutStandingMemUsage += x);
95     tm = (struct osimem *)AFS_KALLOC_NOSLEEP(size);
96     return (void *)tm;
97 }
98
99 #endif /* SUN || SGI */
100
101 void
102 afs_osi_Free(void *x, size_t asize)
103 {
104     AFS_STATCNT(osi_Free);
105     if (x == &memZero)
106         return;                 /* check for putting memZero back */
107
108     AFS_STATS(afs_stats_cmperf.OutStandingAllocs--);
109     AFS_STATS(afs_stats_cmperf.OutStandingMemUsage -= asize);
110 #if defined(AFS_LINUX20_ENV)
111     osi_linux_free(x);
112 #elif defined(AFS_FBSD_ENV)
113     osi_fbsd_free(x);
114 #elif defined(AFS_OBSD44_ENV)
115     osi_obsd_Free(x, asize);
116 #else
117     AFS_KFREE((struct osimem *)x, asize);
118 #endif
119 }
120
121 void
122 afs_osi_FreeStr(char *x)
123 {
124     afs_osi_Free(x, strlen(x) + 1);
125 }
126
127
128
129 /* free space allocated by AllocLargeSpace.  Also called by mclput when freeing
130  * a packet allocated by osi_NetReceive. */
131
132 void
133 osi_FreeLargeSpace(void *adata)
134 {
135
136     AFS_ASSERT_GLOCK();
137
138     AFS_STATCNT(osi_FreeLargeSpace);
139     afs_stats_cmperf.LargeBlocksActive--;
140     MObtainWriteLock(&osi_flplock, 322);
141     ((struct osi_packet *)adata)->next = freePacketList;
142     freePacketList = adata;
143     MReleaseWriteLock(&osi_flplock);
144 }
145
146 void
147 osi_FreeSmallSpace(void *adata)
148 {
149
150     AFS_ASSERT_GLOCK();
151
152     AFS_STATCNT(osi_FreeSmallSpace);
153     afs_stats_cmperf.SmallBlocksActive--;
154     MObtainWriteLock(&osi_fsplock, 323);
155     ((struct osi_packet *)adata)->next = freeSmallList;
156     freeSmallList = adata;
157     MReleaseWriteLock(&osi_fsplock);
158 }
159
160
161 /* allocate space for sender */
162 void *
163 osi_AllocLargeSpace(size_t size)
164 {
165     register struct osi_packet *tp;
166
167     AFS_ASSERT_GLOCK();
168
169     AFS_STATCNT(osi_AllocLargeSpace);
170     if (size > AFS_LRALLOCSIZ)
171         osi_Panic("osi_AllocLargeSpace: size=%d\n", (int)size);
172     afs_stats_cmperf.LargeBlocksActive++;
173     if (!freePacketList) {
174         char *p;
175
176         afs_stats_cmperf.LargeBlocksAlloced++;
177         p = (char *)afs_osi_Alloc(AFS_LRALLOCSIZ);
178 #ifdef  KERNEL_HAVE_PIN
179         /*
180          * Need to pin this memory since under heavy conditions this memory
181          * could be swapped out; the problem is that we could inside rx where
182          * interrupts are disabled and thus we would panic if we don't pin it.
183          */
184         pin(p, AFS_LRALLOCSIZ);
185 #endif
186         return p;
187     }
188     MObtainWriteLock(&osi_flplock, 324);
189     tp = freePacketList;
190     if (tp)
191         freePacketList = tp->next;
192     MReleaseWriteLock(&osi_flplock);
193     return (char *)tp;
194 }
195
196
197 /* allocate space for sender */
198 void *
199 osi_AllocSmallSpace(size_t size)
200 {
201     register struct osi_packet *tp;
202
203     AFS_STATCNT(osi_AllocSmallSpace);
204     if (size > AFS_SMALLOCSIZ)
205         osi_Panic("osi_AllocSmallS: size=%d\n", (int)size);
206
207     if (!freeSmallList) {
208         afs_stats_cmperf.SmallBlocksAlloced++;
209         afs_stats_cmperf.SmallBlocksActive++;
210         tp = afs_osi_Alloc(AFS_SMALLOCSIZ);
211 #ifdef KERNEL_HAVE_PIN
212         pin((char *)tp, AFS_SMALLOCSIZ);
213 #endif
214         return (char *)tp;
215     }
216     afs_stats_cmperf.SmallBlocksActive++;
217     MObtainWriteLock(&osi_fsplock, 327);
218     tp = freeSmallList;
219     if (tp)
220         freeSmallList = tp->next;
221     MReleaseWriteLock(&osi_fsplock);
222     return (char *)tp;
223 }
224
225
226
227 void
228 shutdown_osinet(void)
229 {
230     AFS_STATCNT(shutdown_osinet);
231     if (afs_cold_shutdown) {
232         struct osi_packet *tp;
233
234         while ((tp = freePacketList)) {
235             freePacketList = tp->next;
236             afs_osi_Free(tp, AFS_LRALLOCSIZ);
237 #ifdef  KERNEL_HAVE_PIN
238             unpin(tp, AFS_LRALLOCSIZ);
239 #endif
240         }
241
242         while ((tp = freeSmallList)) {
243             freeSmallList = tp->next;
244             afs_osi_Free(tp, AFS_SMALLOCSIZ);
245 #ifdef  KERNEL_HAVE_PIN
246             unpin(tp, AFS_SMALLOCSIZ);
247 #endif
248         }
249         LOCK_INIT(&osi_fsplock, "osi_fsplock");
250         LOCK_INIT(&osi_flplock, "osi_flplock");
251     }
252     if (afs_stats_cmperf.LargeBlocksActive || 
253         afs_stats_cmperf.SmallBlocksActive) 
254     {
255         afs_warn("WARNING: not all blocks freed: large %d small %d\n", 
256                  afs_stats_cmperf.LargeBlocksActive, 
257                  afs_stats_cmperf.SmallBlocksActive);
258     }
259 }
260