1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
9 * Copyright (C) 2003 Tat Tang
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
19 ****************************************************************************/
27 unsigned char data
[1]; /* place holder */
30 #define lru_node_p(pl, x) \
31 ((struct lru_node*)(pl->_base + pl->_slot_size * x))
33 /*******************************************************************************
35 ******************************************************************************/
36 void lru_create(struct lru
* pl
, void *buf
, short size
, short data_size
)
38 pl
->_base
= (unsigned char*) buf
;
39 pl
->_slot_size
= data_size
+ LRU_SLOT_OVERHEAD
;
44 pl
->_tail
= pl
->_size
- 1;
46 /* Initialise slots */
48 for (i
=0; i
<pl
->_size
; i
++)
50 lru_node_p(pl
, i
)->_next
= i
+ 1;
51 lru_node_p(pl
, i
)->_prev
= i
- 1;
54 /* Fix up head and tail to form circular buffer */
55 lru_node_p(pl
, 0)->_prev
= pl
->_tail
;
56 lru_node_p(pl
, pl
->_tail
)->_next
= pl
->_head
;
59 /*******************************************************************************
61 ******************************************************************************/
62 void lru_traverse(struct lru
* pl
, void (*callback
)(void* data
))
65 struct lru_node
* slot
;
66 short loc
= pl
->_head
;
68 for (i
= 0; i
< pl
->_size
; i
++)
70 slot
= lru_node_p(pl
, loc
);
76 /*******************************************************************************
78 ******************************************************************************/
79 void lru_touch(struct lru
* pl
, short handle
)
81 if (handle
== pl
->_head
)
83 pl
->_head
= lru_node_p(pl
, pl
->_head
)->_next
;
84 pl
->_tail
= lru_node_p(pl
, pl
->_tail
)->_next
;
88 if (handle
== pl
->_tail
)
93 /* Remove current node from linked list */
94 struct lru_node
* curr_node
= lru_node_p(pl
, handle
);
95 struct lru_node
* prev_node
= lru_node_p(pl
, curr_node
->_prev
);
96 struct lru_node
* next_node
= lru_node_p(pl
, curr_node
->_next
);
98 prev_node
->_next
= curr_node
->_next
;
99 next_node
->_prev
= curr_node
->_prev
;
101 /* insert current node at tail */
102 struct lru_node
* tail_node
= lru_node_p(pl
, pl
->_tail
);
103 short tail_node_next_handle
= tail_node
->_next
; /* Bug fix */
104 struct lru_node
* tail_node_next
= lru_node_p(pl
, tail_node_next_handle
); /* Bug fix */
106 curr_node
->_next
= tail_node
->_next
;
107 curr_node
->_prev
= pl
->_tail
;
108 tail_node_next
->_prev
= handle
; /* Bug fix */
109 tail_node
->_next
= handle
;
114 /*******************************************************************************
116 ******************************************************************************/
117 void *lru_data(struct lru
* pl
, short handle
)
119 return lru_node_p(pl
, handle
)->data
;