Added buffer system

This commit is contained in:
Andrew Pamment 2016-01-25 22:37:01 +10:00
parent e661437d91
commit ffb6e38065
8 changed files with 201 additions and 14 deletions

View File

@ -84,7 +84,7 @@ io.o:
$(CC) $(CFLAGS) $(LDFLAGS) -o io.o -c io.c
malloc.o:
$(CC) $(CFLAGS) -DMALLOC_FAILURE_ACTION -DHAVE_MMAP=0 -DLACKS_SYS_PARAM_H -DLACKS_UNISTD_H -DLACKS_FCNTL_H -DLACKS_SYS_TYPES_H=1 -DNO_MALLOC_STATS=1 -DLACKS_ERRNO_H -DLACKS_TIME_H -DLACKS_STDLIB_H -DLACKS_STRING_H -DLACKS_SYS_MMAN_H $(LDFLAGS) -o malloc.o -c malloc.c
$(CC) $(CFLAGS) -DMORECORE_CANNOT_TRIM=1 -DMALLOC_FAILURE_ACTION -DHAVE_MMAP=0 -DLACKS_SYS_PARAM_H -DLACKS_UNISTD_H -DLACKS_FCNTL_H -DLACKS_SYS_TYPES_H=1 -DNO_MALLOC_STATS=1 -DLACKS_ERRNO_H -DLACKS_TIME_H -DLACKS_STDLIB_H -DLACKS_STRING_H -DLACKS_SYS_MMAN_H $(LDFLAGS) -o malloc.o -c malloc.c
memory.o:
$(CC) $(CFLAGS) $(LDFLAGS) -o memory.o -c memory.c

3
fat.c
View File

@ -449,6 +449,9 @@ void fat_write_entire_file(struct vfs_device_t *device, unsigned int start_clust
}
}
free(clusterchain);
if ((device->device & 0xff00) == 0x100) {
hd_sync(device->device & 0xff);
}
return;
}

177
hd.c
View File

