2 * Copyright 2000, International Business Machines Corporation and others.
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
10 #include <afsconfig.h>
11 #include "afs/param.h"
14 #include "afs/sysincludes.h" /* Standard vendor system headers */
15 #include "afsincludes.h" /* Afs-based standard headers */
16 #include "afs/afs_stats.h" /* statistics */
18 static struct axscache
*afs_axsfreelist
= NULL
;
20 #define NAXSs (1000 / sizeof(struct axscache))
21 static struct xfreelist
{
22 struct xfreelist
*next
;
23 struct axscache data
[NAXSs
];
25 static int afs_xaxscnt
= 0;
26 afs_rwlock_t afs_xaxs
;
28 /* takes an address of an access cache & uid, returns ptr */
29 /* PRECONDITION: first field has been checked and doesn't match!
30 * INVARIANT: isparent(i,j) ^ isparent(j,i) (ie, they switch around)
33 afs_SlowFindAxs(struct axscache
**cachep
, afs_int32 id
)
35 struct axscache
*i
, *j
;
41 axs_Front(cachep
, j
, i
); /* maintain LRU queue */
45 if ((j
= i
->next
)) { /* ASSIGNMENT HERE! */
47 axs_Front(cachep
, i
, j
);
61 struct axscache
*i
, *j
;
62 struct xfreelist
*h
, *xsp
;
65 ObtainWriteLock(&afs_xaxs
, 174);
66 if ((i
= afs_axsfreelist
)) {
67 afs_axsfreelist
= i
->next
;
68 ReleaseWriteLock(&afs_xaxs
);
71 h
= afs_osi_Alloc(sizeof(struct xfreelist
));
72 osi_Assert(h
!= NULL
);
76 xfreemallocs
->next
= xsp
;
78 for (k
= 0; k
< NAXSs
- 1; k
++, i
++) {
81 i
->next
= ++j
; /* need j because order of evaluation not defined */
86 afs_axsfreelist
= (h
->data
)->next
;
88 ReleaseWriteLock(&afs_xaxs
);
93 #define axs_Free(axsp) { \
94 ObtainWriteLock(&afs_xaxs,175); \
95 axsp->next = afs_axsfreelist; \
96 afs_axsfreelist = axsp; \
97 ReleaseWriteLock(&afs_xaxs); \
101 /* I optimize for speed on lookup, and don't give a RIP about delete.
104 afs_RemoveAxs(struct axscache
**headp
, struct axscache
*axsp
)
106 struct axscache
*i
, *j
;
108 if (*headp
&& axsp
) { /* is bullet-proofing really neccessary? */
109 if (*headp
== axsp
) { /* most common case, I think */
124 if ((i
= j
->next
)) { /* ASSIGNMENT HERE! */
131 /* end of "if neither pointer is NULL" */
132 return; /* !#@ FAILED to find it! */
137 * Takes an entire list of access cache structs and prepends them, lock, stock,
138 * and barrel, to the front of the freelist.
141 afs_FreeAllAxs(struct axscache
**headp
)
143 struct axscache
*i
, *j
;
148 while (i
) { /* chase down the list 'til we reach the end */
151 ObtainWriteLock(&afs_xaxs
, 176);
152 i
->next
= afs_axsfreelist
; /* tack on the freelist to the end */
153 afs_axsfreelist
= *headp
;
154 ReleaseWriteLock(&afs_xaxs
);
161 if (j
) { /* we ran off the end of the list... */
162 ObtainWriteLock(&afs_xaxs
, 177);
163 j
->next
= afs_axsfreelist
; /* tack on the freelist to the end */
164 afs_axsfreelist
= *headp
;
165 ReleaseWriteLock(&afs_xaxs
);
173 shutdown_xscache(void)
175 struct xfreelist
*xp
, *nxp
;
177 AFS_RWLOCK_INIT(&afs_xaxs
, "afs_xaxs");
181 afs_osi_Free(xp
, sizeof(struct xfreelist
));
184 afs_axsfreelist
= NULL
;