u_malloc支持
This commit is contained in:
@@ -122,6 +122,7 @@ static int _sys_mmap2(void *start, size_t len, int prot, int flags, int fd, off_
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
len = ALIGN(len, MK_PAGE_SIZE);
|
||||
if (prot & PROT_PFS)
|
||||
{
|
||||
msg_tag_t tag;
|
||||
@@ -154,10 +155,10 @@ static int _sys_mmap2(void *start, size_t len, int prot, int flags, int fd, off_
|
||||
}
|
||||
else
|
||||
{
|
||||
if (len & (PAGE_SIZE - 1))
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
// if (len & (PAGE_SIZE - 1))
|
||||
// {
|
||||
// return -EINVAL;
|
||||
// }
|
||||
*addr = (umword_t)mm_page_alloc(len / PAGE_SIZE);
|
||||
}
|
||||
if (*addr == 0)
|
||||
|
||||
13
mkrtos_user/lib/util/inc/u_malloc.h
Normal file
13
mkrtos_user/lib/util/inc/u_malloc.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
struct allocmem
|
||||
{
|
||||
void *ptr;
|
||||
size_t size;
|
||||
struct allocmem *next;
|
||||
};
|
||||
|
||||
void *u_malloc(size_t size);
|
||||
void *u_calloc(size_t size, int nmemb);
|
||||
void u_free(void *ptr);
|
||||
// void spurge();
|
||||
3
mkrtos_user/lib/util/inc/u_path.h
Normal file
3
mkrtos_user/lib/util/inc/u_path.h
Normal file
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
void u_rel_path_to_abs(const char *cur_path, const char *path, char *new_path);
|
||||
149
mkrtos_user/lib/util/src/u_malloc.c
Normal file
149
mkrtos_user/lib/util/src/u_malloc.c
Normal file
@@ -0,0 +1,149 @@
|
||||
/**
|
||||
* u_malloc.c: a simple memory allocator for use in MKRTOS.
|
||||
* 使用缺页模拟申请内存,申请的内存不能用于栈内存。
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/shm.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <u_malloc.h>
|
||||
|
||||
static struct allocmem *memlocs = NULL;
|
||||
|
||||
static struct allocmem *new_alloc_mem()
|
||||
{
|
||||
struct allocmem *ptr;
|
||||
if ((ptr = mmap(NULL, sizeof(struct allocmem), PROT_READ | PROT_WRITE | PROT_PFS, MAP_POPULATE | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)) == MAP_FAILED)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr->ptr = NULL;
|
||||
ptr->size = 0;
|
||||
ptr->next = NULL;
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
|
||||
static void free_alloc_mem(struct allocmem *ptr)
|
||||
{
|
||||
if (ptr != NULL)
|
||||
{
|
||||
munmap(ptr, sizeof(struct allocmem));
|
||||
}
|
||||
}
|
||||
|
||||
/// Pass a valid pointer (or NULL) to store the resultant into
|
||||
struct allocmem *insert_end(struct allocmem *ptr, struct allocmem **outVar)
|
||||
{
|
||||
if (ptr == NULL)
|
||||
{
|
||||
struct allocmem *outAble = new_alloc_mem();
|
||||
if (outVar != NULL)
|
||||
*outVar = outAble;
|
||||
return (outAble);
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr->next = insert_end(ptr->next, outVar);
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
|
||||
struct allocmem *find(struct allocmem *ptr, void *searchPtr)
|
||||
{
|
||||
if (ptr == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (ptr->ptr == searchPtr)
|
||||
return ptr;
|
||||
return find(ptr->next, searchPtr);
|
||||
}
|
||||
|
||||
struct allocmem *find_and_remove(struct allocmem *ptr, void *searchPtr)
|
||||
{
|
||||
if (ptr == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (ptr->ptr == searchPtr)
|
||||
{
|
||||
struct allocmem *nextUp = ptr->next;
|
||||
free_alloc_mem(ptr);
|
||||
return nextUp;
|
||||
}
|
||||
ptr->next = find_and_remove(ptr->next, searchPtr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *u_malloc(size_t size)
|
||||
{
|
||||
struct allocmem *info = NULL;
|
||||
memlocs = insert_end(memlocs, &info);
|
||||
if (info == NULL)
|
||||
{
|
||||
/// Failed to initialize metadata info
|
||||
return NULL;
|
||||
}
|
||||
void *ptr;
|
||||
if ((ptr = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_PFS, MAP_POPULATE | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)) == MAP_FAILED)
|
||||
{
|
||||
/// Failed to make data, revert changes
|
||||
memlocs = find_and_remove(memlocs, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
/// Got it together
|
||||
info->ptr = ptr;
|
||||
info->size = size;
|
||||
/// Return this precious pointer
|
||||
return ptr;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *u_calloc(size_t size, int nmemb)
|
||||
{
|
||||
size_t isOverFlow = size * nmemb;
|
||||
if (size != isOverFlow / nmemb)
|
||||
{
|
||||
/// Overflow, dont try
|
||||
return NULL;
|
||||
}
|
||||
void *newPtr = u_malloc(isOverFlow);
|
||||
if (newPtr == NULL)
|
||||
{
|
||||
/// Failed to init
|
||||
return NULL;
|
||||
}
|
||||
/// A character is a byte of data that can be managed
|
||||
for (size_t loc = 0; loc < isOverFlow; loc++)
|
||||
{
|
||||
*(((char *)newPtr) + loc) = 0;
|
||||
}
|
||||
return newPtr;
|
||||
}
|
||||
|
||||
void u_free(void *ptr)
|
||||
{
|
||||
if (ptr == NULL)
|
||||
return;
|
||||
struct allocmem *info = find(memlocs, ptr);
|
||||
if (info == NULL)
|
||||
return;
|
||||
munmap(info->ptr, info->size);
|
||||
memlocs = find_and_remove(memlocs, ptr);
|
||||
}
|
||||
|
||||
/// Violently Remove Everything
|
||||
// void spurge()
|
||||
// {
|
||||
// while (memlocs)
|
||||
// {
|
||||
// sfree(memlocs->ptr);
|
||||
// }
|
||||
// }
|
||||
147
mkrtos_user/lib/util/src/u_path.c
Normal file
147
mkrtos_user/lib/util/src/u_path.c
Normal file
@@ -0,0 +1,147 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
static int path_name_cp(char *dst, const char *src, int src_inx, int *cp_len, int *jmp_len)
|
||||
{
|
||||
int j = 0;
|
||||
int jmp_cn = 0;
|
||||
int type = -1;
|
||||
int last_is_slash = 0;
|
||||
|
||||
while (*src)
|
||||
{
|
||||
if (src[0] == '.' && (src_inx == 0 || src[-1] == '/'))
|
||||
{
|
||||
if (src[1] == 0)
|
||||
{
|
||||
type = 0;
|
||||
}
|
||||
else if (src[1] == '.')
|
||||
{
|
||||
if (src[2] == '/')
|
||||
{
|
||||
type = 1;
|
||||
}
|
||||
else if (src[2] == 0)
|
||||
{
|
||||
type = 2;
|
||||
}
|
||||
}
|
||||
else if (src[1] == '/')
|
||||
{
|
||||
type = 3;
|
||||
}
|
||||
}
|
||||
if (type != -1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (*src != '/' || last_is_slash == 0)
|
||||
{
|
||||
*dst = *src;
|
||||
dst++;
|
||||
j++;
|
||||
}
|
||||
if (*src == '/')
|
||||
{
|
||||
last_is_slash = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
last_is_slash = 0;
|
||||
}
|
||||
src++;
|
||||
jmp_cn++;
|
||||
}
|
||||
dst[j] = 0;
|
||||
*cp_len = j;
|
||||
*jmp_len = jmp_cn;
|
||||
return type;
|
||||
}
|
||||
/**
|
||||
* 相对路径转绝对路径
|
||||
* @param cur_path 基路径
|
||||
* @param path 相对路径
|
||||
* @param new_path 输出的路径
|
||||
* @return 输出的路径
|
||||
*/
|
||||
char *u_rel_path_to_abs(const char *cur_path, const char *path, char *new_path)
|
||||
{
|
||||
int t_len = 0;
|
||||
if (path[0] != '/' || (path[0] == '.' && path[1] == '/'))
|
||||
{
|
||||
strcpy(new_path, cur_path);
|
||||
if (new_path[strlen(new_path) - 1] != '/')
|
||||
{
|
||||
strcat(new_path, "/");
|
||||
t_len += 1;
|
||||
}
|
||||
t_len = strlen(cur_path);
|
||||
}
|
||||
for (int i = 0; path[i];)
|
||||
{
|
||||
int cp_len;
|
||||
int jmp_len;
|
||||
int type = path_name_cp(new_path + t_len, path + i, i, &cp_len, &jmp_len);
|
||||
|
||||
t_len += cp_len;
|
||||
i += jmp_len;
|
||||
switch (type)
|
||||
{
|
||||
case 0:
|
||||
i += 1;
|
||||
break;
|
||||
case 1:
|
||||
if (t_len == 0)
|
||||
{
|
||||
i += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_path[--t_len] = 0;
|
||||
while (t_len > 0)
|
||||
{
|
||||
if (new_path[--t_len] == '/')
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
new_path[t_len] = 0;
|
||||
i += 3;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (t_len == 0)
|
||||
{
|
||||
i += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_path[--t_len] = 0;
|
||||
while (t_len > 0)
|
||||
{
|
||||
if (new_path[--t_len] == '/')
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
new_path[t_len] = 0;
|
||||
i += 2;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
i += 2;
|
||||
break;
|
||||
default:
|
||||
goto end;
|
||||
}
|
||||
if (t_len == 0)
|
||||
{
|
||||
new_path[0] = '/';
|
||||
t_len = 1;
|
||||
}
|
||||
}
|
||||
end:
|
||||
new_path[t_len] = 0;
|
||||
return new_path;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
file(GLOB deps src/*.c src/*.S src/test/*.c)
|
||||
file(GLOB deps src/*.c src/*.S src/test/*.c src/nsfs/ns.c src/nsfs/nsfs.c)
|
||||
file(GLOB arch_src src/test/${ARCH_NAME}/*.c src/test/${ARCH_NAME}/*.S)
|
||||
|
||||
if (NOT $ENV{MKRTOS_TEST_MODE} STREQUAL "normal")
|
||||
|
||||
@@ -5,7 +5,10 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "ns.h"
|
||||
|
||||
#ifdef MKRTOS
|
||||
#include <u_hd_man.h>
|
||||
#include <u_malloc.h>
|
||||
#endif
|
||||
// 其他进程可以注册节点进来,并且可以注册子节点进来,子节点可以注册更多的子节点进来。
|
||||
// 可以注册两种节点DUMMY和SVR节点
|
||||
// 只有DUMMY节点里面可以注册SVR节点
|
||||
@@ -98,7 +101,11 @@ static ns_node_t *node_create(const char *name, node_type_t type)
|
||||
{
|
||||
ns_node_t *tmp;
|
||||
|
||||
#ifdef MKRTOS
|
||||
tmp = u_calloc(sizeof(ns_node_t), 1);
|
||||
#else
|
||||
tmp = calloc(sizeof(ns_node_t), 1);
|
||||
#endif
|
||||
if (!tmp)
|
||||
{
|
||||
return NULL;
|
||||
|
||||
@@ -8,11 +8,12 @@
|
||||
#endif
|
||||
|
||||
#define NS_NODE_NAME_LEN 32
|
||||
|
||||
#ifndef MKRTOS
|
||||
typedef unsigned long obj_handler_t;
|
||||
|
||||
#define HANDLER_INVALID ((obj_handler_t)(-1))
|
||||
|
||||
#else
|
||||
#include <u_types.h>
|
||||
#endif
|
||||
typedef enum node_type
|
||||
{
|
||||
NODE_TYPE_DUMMY, //!< 虚拟节点,可以有子节点
|
||||
|
||||
@@ -66,6 +66,17 @@ static void mmap_test(CuTest *cu)
|
||||
}
|
||||
#undef TEST_MEM_SIZE
|
||||
}
|
||||
#include "u_malloc.h"
|
||||
static void u_alloc_test(CuTest *cu)
|
||||
{
|
||||
for (int i = 0; i < 1000; i++)
|
||||
{
|
||||
void *mem = u_malloc(1024);
|
||||
CuAssert(cu, "u_malloc failed.\n", mem != NULL);
|
||||
memset(mem, 0, 1024);
|
||||
u_free(mem);
|
||||
}
|
||||
}
|
||||
static CuSuite suite;
|
||||
CuSuite *malloc_test_suite(void)
|
||||
{
|
||||
@@ -73,5 +84,6 @@ CuSuite *malloc_test_suite(void)
|
||||
|
||||
SUITE_ADD_TEST(&suite, malloc_test);
|
||||
SUITE_ADD_TEST(&suite, mmap_test);
|
||||
SUITE_ADD_TEST(&suite, u_alloc_test);
|
||||
return &suite;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user