@ -7,6 +7,13 @@
struct hd_dev **hds;
unsigned char hd_count = 0;
struct trim_struct {
struct block_buffer **bbs;
int count;
int top;
int filled;
};
int init_hd(struct ide_dev *ide) {
int i;
int j;
@ -33,6 +40,7 @@ int init_hd(struct ide_dev *ide) {
tmp_hd->part_offset = part->relative_sector;
tmp_hd->part_len = part->total_sectors;
tmp_hd->drive = i;
tmp_hd->block_buffers = hashmap_new();
if (hd_count == 0) {
hds = (struct hd_dev **)malloc(sizeof(struct hd_dev *));
} else {
@ -79,7 +87,118 @@ int init_hd(struct ide_dev *ide) {
}
char *hd_convert_key(int number, char *buffer) {
char *ptr;
int i;
buffer[15] = '\0';
ptr = &buffer[14];
if (number == 0) {
ptr--;
*ptr = 0;
return ptr;
}
while (number > 0 && ptr != buffer) {
ptr--;
i = number % 16;
*ptr = "fedcba9876543210123456789abcdef"[15 + i];
number /= 16;
}
return ptr;
}
int hd_sync_iter(any_t item, any_t data) {
struct block_buffer *bb = (struct block_buffer *)data;
int hd = (int)item;
if (bb->dirty == 1) {
ide_write_sectors(hds[hd]->ide_dev, hds[hd]->drive, 1, bb->lba, 0x10, (unsigned int)bb->buffer);
bb->dirty = 0;
}
return MAP_OK;
}
void hd_sync(int hd) {
if (hd < 0 || hd >= hd_count) {
return;
}
hashmap_iterate(hds[hd]->block_buffers, hd_sync_iter, (any_t)hd);
}
int hd_trim_iter(any_t item, any_t data) {
struct trim_struct *trim = (struct trim_struct *)item;
struct block_buffer *bb = (struct block_buffer *)data;
int j;
int bbtop;
if (trim->filled < trim->count) {
if (trim->top == 0 || bb->accessed < trim->top) {
trim->top = bb->accessed;
}
trim->bbs[trim->filled] = bb;
trim->filled++;
} else if (bb->accessed < trim->top) {
trim->top = bb->accessed;
bbtop = 0;
for (j=1;j<trim->count;j++) {
if (trim->bbs[bbtop]->accessed < trim->bbs[j]->accessed) {
bbtop = j;
}
}
trim->bbs[bbtop] = bb;
}
return MAP_OK;
}
void hd_buffer_trim() {
int hd;
struct trim_struct trim;
int i;
for (hd=0;hd<hd_count;hd++) {
if (hashmap_length(hds[hd]->block_buffers) > 20000) {
trim.count = hashmap_length(hds[hd]->block_buffers) - 20000;
trim.top = 0;
trim.bbs = (struct block_buffer **)malloc(sizeof(struct block_buffer *) * trim.count);
trim.filled = 0;
for(i=0;i<trim.count;i++) {
trim.bbs[i] = (void *)0;
}
hashmap_iterate(hds[hd]->block_buffers, hd_trim_iter, (any_t)&trim);
for(i=0;i<trim.count;i++) {
if (trim.bbs[i] != (void *)0) {
hashmap_remove(hds[hd]->block_buffers, trim.bbs[i]->key);
if (trim.bbs[i]->dirty == 1) {
ide_write_sectors(hds[hd]->ide_dev, hds[hd]->drive, 1, trim.bbs[i]->lba, 0x10, (unsigned int)trim.bbs[i]->buffer);
}
free(trim.bbs[i]);
} else {
kprintf("TRIM = NULL o.O\n");
}
}
free(trim.bbs);
}
}
}
void hd_write_block(int hd, unsigned int blockno, char *source, unsigned int blocksize) {
char key[16];
struct block_buffer *bb;
int i;
if (hd < 0 || hd >= hd_count) {
return;
}
@ -88,15 +207,32 @@ void hd_write_block(int hd, unsigned int blockno, char *source, unsigned int blo
int lba = (blockno * count) + hds[hd]->part_offset;
if ((blockno * count) + count > hds[hd]->part_len) {
return;
}
ide_write_sectors(hds[hd]->ide_dev, hds[hd]->drive, count, lba, 0x10, (unsigned int)source);
for (i=0;i<count;i++) {
if (hashmap_get(hds[hd]->block_buffers, hd_convert_key((lba + (i * 512)), key), &bb) == MAP_OK) {
bb->dirty = 1;
bb->accessed++;
memcpy(bb->buffer, &source[i * 512], 512);
} else {
bb = (struct block_buffer *)malloc(sizeof(struct block_buffer));
bb->lba = lba + (i * 512);
bb->dirty = 1;
bb->accessed = 1;
strcpy(bb->key, hd_convert_key((lba + (i * 512)), key));
memcpy(bb->buffer, &source[i * 512], 512);
hashmap_put(hds[hd]->block_buffers,bb->key, bb);
}
}
}
char *hd_read_block(int hd, unsigned int blockno, char *dest, unsigned int blocksize) {
struct block_buffer *bb;
char key[16];
int i;
if (hd < 0 || hd >= hd_count) {
return (void *)0;
}
@ -109,14 +245,31 @@ char *hd_read_block(int hd, unsigned int blockno, char *dest, unsigned int block
return (void *)0;
}
ide_read_sectors(hds[hd]->ide_dev, hds[hd]->drive, count, lba, 0x10, (unsigned int)dest);
for (i=0;i<count;i++) {
if (hashmap_get(hds[hd]->block_buffers, hd_convert_key((lba + (i * 512)), key), &bb) == MAP_OK) {
bb->accessed++;
memcpy(&dest[i * 512], bb->buffer, 512);
} else {
bb = (struct block_buffer *)malloc(sizeof(struct block_buffer));
bb->lba = lba + (i * 512);
bb->accessed = 1;
strcpy(bb->key, hd_convert_key((lba + (i * 512)), key));
ide_read_sectors(hds[hd]->ide_dev, hds[hd]->drive, 1, (lba + (i * 512)), 0x10, bb->buffer);
memcpy(&dest[i * 512], bb->buffer, 512);
hashmap_put(hds[hd]->block_buffers, bb->key, bb);
}
}
return dest;
}
void hd_write_blocks(int hd, unsigned int blockstart, unsigned int blockcount, char *source, unsigned int blocksize) {
int i;
if (hd < 0 || hd >= hd_count) {
return;
}
@ -132,12 +285,17 @@ void hd_write_blocks(int hd, unsigned int blockstart, unsigned int blockcount, c
}
}
ide_write_sectors(hds[hd]->ide_dev, hds[hd]->drive, blocks, (blockstart * (blocksize / 512) + hds[hd]->part_offset), 0x10, (unsigned int)source);
for (i=0;i<blocks;i++) {
hd_write_block(hd, blockstart + i, &source[i * 512], 512);
}
// ide_write_sectors(hds[hd]->ide_dev, hds[hd]->drive, blocks, (blockstart * (blocksize / 512) + hds[hd]->part_offset), 0x10, (unsigned int)source);
return;
}
int hd_read_blocks(int hd, unsigned int blockstart, unsigned int blockcount, char *dest, unsigned int blocksize) {
int i;
if (hd < 0 || hd >= hd_count) {
return 0;
}
@ -152,7 +310,10 @@ int hd_read_blocks(int hd, unsigned int blockstart, unsigned int blockcount, cha
return 0;
}
}
for (i=0;i<blocks;i++) {
hd_read_block(hd, blockstart + i, &dest[i * 512], 512);
}
ide_read_sectors(hds[hd]->ide_dev, hds[hd]->drive, blocks, (blockstart * (blocksize / 512) + hds[hd]->part_offset), 0x10, (unsigned int)dest);
// ide_read_sectors(hds[hd]->ide_dev, hds[hd]->drive, blocks, (blockstart * (blocksize / 512) + hds[hd]->part_offset), 0x10, (unsigned int)dest);
return blocks;
}

12
hd.h
View File

@ -2,6 +2,7 @@
#define __HD_H
#include "pata.h"
#include "hashmap.h"
struct partition_table {
unsigned char boot;
@ -14,15 +15,26 @@ struct partition_table {
unsigned int total_sectors;
} __attribute__((packed));
struct block_buffer {
char key[16];
unsigned long lba;
unsigned int accessed;
unsigned char dirty;
char buffer[512];
};
struct hd_dev {
struct ide_dev *ide_dev;
unsigned char drive;
unsigned char part;
unsigned int part_offset;
unsigned int part_len;
map_t block_buffers;
};
extern int init_hd(struct ide_dev *ide);
extern void hd_sync(int hd);
extern void hd_buffer_trim();
extern char *hd_read_block(int hd, unsigned int blockno, char *dest, unsigned int blocksize);
extern int hd_read_blocks(int hd, unsigned int blockstart, unsigned int blockcount, char *dest, unsigned int blocksize);
extern void hd_write_blocks(int hd, unsigned int blockstart, unsigned int blockcount, char *source, unsigned int blocksize);

View File

@ -630,9 +630,9 @@ void *sbrk(int amount) {
}
if (amount <= 0) {
//if (initialized) {
//kprintf("trying to free kernel memory\n");
//}
if (initialized) {
kprintf("trying to free kernel memory\n");
}
return previous_ds;
}

View File

@ -70,7 +70,7 @@ int main(int argc, char **argv) {
if(!quinn_add_button(window_handle, 25, 215, 100, 50, "Memory Info", NULL, btn_callback3)) {
quinn_exit();
}
surf = quinn_add_surface(window_handle, 0, 0, 150, 100);
surf = quinn_add_surface(window_handle, 0, 0, 150, 100, NULL);
if (surf == NULL) {
quinn_exit();
}

View File

@ -5,6 +5,7 @@
#include "console.h"
#include "string.h"
#include "fat.h"
#include "hd.h"
struct task_t *current_task;
struct task_t *first_task;
@ -37,6 +38,7 @@ static int current_pid = 0;
unsigned char stack_spaces[256];
static int gui_timer = 0;
static int block_buffer_trim_timer = 0;
char *stack_alloc(void) {
char * blk;
@ -186,7 +188,13 @@ void schedule(struct regs *r) {
struct task_t *sem_task = first_task;
unsigned int *sem_return;
int i;
if (block_buffer_trim_timer == 20) {
hd_buffer_trim();
block_buffer_trim_timer = 0;
}
block_buffer_trim_timer++;
if (gui_timer == 5 ) {
gui_flip();
gui_timer = 0;

3
vfs.c
View File

@ -322,6 +322,9 @@ void vfs_close_file(int fno) {
free(info->clusterchain);
}
if ((current_task->filehandles[fno].device->device & 0xff00) == 0x100) {
hd_sync(current_task->filehandles[fno].device->device & 0xff);
}
free(current_task->filehandles[fno].fs_specific);
free(current_task->filehandles[fno].filepath);