1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
9 * Copyright (C) 2003 Tat Tang
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
17 ****************************************************************************/
25 unsigned char data
[1]; /* place holder */
28 #define lru_node_p(pl, x) \
29 ((struct lru_node*)(pl->_base + pl->_slot_size * x))
31 /*******************************************************************************
33 ******************************************************************************/
34 void lru_create(struct lru
* pl
, void *buf
, short size
, short data_size
)
36 pl
->_base
= (unsigned char*) buf
;
37 pl
->_slot_size
= data_size
+ LRU_SLOT_OVERHEAD
;
42 pl
->_tail
= pl
->_size
- 1;
44 /* Initialise slots */
46 for (i
=0; i
<pl
->_size
; i
++)
48 lru_node_p(pl
, i
)->_next
= i
+ 1;
49 lru_node_p(pl
, i
)->_prev
= i
- 1;
52 /* Fix up head and tail to form circular buffer */
53 lru_node_p(pl
, 0)->_prev
= pl
->_tail
;
54 lru_node_p(pl
, pl
->_tail
)->_next
= pl
->_head
;
57 /*******************************************************************************
59 ******************************************************************************/
60 void lru_traverse(struct lru
* pl
, void (*callback
)(void* data
))
63 struct lru_node
* slot
;
64 short loc
= pl
->_head
;
66 for (i
= 0; i
< pl
->_size
; i
++)
68 slot
= lru_node_p(pl
, loc
);
74 /*******************************************************************************
76 ******************************************************************************/
77 void lru_touch(struct lru
* pl
, short handle
)
79 if (handle
== pl
->_head
)
81 pl
->_head
= lru_node_p(pl
, pl
->_head
)->_next
;
82 pl
->_tail
= lru_node_p(pl
, pl
->_tail
)->_next
;
86 if (handle
== pl
->_tail
)
91 /* Remove current node from linked list */
92 struct lru_node
* curr_node
= lru_node_p(pl
, handle
);
93 struct lru_node
* prev_node
= lru_node_p(pl
, curr_node
->_prev
);
94 struct lru_node
* next_node
= lru_node_p(pl
, curr_node
->_next
);
96 prev_node
->_next
= curr_node
->_next
;
97 next_node
->_prev
= curr_node
->_prev
;
99 /* insert current node at tail */
100 struct lru_node
* tail_node
= lru_node_p(pl
, pl
->_tail
);
101 short tail_node_next_handle
= tail_node
->_next
; /* Bug fix */
102 struct lru_node
* tail_node_next
= lru_node_p(pl
, tail_node_next_handle
); /* Bug fix */
104 curr_node
->_next
= tail_node
->_next
;
105 curr_node
->_prev
= pl
->_tail
;
106 tail_node_next
->_prev
= handle
; /* Bug fix */
107 tail_node
->_next
= handle
;
112 /*******************************************************************************
114 ******************************************************************************/
115 void *lru_data(struct lru
* pl
, short handle
)
117 return lru_node_p(pl
, handle
)->data
;