-#ifndef __LUNAIX_SLAB_H
-#define __LUNAIX_SLAB_H
+#ifndef __LUNAIX_CAKE_H
+#define __LUNAIX_CAKE_H
#include <lunaix/ds/llist.h>
#define PILE_NAME_MAXLEN 20
+#define PILE_CACHELINE 1
+
struct cake_pile
{
struct llist_header piles;
struct llist_header full;
struct llist_header partial;
struct llist_header free;
+ unsigned int offset;
unsigned int piece_size;
unsigned int cakes_count;
unsigned int alloced_pieces;
};
/**
- * @brief 创建一个堆
+ * @brief 创建一个蛋糕堆
*
* @param name 堆名称
- * @param piece_size 每个蛋糕上可以被切分的大小
+ * @param piece_size 每个蛋糕切块儿的大小
* @param pg_per_cake 每个蛋糕所占据的页数
* @return struct cake_pile*
*/
struct cake_pile*
-cake_new_pile(char* name, unsigned int piece_size, unsigned int pg_per_cake);
+cake_new_pile(char* name,
+ unsigned int piece_size,
+ unsigned int pg_per_cake,
+ int options);
/**
* @brief 拿一块儿蛋糕
void
vfree(void* ptr);
+void*
+valloc_dma(unsigned int size);
+
+void
+vfree_dma(void* ptr);
+
void
valloc_init();
LOG_MODULE("CAKE")
-#define SLAB_SIZE PG_SIZE
+#define CACHE_LINE_SIZE 128
struct cake_pile master_pile;
int max_piece = pile->pieces_per_cake;
- cake->first_piece =
- (void*)((uintptr_t)(cake + 1) + max_piece * sizeof(piece_index_t));
+ cake->first_piece = (void*)((uintptr_t)cake + pile->offset);
cake->next_free = 0;
piece_index_t* free_list = &cake->free_list;
__init_pile(struct cake_pile* pile,
char* name,
unsigned int piece_size,
- unsigned int pg_per_cake)
+ unsigned int pg_per_cake,
+ int options)
{
+ unsigned int offset = sizeof(long);
+
+ // 默认每块儿蛋糕对齐到地址总线宽度
+ if ((options & PILE_CACHELINE)) {
+ // 对齐到128字节缓存行大小,主要用于DMA
+ offset = CACHE_LINE_SIZE;
+ }
+
+ piece_size = ROUNDUP(piece_size, offset);
*pile = (struct cake_pile){ .piece_size = piece_size,
.cakes_count = 1,
.pieces_per_cake =
(piece_size + sizeof(piece_index_t)),
.pg_per_cake = pg_per_cake };
+ unsigned int overhead_size =
+ sizeof(struct cake_s) + pile->pieces_per_cake * sizeof(piece_index_t);
+
+ pile->offset = ROUNDUP(overhead_size, offset);
+
strncpy(&pile->pile_name, name, PILE_NAME_MAXLEN);
llist_init_head(&pile->free);
void
cake_init()
{
- __init_pile(&master_pile, "master", sizeof(master_pile), 1);
+ __init_pile(&master_pile, "pinkamina", sizeof(master_pile), 1, 0);
}
struct cake_pile*
-cake_new_pile(char* name, unsigned int piece_size, unsigned int pg_per_cake)
+cake_new_pile(char* name,
+ unsigned int piece_size,
+ unsigned int pg_per_cake,
+ int options)
{
struct cake_pile* pile = (struct cake_pile*)cake_grab(&master_pile);
- __init_pile(pile, name, piece_size, pg_per_cake);
+ __init_pile(pile, name, piece_size, pg_per_cake, options);
return pile;
}
#define MAX_CLASS 6
static char piles_names[MAX_CLASS][PILE_NAME_MAXLEN] = {
- "valloc_128", "valloc_256", "valloc_512",
- "valloc_1k", "valloc_2k", "valloc_4k"
+ "valloc_16", "valloc_32", "valloc_64",
+ "valloc_128", "valloc_256", "valloc_512"
+};
+
+static char piles_names_dma[MAX_CLASS][PILE_NAME_MAXLEN] = {
+ "valloc_dma_128", "valloc_dma_512", "valloc_dma_512",
+ "valloc_dma_1k", "valloc_dma_2k", "valloc_dma_4k"
};
static struct cake_pile* piles[MAX_CLASS];
+static struct cake_pile* piles_dma[MAX_CLASS];
void
valloc_init()
{
+ for (size_t i = 0; i < MAX_CLASS; i++) {
+ int size = 1 << (i + 4);
+ piles[i] = cake_new_pile(&piles_names[i], size, 1, 0);
+ }
+
+ // DMA 内存保证128字节对齐
for (size_t i = 0; i < MAX_CLASS; i++) {
int size = 1 << (i + 7);
- piles[i] = cake_new_pile(&piles_names[i], size, size > 1024 ? 8 : 1);
+ piles_dma[i] = cake_new_pile(
+ &piles_names_dma[i], size, size > 1024 ? 8 : 1, PILE_CACHELINE);
}
}
void*
-valloc(unsigned int size)
+__valloc(unsigned int size, struct cake_pile** segregate_list)
{
size_t i = 0;
for (; i < MAX_CLASS; i++) {
- if (piles[i]->piece_size > size) {
+ if (segregate_list[i]->piece_size >= size) {
goto found_class;
}
}
return NULL;
found_class:
- return cake_grab(piles[i]);
+ return cake_grab(segregate_list[i]);
}
void
-vfree(void* ptr)
+__vfree(void* ptr, struct cake_pile** segregate_list)
{
size_t i = 0;
for (; i < MAX_CLASS; i++) {
- if (cake_release(piles[i], ptr)) {
+ if (cake_release(segregate_list[i], ptr)) {
return;
}
}
+}
+
+void*
+valloc(unsigned int size)
+{
+ return __valloc(size, &piles);
+}
+
+void
+vfree(void* ptr)
+{
+ __vfree(ptr, &piles);
+}
+
+void*
+valloc_dma(unsigned int size)
+{
+ return __valloc(size, &piles_dma);
+}
+
+void
+vfree_dma(void* ptr)
+{
+ __vfree(ptr, &piles_dma);
}
\ No newline at end of file
ps2_kbd_init();
pci_init();
ahci_init();
- pci_print_device();
ahci_list_device();
cake_stats();