5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
@@ -96,7 +96,10 @@
|
||||
"vgic.h": "c",
|
||||
"aarch64_emul.h": "c",
|
||||
"uvmm_host_irqs.h": "c",
|
||||
"stdio.h": "c"
|
||||
"stdio.h": "c",
|
||||
"u_thread_util.h": "c",
|
||||
"u_hd_man.h": "c",
|
||||
"u_mm.h": "c"
|
||||
},
|
||||
"cortex-debug.showRTOS": false,
|
||||
"cortex-debug.variableUseNaturalFormat": false,
|
||||
|
||||
@@ -139,6 +139,11 @@ typedef struct sp_info
|
||||
#endif
|
||||
} sp_info_t;
|
||||
|
||||
#define flush_all_tlb() \
|
||||
do { \
|
||||
/*asm volatile("tlbi alle2");*/\
|
||||
asm volatile("tlbi alle1");\
|
||||
} while (0)
|
||||
#define cpu_sleep() asm volatile("wfi" : : : "memory")
|
||||
#define _barrier() __asm__ __volatile__("" : : : "memory")
|
||||
#define _dmb(ins) \
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <asm/mm.h>
|
||||
#include "mm_page.h"
|
||||
#include <mmu.h>
|
||||
#include <string.h>
|
||||
int page_entry_init(page_entry_t *entry)
|
||||
{
|
||||
entry->dir = buddy_alloc(buddy_get_alloter(), PAGE_SIZE);
|
||||
@@ -10,6 +11,7 @@ int page_entry_init(page_entry_t *entry)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(entry->dir, 0, PAGE_SIZE);
|
||||
knl_pdir_init(entry, entry->dir, 3);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ pte_t *pages_walk(page_entry_t *pdir, addr_t virt_addr, mword_t order, void *(*f
|
||||
int i;
|
||||
pte_t *next = &pdir->dir[(virt_addr >> pdir->lv_shift_sizes[(PAGE_DEEP - pdir->depth)]) & 0x1ffUL];
|
||||
|
||||
// 找到所在深度
|
||||
// 找到所在深度
|
||||
for (i = (PAGE_DEEP - pdir->depth); i < PAGE_DEEP; i++)
|
||||
{
|
||||
if (pdir->lv_shift_sizes[i] == order)
|
||||
@@ -162,7 +162,7 @@ int unmap_mm(page_entry_t *pdir, addr_t virt_addr, mword_t page_order, mword_t p
|
||||
{
|
||||
for (mword_t i = 0; i < pfn_cn; i++)
|
||||
{
|
||||
pte_t *pte = pages_walk(pdir, virt_addr + (i << page_order), page_order, NULL);
|
||||
pte_t *pte = pages_walk(pdir, virt_addr + (i << page_order), page_order, page_alloc_cb);
|
||||
|
||||
if (pte != NULL)
|
||||
{
|
||||
|
||||
@@ -49,3 +49,5 @@ umword_t mm_get_paddr(page_entry_t *pdir, addr_t virt_addr, mword_t page_order);
|
||||
void per_cpu_boot_mapping(bool_t init_pages);
|
||||
page_entry_t *boot_get_pdir(void);
|
||||
void knl_pdir_init(page_entry_t *pdir, pte_t *dir, int page_deep);
|
||||
|
||||
void flush_cache_range(void *start, void *end);
|
||||
|
||||
@@ -20,7 +20,6 @@ static void sw_mmu(thread_t *next_thread)
|
||||
{
|
||||
|
||||
assert(get_sp());
|
||||
// _dsb(sy);
|
||||
write_sysreg(p_next_dir | (next_task->mm_space.asid << 48) /*TODO:*/, vttbr_el2); // 切换用户态页表
|
||||
_isb();
|
||||
// asm volatile("ic iallu");
|
||||
|
||||
@@ -76,8 +76,6 @@ static int thread_exec_to_vcpu(thread_t *th, entry_frame_t *regs, umword_t esr,
|
||||
if (ret >= 0)
|
||||
{
|
||||
*regs = *dst_pf;
|
||||
// regs->pc = dst_pf->pc; /*TODO:可能还有其他信息*/
|
||||
// regs->pstate = dst_pf->pstate;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -114,6 +112,7 @@ void thread_sync_entry(entry_frame_t *regs)
|
||||
if (ret < 0)
|
||||
{
|
||||
printk("[knl] inst abort 0x20 pfa:0x%lx\n", addr);
|
||||
dump_stack(regs->pc, regs->regs[29]);
|
||||
task_knl_kill(th, FALSE);
|
||||
}
|
||||
break;
|
||||
@@ -132,6 +131,7 @@ void thread_sync_entry(entry_frame_t *regs)
|
||||
ret = task_vma_page_fault(&tk->mm_space.mem_vma, ALIGN_DOWN(addr, PAGE_SIZE));
|
||||
if (ret < 0)
|
||||
{
|
||||
dump_stack(regs->pc, regs->regs[29]);
|
||||
task_knl_kill(th, FALSE);
|
||||
}
|
||||
break;
|
||||
@@ -144,10 +144,12 @@ void thread_sync_entry(entry_frame_t *regs)
|
||||
ret = thread_exec_to_vcpu(th, regs, esr, addr);
|
||||
if (ret < 0)
|
||||
{
|
||||
dump_stack(regs->pc, regs->regs[29]);
|
||||
task_knl_kill(th, FALSE);
|
||||
}
|
||||
// printk("%s:%d ret:%d\n", __func__, __LINE__, ret);
|
||||
#else
|
||||
dump_stack(regs->pc, regs->regs[29]);
|
||||
task_knl_kill(th, FALSE);
|
||||
#endif
|
||||
break;
|
||||
|
||||
@@ -25,11 +25,11 @@ typedef struct buddy_head
|
||||
mword_t nr_free; //!< 多少个可用的块
|
||||
} buddy_head_t;
|
||||
|
||||
#define BUDDY_MAX_ORDER 12
|
||||
#define BUDDY_MAX_ORDER 10
|
||||
|
||||
typedef struct buddy_order
|
||||
{
|
||||
buddy_head_t order_tab[BUDDY_MAX_ORDER]; // max 16MB
|
||||
buddy_head_t order_tab[BUDDY_MAX_ORDER]; // max 4MB
|
||||
addr_t heap_addr;
|
||||
spinlock_t lock;
|
||||
size_t heap_size;
|
||||
|
||||
@@ -219,6 +219,7 @@ void thread_unbind(thread_t *th);
|
||||
|
||||
void thread_send_wait(thread_t *th);
|
||||
bool_t thread_sched(bool_t is_sche);
|
||||
int thread_suspend_remote(thread_t *th, bool_t is_sche);
|
||||
void thread_suspend(thread_t *th);
|
||||
void thread_dead(thread_t *th);
|
||||
void thread_todead(thread_t *th, bool_t is_sche);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <printk.h>
|
||||
#include <assert.h>
|
||||
#include <spinlock.h>
|
||||
|
||||
#include <string.h>
|
||||
static buddy_entry_t *buddy_entry_simp_slab;
|
||||
static size_t buddy_entry_cn = 0;
|
||||
static buddy_order_t buddy_kmem;
|
||||
@@ -20,6 +20,10 @@ static inline void buddy_entry_set_use_state(buddy_entry_t *be, bool_t state)
|
||||
be->addr &= ~0x2ULL;
|
||||
be->addr |= (!!state) << 1;
|
||||
}
|
||||
static inline int buddy_entry_get_use_state(buddy_entry_t *be)
|
||||
{
|
||||
return !!(be->addr & 0x2ULL);
|
||||
}
|
||||
static inline void buddy_entry_set_valid_state(buddy_entry_t *be, bool_t state)
|
||||
{
|
||||
be->addr &= ~0x1ULL;
|
||||
@@ -57,6 +61,7 @@ static buddy_entry_t *buddy_entry_alloc(void)
|
||||
return &buddy_entry_simp_slab[i];
|
||||
}
|
||||
}
|
||||
assert(0);
|
||||
return NULL;
|
||||
}
|
||||
static void buddy_entry_free(buddy_entry_t *be)
|
||||
@@ -68,12 +73,16 @@ buddy_order_t *buddy_get_alloter(void)
|
||||
{
|
||||
return &buddy_kmem;
|
||||
}
|
||||
|
||||
#define BUDDY_MAX_BYTES (1 << (CONFIG_PAGE_SHIFT + BUDDY_MAX_ORDER))
|
||||
int buddy_init(buddy_order_t *buddy, addr_t start_addr, size_t size)
|
||||
{
|
||||
assert(buddy);
|
||||
|
||||
if ((start_addr & (PAGE_SIZE - 1)) != 0)
|
||||
if (start_addr % BUDDY_MAX_BYTES)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (size % BUDDY_MAX_BYTES)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
@@ -82,26 +91,17 @@ int buddy_init(buddy_order_t *buddy, addr_t start_addr, size_t size)
|
||||
{
|
||||
slist_init(&buddy->order_tab[i].b_order);
|
||||
}
|
||||
size_t entry_cn = 0;
|
||||
size_t entry_cn = (size / BUDDY_MAX_BYTES) << (BUDDY_MAX_ORDER - 1);
|
||||
|
||||
int iffs = ffs(size);
|
||||
if (!is_power_of_2(iffs))
|
||||
{
|
||||
iffs++;
|
||||
}
|
||||
while (iffs >= PAGE_SHIFT)
|
||||
{
|
||||
entry_cn += ((1UL << iffs) >> PAGE_SHIFT);
|
||||
iffs--;
|
||||
}
|
||||
buddy_entry_simp_slab = (void *)start_addr;
|
||||
size_t entrys_size = ALIGN(entry_cn * (sizeof(buddy_entry_t)), PAGE_SIZE);
|
||||
size_t entrys_size = ALIGN(entry_cn * (sizeof(buddy_entry_t)), BUDDY_MAX_BYTES);
|
||||
start_addr += entrys_size;
|
||||
size -= entrys_size;
|
||||
buddy->heap_addr = start_addr;
|
||||
buddy_entry_cn = entry_cn;
|
||||
|
||||
printk("buddy mem size:%dMB\n", size / 1024 / 1024);
|
||||
printk("buddy start addr:[0x%lx - 0x%lx], buddy mem size:%dMB\n", start_addr,
|
||||
start_addr + size - 1, size / 1024 / 1024);
|
||||
|
||||
size_t remain_size = size;
|
||||
addr_t add_addr = buddy->heap_addr;
|
||||
@@ -109,24 +109,17 @@ int buddy_init(buddy_order_t *buddy, addr_t start_addr, size_t size)
|
||||
// 内存分布到不同地order中=
|
||||
while (remain_size)
|
||||
{
|
||||
int i_ffs = ffs(remain_size);
|
||||
i_ffs -= PAGE_SHIFT;
|
||||
if (i_ffs >= BUDDY_MAX_ORDER)
|
||||
{
|
||||
i_ffs = BUDDY_MAX_ORDER;
|
||||
}
|
||||
|
||||
buddy_entry_t *new_be = buddy_entry_alloc();
|
||||
if (!new_be)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
buddy_entry_init(new_be, add_addr);
|
||||
slist_add(&buddy->order_tab[i_ffs == 0 ? 1 : i_ffs - 1].b_order, &new_be->next);
|
||||
buddy->order_tab[i_ffs - 1].nr_free++;
|
||||
slist_add(&buddy->order_tab[BUDDY_MAX_ORDER - 1].b_order, &new_be->next);
|
||||
buddy->order_tab[BUDDY_MAX_ORDER - 1].nr_free++;
|
||||
|
||||
remain_size -= to_size(i_ffs);
|
||||
add_addr += to_size(i_ffs);
|
||||
remain_size -= BUDDY_MAX_BYTES;
|
||||
add_addr += BUDDY_MAX_BYTES;
|
||||
}
|
||||
buddy->heap_size = size;
|
||||
return 0;
|
||||
@@ -158,13 +151,16 @@ static buddy_entry_t *buddy_order_div(buddy_order_t *buddy, mword_t st_order)
|
||||
assert(st_order < BUDDY_MAX_ORDER);
|
||||
assert(st_order > 0);
|
||||
|
||||
// 找到一个空的
|
||||
buddy_entry_t *free_b = buddy_order_find_free(&buddy->order_tab[st_order]);
|
||||
|
||||
if (!free_b)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
// 设置被使用
|
||||
buddy_entry_set_use_state(free_b, TRUE);
|
||||
// 可用数量-1
|
||||
buddy->order_tab[st_order].nr_free--;
|
||||
|
||||
buddy_entry_t *new_l = buddy_entry_alloc();
|
||||
@@ -176,6 +172,12 @@ static buddy_entry_t *buddy_order_div(buddy_order_t *buddy, mword_t st_order)
|
||||
{
|
||||
buddy_entry_free(new_l);
|
||||
}
|
||||
if (new_l)
|
||||
{
|
||||
buddy_entry_free(new_r);
|
||||
}
|
||||
buddy_entry_set_use_state(free_b, FALSE);
|
||||
buddy->order_tab[st_order].nr_free++;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -185,8 +187,8 @@ static buddy_entry_t *buddy_order_div(buddy_order_t *buddy, mword_t st_order)
|
||||
new_r->parent = free_b;
|
||||
buddy_entry_init(new_l, div_addr);
|
||||
buddy_entry_init(new_r, div_addr + to_size(st_order - 1));
|
||||
buddy_entry_set_lr(new_l, TRUE);
|
||||
buddy_entry_set_lr(new_r, FALSE);
|
||||
buddy_entry_set_lr(new_l, TRUE); // 设置为左边
|
||||
buddy_entry_set_lr(new_r, FALSE); // 设置为右边
|
||||
slist_add(&buddy->order_tab[st_order - 1].b_order, &new_l->next);
|
||||
slist_add(&buddy->order_tab[st_order - 1].b_order, &new_r->next);
|
||||
|
||||
@@ -232,6 +234,7 @@ void *buddy_alloc(buddy_order_t *buddy, size_t size)
|
||||
// 有空闲的直接分配
|
||||
buddy_entry_t *free_b = buddy_order_find_free(&buddy->order_tab[need_ffs]);
|
||||
|
||||
assert(free_b);
|
||||
buddy->order_tab[need_ffs].nr_free--;
|
||||
buddy_entry_set_use_state(free_b, TRUE);
|
||||
ret_mem = (void *)BUDDY_ENTRY_ADDR(free_b);
|
||||
@@ -272,7 +275,7 @@ void *buddy_alloc(buddy_order_t *buddy, size_t size)
|
||||
}
|
||||
end:
|
||||
spinlock_set(&buddy->lock, l_state);
|
||||
//printk("alloc addr 0x%x.\n", ret_mem);
|
||||
// printk("alloc addr 0x%x.\n", ret_mem);
|
||||
return ret_mem;
|
||||
}
|
||||
static inline addr_t get_buddy_addr(buddy_entry_t *merge_be, size_t size)
|
||||
@@ -315,6 +318,10 @@ static buddy_entry_t *buddy_merge(buddy_order_t *buddy, buddy_entry_t *merge_be,
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (buddy_entry_get_use_state(merge_be))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
addr_t buddy_addr = get_buddy_addr(merge_be, to_size(st_ffs));
|
||||
buddy_entry_t *tmp = NULL;
|
||||
|
||||
@@ -326,8 +333,9 @@ static buddy_entry_t *buddy_merge(buddy_order_t *buddy, buddy_entry_t *merge_be,
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
// assert(!BUDDY_ENTRY_USED(tmp));
|
||||
assert(BUDDY_ENTRY_VALID(tmp));
|
||||
|
||||
buddy_entry_t *merge_node;
|
||||
addr_t buddy_st_addr = get_buddy_start(tmp, to_size(st_ffs));
|
||||
|
||||
slist_del(&merge_be->next);
|
||||
@@ -337,9 +345,19 @@ static buddy_entry_t *buddy_merge(buddy_order_t *buddy, buddy_entry_t *merge_be,
|
||||
assert(tmp->parent);
|
||||
buddy_entry_set_use_state(tmp, FALSE);
|
||||
|
||||
buddy_entry_free(merge_be);
|
||||
buddy_entry_free(tmp);
|
||||
if (BUDDY_ENTRY_IS_L(merge_be))
|
||||
{
|
||||
merge_node = merge_be;
|
||||
buddy_entry_free(tmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
merge_node = tmp;
|
||||
buddy_entry_free(merge_be);
|
||||
}
|
||||
buddy_entry_init(merge_node, buddy_st_addr);
|
||||
buddy->order_tab[st_ffs + 1].nr_free++;
|
||||
slist_add(&buddy->order_tab[st_ffs + 1].b_order, &merge_node->next);
|
||||
return tmp->parent;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,8 +70,9 @@ static void mem_sys_init(void)
|
||||
int ret;
|
||||
size_t buddy_size = (size_t)CONFIG_KNL_DATA_SIZE - ((addr_t)_buddy_data_start - CONFIG_KNL_DATA_ADDR - CONFIG_KNL_OFFSET);
|
||||
|
||||
ret = buddy_init(buddy_get_alloter(), (addr_t)_buddy_data_start,
|
||||
buddy_size);
|
||||
ret = buddy_init(buddy_get_alloter(),
|
||||
ALIGN((addr_t)_buddy_data_start, (1 << (BUDDY_MAX_ORDER + CONFIG_PAGE_SHIFT))) /*FIXME:这里可能会浪费一点内存*/,
|
||||
ALIGN_DOWN(buddy_size - (1 << (BUDDY_MAX_ORDER + CONFIG_PAGE_SHIFT)), (1 << (BUDDY_MAX_ORDER + CONFIG_PAGE_SHIFT))));
|
||||
assert(ret >= 0);
|
||||
mmu_page_alloc_set(mm_buddy_alloc_one_page);
|
||||
#else
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <util.h>
|
||||
#include <init.h>
|
||||
#include <arch.h>
|
||||
#include <string.h>
|
||||
static slab_t *rbtree_node_slab;
|
||||
|
||||
static void *mk_rbtree_pool_alloc_handler(void *pool, mln_size_t size)
|
||||
@@ -20,6 +21,7 @@ static void *mk_rbtree_pool_alloc_handler(void *pool, mln_size_t size)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
memset(mem, 0, sizeof(mln_rbtree_node_t) + sizeof(void *));
|
||||
*((size_t *)mem) = size;
|
||||
mem = (char *)mem + sizeof(void *);
|
||||
break;
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <vma.h>
|
||||
|
||||
#define VMA_DEBUG 0
|
||||
#define VMA_DEBUG2 0
|
||||
|
||||
static slab_t *vma_slab;
|
||||
static int vma_idl_tree_insert_cmp_handler(const void *key, const void *data);
|
||||
@@ -95,8 +96,8 @@ void task_vma_rbtree_print(mln_rbtree_t *t, mln_rbtree_node_t *root)
|
||||
vma_t *data = mln_rbtree_node_data_get(root);
|
||||
|
||||
task_vma_rbtree_print(t, root->left);
|
||||
printk("[0x%lx 0x%lx U:%d 0x%x]\n", vma_addr_get_addr(data->vaddr), vma_addr_get_addr(data->vaddr) + data->size,
|
||||
vma_node_get_used(data), vma_addr_get_prot(data->vaddr));
|
||||
printk("[0x%lx 0x%lx U:%d P:0x%x F:0x%x]\n", vma_addr_get_addr(data->vaddr), vma_addr_get_addr(data->vaddr) + data->size,
|
||||
vma_node_get_used(data), vma_addr_get_prot(data->vaddr), vma_addr_get_flags(data->vaddr));
|
||||
task_vma_rbtree_print(t, root->right);
|
||||
}
|
||||
|
||||
@@ -461,8 +462,8 @@ int task_vma_alloc(task_vma_t *task_vma, vma_addr_t vaddr, size_t size,
|
||||
goto end;
|
||||
}
|
||||
//!< 设置当前节点是使用节点,设置属性等,并插入到树中
|
||||
vma_node_set_used(node_data);
|
||||
vma_addr_set_flags(&node_data->vaddr, vma_addr_get_flags(vaddr));
|
||||
vma_node_set_used(node_data);
|
||||
vma_addr_set_prot(&node_data->vaddr, vma_addr_get_prot(vaddr));
|
||||
vma_node_set_paddr(node_data, paddr);
|
||||
task_vma->idle_tree.cmp = vma_idl_tree_insert_cmp_handler;
|
||||
@@ -473,7 +474,9 @@ int task_vma_alloc(task_vma_t *task_vma, vma_addr_t vaddr, size_t size,
|
||||
//!< 设置分配后的地址
|
||||
*ret_vaddr = alloc_addr;
|
||||
}
|
||||
printk("alloc:[0x%x 0x%x] size:0x%x\n", alloc_addr, alloc_addr + size - 1, size);
|
||||
#if VMA_DEBUG2
|
||||
printk("virt alloc:[0x%x 0x%x] size:0x%x\n", alloc_addr, alloc_addr + size - 1, size);
|
||||
#endif
|
||||
#if VMA_DEBUG
|
||||
task_vma_rbtree_print(&task_vma->idle_tree, mln_rbtree_root(&task_vma->idle_tree));
|
||||
#endif
|
||||
@@ -671,6 +674,7 @@ int task_vma_grant(task_vma_t *src_task_vma, task_vma_t *dst_task_vma, vaddr_t s
|
||||
printk("grant:\n");
|
||||
task_vma_rbtree_print(&dst_task_vma->idle_tree, mln_rbtree_root(&dst_task_vma->idle_tree));
|
||||
#endif
|
||||
flush_all_tlb();
|
||||
end:
|
||||
task_vma_unlock_two(src_task_vma, dst_task_vma, lock_status0, lock_status1);
|
||||
return ret;
|
||||
@@ -684,6 +688,24 @@ static int rbtree_cmp_merge_r(const void *key, const void *data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (key_p->addr > vma_addr_get_addr(data_p->vaddr) + data_p->size)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
static int rbtree_cmp_merge_l(const void *key, const void *data)
|
||||
{
|
||||
vma_idl_tree_insert_params_t *key_p = (vma_idl_tree_insert_params_t *)key;
|
||||
vma_t *data_p = (vma_t *)data;
|
||||
|
||||
if (key_p->addr + key_p->size == vma_addr_get_addr(data_p->vaddr))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (key_p->addr + key_p->size < vma_addr_get_addr(data_p->vaddr))
|
||||
{
|
||||
return -1;
|
||||
@@ -693,23 +715,36 @@ static int rbtree_cmp_merge_r(const void *key, const void *data)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
static int rbtree_cmp_merge_l(const void *key, const void *data)
|
||||
static bool_t vma_node_can_merge(mln_rbtree_t *r_tree, mln_rbtree_node_t *cur_node, mln_rbtree_node_t *merge_node, bool_t is_cmp_pf)
|
||||
{
|
||||
vma_idl_tree_insert_params_t *key_p = (vma_idl_tree_insert_params_t *)key;
|
||||
vma_t *data_p = (vma_t *)data;
|
||||
if (mln_rbtree_null(merge_node, r_tree))
|
||||
{
|
||||
// 空节点,不可合并
|
||||
return FALSE;
|
||||
}
|
||||
vma_t *merge_node_data = mln_rbtree_node_data_get(merge_node);
|
||||
vma_t *cur_node_data = mln_rbtree_node_data_get(cur_node);
|
||||
|
||||
if (key_p->addr == vma_addr_get_addr(data_p->vaddr))
|
||||
if ((vma_node_get_used(merge_node_data) !=
|
||||
vma_node_get_used(cur_node_data)))
|
||||
{
|
||||
return 0;
|
||||
return FALSE;
|
||||
}
|
||||
else if (key_p->addr < vma_addr_get_addr(data_p->vaddr))
|
||||
if (!is_cmp_pf)
|
||||
{
|
||||
return -1;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
if (vma_addr_get_prot(merge_node_data->vaddr) !=
|
||||
vma_addr_get_prot(cur_node_data->vaddr))
|
||||
{
|
||||
return 1;
|
||||
return FALSE;
|
||||
}
|
||||
if (vma_addr_get_flags(merge_node_data->vaddr) !=
|
||||
vma_addr_get_flags(cur_node_data->vaddr))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
/**
|
||||
* @brief 合并节点TODO:合并时属性不一致也不能合并
|
||||
@@ -718,7 +753,7 @@ static int rbtree_cmp_merge_l(const void *key, const void *data)
|
||||
* @param node
|
||||
* @return int
|
||||
*/
|
||||
static int vma_node_merge(mln_rbtree_t *r_tree, mln_rbtree_node_t *node)
|
||||
static int vma_node_merge(mln_rbtree_t *r_tree, mln_rbtree_node_t *node, bool_t is_cmp_fp)
|
||||
{
|
||||
assert(r_tree);
|
||||
assert(node);
|
||||
@@ -729,8 +764,6 @@ static int vma_node_merge(mln_rbtree_t *r_tree, mln_rbtree_node_t *node)
|
||||
vma_t *l_datanode;
|
||||
vma_t *data_node;
|
||||
|
||||
// rnode = node->right;
|
||||
// lnode = node->left;
|
||||
data_node = mln_rbtree_node_data_get(node);
|
||||
|
||||
r_tree->cmp = rbtree_cmp_merge_r;
|
||||
@@ -745,33 +778,20 @@ static int vma_node_merge(mln_rbtree_t *r_tree, mln_rbtree_node_t *node)
|
||||
rnode = mln_rbtree_search(
|
||||
r_tree,
|
||||
&(vma_idl_tree_insert_params_t){
|
||||
.size = 0,
|
||||
.addr = vma_addr_get_addr(data_node->vaddr) + data_node->size,
|
||||
}); //!< 查找是否存在
|
||||
.size = data_node->size,
|
||||
.addr = vma_addr_get_addr(data_node->vaddr)}); //!< 查找是否存在
|
||||
|
||||
r_tree->cmp = vma_idl_tree_insert_cmp_handler;
|
||||
int l_dmerge = vma_node_can_merge(r_tree, node, lnode, is_cmp_fp);
|
||||
int r_dmerge = vma_node_can_merge(r_tree, node, rnode, is_cmp_fp);
|
||||
|
||||
vma_node_set_unused(data_node);
|
||||
|
||||
int l_dmerge = !!mln_rbtree_null(lnode, r_tree) || ((!mln_rbtree_null(lnode, r_tree)) && (vma_node_get_used(((vma_t *)mln_rbtree_node_data_get(lnode))) !=
|
||||
vma_node_get_used(data_node)) ||
|
||||
(vma_node_get_used(((vma_t *)mln_rbtree_node_data_get(lnode))) && ((vma_addr_get_prot(((vma_t *)mln_rbtree_node_data_get(lnode))->vaddr) !=
|
||||
vma_addr_get_prot(data_node->vaddr)) ||
|
||||
(vma_addr_get_flags(((vma_t *)mln_rbtree_node_data_get(lnode))->vaddr) !=
|
||||
vma_addr_get_flags(data_node->vaddr)))));
|
||||
int r_dmerge = !!mln_rbtree_null(rnode, r_tree) || ((!mln_rbtree_null(rnode, r_tree)) && (vma_node_get_used(mln_rbtree_node_data_get(rnode)) !=
|
||||
vma_node_get_used(data_node)) ||
|
||||
(vma_node_get_used(mln_rbtree_node_data_get(rnode)) && ((vma_addr_get_prot(((vma_t *)mln_rbtree_node_data_get(rnode))->vaddr) !=
|
||||
vma_addr_get_prot(data_node->vaddr)) ||
|
||||
(vma_addr_get_flags(((vma_t *)mln_rbtree_node_data_get(rnode))->vaddr) !=
|
||||
vma_addr_get_flags(data_node->vaddr)))));
|
||||
if (l_dmerge && r_dmerge)
|
||||
// printk("merge_l:%d merge_r:%d.\n", l_dmerge, r_dmerge);
|
||||
if (!l_dmerge && !r_dmerge)
|
||||
{
|
||||
// 左右都是空的
|
||||
vma_node_set_unused(data_node);
|
||||
return 0;
|
||||
}
|
||||
else if (l_dmerge && !r_dmerge)
|
||||
else if (!l_dmerge && r_dmerge)
|
||||
{ // 左边是空的
|
||||
mln_rbtree_delete(r_tree, node);
|
||||
|
||||
@@ -783,7 +803,7 @@ static int vma_node_merge(mln_rbtree_t *r_tree, mln_rbtree_node_t *node)
|
||||
|
||||
mln_rbtree_insert(r_tree, node);
|
||||
}
|
||||
else if (!l_dmerge && r_dmerge)
|
||||
else if (l_dmerge && !r_dmerge)
|
||||
{ // 右边是空的
|
||||
mln_rbtree_delete(r_tree, node);
|
||||
|
||||
@@ -796,6 +816,7 @@ static int vma_node_merge(mln_rbtree_t *r_tree, mln_rbtree_node_t *node)
|
||||
}
|
||||
else
|
||||
{
|
||||
// 左右都不空
|
||||
mln_rbtree_delete(r_tree, node);
|
||||
r_datanode = mln_rbtree_node_data_get(rnode);
|
||||
l_datanode = mln_rbtree_node_data_get(lnode);
|
||||
@@ -803,11 +824,11 @@ static int vma_node_merge(mln_rbtree_t *r_tree, mln_rbtree_node_t *node)
|
||||
mln_rbtree_delete(r_tree, lnode);
|
||||
mln_rbtree_delete(r_tree, rnode);
|
||||
|
||||
data_node->size += l_datanode->size;
|
||||
data_node->size += r_datanode->size;
|
||||
l_datanode->size += data_node->size;
|
||||
l_datanode->size += r_datanode->size;
|
||||
|
||||
mln_rbtree_insert(r_tree, node);
|
||||
vma_node_free(r_tree, lnode);
|
||||
mln_rbtree_insert(r_tree, lnode);
|
||||
vma_node_free(r_tree, node);
|
||||
vma_node_free(r_tree, rnode);
|
||||
}
|
||||
return 0;
|
||||
@@ -837,7 +858,10 @@ static int rbtree_iterate_alloc_tree_del(mln_rbtree_node_t *node, void *udata)
|
||||
// 解除映射
|
||||
unmap_mm(mm_space_get_pdir(param->mm_space),
|
||||
vma_addr_get_addr(node_data->vaddr), PAGE_SHIFT, 1);
|
||||
|
||||
buddy_free(buddy_get_alloter(), (void *)vma_node_get_paddr(node_data));
|
||||
#if VMA_DEBUG2
|
||||
printk("free page: vaddr:0x%lx pmem:0x%lx\n", vma_addr_get_addr(node_data->vaddr), vma_node_get_paddr(node_data));
|
||||
#endif
|
||||
// 从红黑树中删除
|
||||
mln_rbtree_delete(param->r_tree, node);
|
||||
vma_node_free(param->r_tree, node);
|
||||
@@ -871,10 +895,10 @@ int task_vma_free(task_vma_t *task_vma, vaddr_t addr, size_t size)
|
||||
{
|
||||
return lock_status;
|
||||
}
|
||||
#if VMA_DEBUG
|
||||
printk("free pre:\n");
|
||||
task_vma_rbtree_print(&task_vma->idle_tree, mln_rbtree_root(&task_vma->idle_tree));
|
||||
#endif
|
||||
// #if VMA_DEBUG
|
||||
// printk("free pre:\n");
|
||||
// task_vma_rbtree_print(&task_vma->idle_tree, mln_rbtree_root(&task_vma->idle_tree));
|
||||
// #endif
|
||||
task_vma->idle_tree.cmp = vma_idl_tree_eq_cmp_handler;
|
||||
find_node = mln_rbtree_search(
|
||||
&task_vma->idle_tree,
|
||||
@@ -901,12 +925,21 @@ int task_vma_free(task_vma_t *task_vma, vaddr_t addr, size_t size)
|
||||
.size = size,
|
||||
};
|
||||
mln_rbtree_iterate(&task_vma->alloc_tree, rbtree_iterate_alloc_tree_del, ¶m);
|
||||
vma_node_merge(&task_vma->idle_tree, find_node);
|
||||
vma_node_set_unused(node_data); // 设置未使用
|
||||
#if VMA_DEBUG
|
||||
printk("free pre:\n");
|
||||
task_vma_rbtree_print(&task_vma->idle_tree, mln_rbtree_root(&task_vma->idle_tree));
|
||||
#endif
|
||||
vma_node_merge(&task_vma->idle_tree, find_node, FALSE);
|
||||
ret = 0;
|
||||
#if VMA_DEBUG2
|
||||
printk("virt free:[0x%x 0x%x] size:0x%x\n", addr, addr + size - 1, size);
|
||||
#endif
|
||||
#if VMA_DEBUG
|
||||
printk("free:\n");
|
||||
task_vma_rbtree_print(&task_vma->idle_tree, mln_rbtree_root(&task_vma->idle_tree));
|
||||
#endif
|
||||
flush_all_tlb(); /*TODO:跨核刷TLB */
|
||||
end:
|
||||
task_vma_unlock(task_vma, lock_status);
|
||||
return ret;
|
||||
@@ -973,7 +1006,18 @@ int task_vma_page_fault(task_vma_t *task_vma, vaddr_t addr)
|
||||
else
|
||||
{
|
||||
mem = buddy_alloc(buddy_get_alloter(), PAGE_SIZE);
|
||||
memset(mem, 0, PAGE_SIZE);
|
||||
if (mem)
|
||||
{
|
||||
memset(mem, 0, PAGE_SIZE);
|
||||
#if VMA_DEBUG2
|
||||
printk("alloc pmem:0x%lx\n", mem);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
printk("alloc pmem failed.\n");
|
||||
// mem = buddy_alloc(buddy_get_alloter(), PAGE_SIZE);
|
||||
}
|
||||
}
|
||||
if (!mem)
|
||||
{
|
||||
@@ -1006,8 +1050,12 @@ int task_vma_page_fault(task_vma_t *task_vma, vaddr_t addr)
|
||||
ret = -ENOMEM;
|
||||
goto end;
|
||||
}
|
||||
#if VMA_DEBUG2
|
||||
printk("page falut: vaddr:0x%lx alloc mem:0x%lx\n", addr, mem);
|
||||
#endif
|
||||
task_vma->alloc_tree.cmp = vma_idl_tree_insert_cmp_handler;
|
||||
mln_rbtree_insert(&task_vma->alloc_tree, alloc_node);
|
||||
flush_all_tlb();
|
||||
ret = 0;
|
||||
end:
|
||||
task_vma_unlock(task_vma, lock_status);
|
||||
|
||||
@@ -72,7 +72,7 @@ obj_map_entry_t *obj_space_insert(obj_space_t *obj_space, ram_limit_t *ram, kobj
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
// memset(obj_space->tab.tabs[tab_inx], 0, sizeof(obj_map_item_t));
|
||||
memset(obj_space->tab.tabs[tab_inx], 0, sizeof(obj_map_item_t));
|
||||
}
|
||||
obj_map_entry_t *entry = &obj_space->tab.tabs[tab_inx]->items[entry_inx];
|
||||
|
||||
|
||||
@@ -37,13 +37,15 @@ slab_t *slab_create(size_t align_size, const char *name)
|
||||
tmp_slab->align_size = align_size;
|
||||
tmp_slab->total_nr = 0;
|
||||
|
||||
for (size_t i = 0; i < alloc_size / (align_size + sizeof(slab_block_head_t)); i++)
|
||||
for (size_t i = 0; i < (alloc_size - sizeof(slab_head_t)) / (align_size + sizeof(slab_block_head_t)) - 1; i++)
|
||||
{
|
||||
if ((i + 1) * (align_size + sizeof(slab_block_head_t)) + (align_size + sizeof(slab_block_head_t)) > alloc_size)
|
||||
{
|
||||
break;
|
||||
}
|
||||
slab_block_head_t *slab_block = (slab_block_head_t *)((mem + sizeof(slab_t)) +
|
||||
// if ((i + 2) * (align_size + sizeof(slab_block_head_t)) +
|
||||
// sizeof(slab_head_t) >
|
||||
// alloc_size)
|
||||
// {
|
||||
// break;
|
||||
// }
|
||||
slab_block_head_t *slab_block = (slab_block_head_t *)(((addr_t)mem + sizeof(slab_t)) +
|
||||
(i * (align_size + sizeof(slab_block_head_t))));
|
||||
|
||||
slab_block->used = 0;
|
||||
@@ -110,13 +112,15 @@ again:
|
||||
slist_init(&slab_head->next);
|
||||
slist_add(&slab->head, &slab_head->next);
|
||||
|
||||
for (size_t i = 0; i < alloc_size / (slab->align_size + sizeof(slab_block_head_t)); i++)
|
||||
for (size_t i = 0; i < (alloc_size - sizeof(slab_head_t)) / (slab->align_size + sizeof(slab_block_head_t)) - 1; i++)
|
||||
{
|
||||
if ((i + 1) * (slab->align_size + sizeof(slab_block_head_t)) + (slab->align_size + sizeof(slab_block_head_t)) > alloc_size)
|
||||
{
|
||||
break;
|
||||
}
|
||||
slab_block_head_t *slab_block = (slab_block_head_t *)((mem + sizeof(slab_head_t)) +
|
||||
// if ((i + 2) * (slab->align_size + sizeof(slab_block_head_t)) +
|
||||
// sizeof(slab_head_t) >
|
||||
// alloc_size)
|
||||
// {
|
||||
// break;
|
||||
// }
|
||||
slab_block_head_t *slab_block = (slab_block_head_t *)(((addr_t)mem + sizeof(slab_head_t)) +
|
||||
(i * (slab->align_size + sizeof(slab_block_head_t))));
|
||||
|
||||
slab_block->used = 0;
|
||||
|
||||
@@ -137,29 +137,13 @@ static bool_t thread_put(kobject_t *kobj)
|
||||
|
||||
return ref_counter_dec(&th->ref) == 1;
|
||||
}
|
||||
static void thread_release_stage1(kobject_t *kobj)
|
||||
static void thread_release_stage1_impl(thread_t *th)
|
||||
{
|
||||
thread_t *th = container_of(kobj, thread_t, kobj);
|
||||
thread_t *cur = thread_get_current();
|
||||
kobject_invalidate(kobj);
|
||||
|
||||
if (cur != th)
|
||||
if (th->status == THREAD_READY)
|
||||
{
|
||||
//! 线程在运行中,则挂起线程
|
||||
if (th->status == THREAD_READY)
|
||||
{
|
||||
thread_suspend(th);
|
||||
}
|
||||
th->ipc_status = THREAD_IPC_ABORT;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cur->status == THREAD_READY)
|
||||
{
|
||||
thread_suspend(th);
|
||||
}
|
||||
cur->ipc_status = THREAD_IPC_ABORT;
|
||||
thread_suspend(th);
|
||||
}
|
||||
th->ipc_status = THREAD_IPC_ABORT;
|
||||
thread_wait_entry_t *pos;
|
||||
|
||||
slist_foreach_not_next(
|
||||
@@ -174,7 +158,7 @@ static void thread_release_stage1(kobject_t *kobj)
|
||||
if (pos->th != th)
|
||||
{
|
||||
pos->th->ipc_status = THREAD_IPC_ABORT;
|
||||
thread_ready_remote(pos->th, TRUE);
|
||||
thread_ready(pos->th, FALSE);
|
||||
}
|
||||
|
||||
slist_del(&pos->node_timeout);
|
||||
@@ -199,12 +183,113 @@ static void thread_release_stage1(kobject_t *kobj)
|
||||
if (pos2->th != th)
|
||||
{
|
||||
pos2->th->ipc_status = THREAD_IPC_ABORT;
|
||||
thread_ready_remote(pos2->th, TRUE);
|
||||
thread_ready(pos2->th, FALSE);
|
||||
}
|
||||
pos2 = next;
|
||||
}
|
||||
thread_unbind(th);
|
||||
}
|
||||
#if IS_ENABLED(CONFIG_SMP)
|
||||
static int thread_remote_release_stage1_handler(ipi_msg_t *msg, bool_t *is_sched)
|
||||
{
|
||||
thread_t *th = (thread_t *)msg->msg;
|
||||
assert(th);
|
||||
thread_release_stage1_impl(th);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
int thread_release_stage1_remote(thread_t *th)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_SMP)
|
||||
if (th->cpu != arch_get_current_cpu_id())
|
||||
{
|
||||
th->ipi_msg_node.msg = (umword_t)th;
|
||||
th->ipi_msg_node.cb = thread_remote_release_stage1_handler;
|
||||
cpu_ipi_to_msg(1 << th->cpu, &th->ipi_msg_node, IPI_CALL);
|
||||
}
|
||||
else
|
||||
{
|
||||
thread_release_stage1_impl(th);
|
||||
}
|
||||
#else
|
||||
thread_release_stage1_impl(th);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
static void thread_release_stage1(kobject_t *kobj)
|
||||
{
|
||||
thread_t *th = container_of(kobj, thread_t, kobj);
|
||||
thread_t *cur = thread_get_current();
|
||||
kobject_invalidate(kobj);
|
||||
|
||||
if (cur != th)
|
||||
{
|
||||
thread_release_stage1_remote(th);
|
||||
} else {
|
||||
thread_release_stage1_remote(cur);
|
||||
}
|
||||
// if (cur != th)
|
||||
// {
|
||||
// //! 线程在运行中,则挂起线程
|
||||
// if (th->status == THREAD_READY)
|
||||
// {
|
||||
// thread_suspend_remote(th, FALSE);
|
||||
// }
|
||||
// th->ipc_status = THREAD_IPC_ABORT;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if (cur->status == THREAD_READY)
|
||||
// {
|
||||
// thread_suspend_remote(th, FALSE);
|
||||
// }
|
||||
// cur->ipc_status = THREAD_IPC_ABORT;
|
||||
// }
|
||||
// thread_wait_entry_t *pos;
|
||||
|
||||
// slist_foreach_not_next(
|
||||
// pos, (slist_head_t *)pre_cpu_get_current_cpu_var(&wait_send_queue),
|
||||
// node_timeout)
|
||||
// {
|
||||
// assert(pos->th->status == THREAD_SUSPEND);
|
||||
// thread_wait_entry_t *next = slist_next_entry(
|
||||
// pos, (slist_head_t *)pre_cpu_get_current_cpu_var(&wait_send_queue),
|
||||
// node_timeout);
|
||||
|
||||
// if (pos->th != th)
|
||||
// {
|
||||
// pos->th->ipc_status = THREAD_IPC_ABORT;
|
||||
// thread_ready_remote(pos->th, FALSE);
|
||||
// }
|
||||
|
||||
// slist_del(&pos->node_timeout);
|
||||
// if (slist_in_list(&pos->node))
|
||||
// {
|
||||
// slist_del(&pos->node);
|
||||
// }
|
||||
// pos = next;
|
||||
// }
|
||||
// thread_wait_entry_t *pos2;
|
||||
|
||||
// slist_foreach_not_next(
|
||||
// pos2, (slist_head_t *)pre_cpu_get_current_cpu_var(&wait_recv_queue),
|
||||
// node)
|
||||
// {
|
||||
// assert(pos2->th->status == THREAD_SUSPEND);
|
||||
// thread_wait_entry_t *next = slist_next_entry(
|
||||
// pos2, (slist_head_t *)pre_cpu_get_current_cpu_var(&wait_recv_queue),
|
||||
// node);
|
||||
|
||||
// slist_del(&pos2->node);
|
||||
// if (pos2->th != th)
|
||||
// {
|
||||
// pos2->th->ipc_status = THREAD_IPC_ABORT;
|
||||
// thread_ready_remote(pos2->th, FALSE);
|
||||
// }
|
||||
// pos2 = next;
|
||||
// }
|
||||
// thread_unbind(th);
|
||||
}
|
||||
static void thread_release_stage2(kobject_t *kobj)
|
||||
{
|
||||
thread_t *th = container_of(kobj, thread_t, kobj);
|
||||
@@ -930,7 +1015,7 @@ static int thread_remote_suspend_handler(ipi_msg_t *msg, bool_t *is_sched)
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
int thread_suspend_remote(thread_t *th)
|
||||
int thread_suspend_remote(thread_t *th, bool_t is_sche)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_SMP)
|
||||
if (th->cpu != arch_get_current_cpu_id())
|
||||
@@ -941,10 +1026,10 @@ int thread_suspend_remote(thread_t *th)
|
||||
}
|
||||
else
|
||||
{
|
||||
thread_suspend(th);
|
||||
thread_suspend_sw(th, is_sche);
|
||||
}
|
||||
#else
|
||||
thread_suspend(th);
|
||||
thread_suspend_sw(th);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@@ -1338,7 +1423,7 @@ static void thread_syscall(kobject_t *kobj, syscall_prot_t sys_p,
|
||||
}
|
||||
if (tag_th != cur_th)
|
||||
{
|
||||
thread_suspend_remote(tag_th);
|
||||
thread_suspend_remote(tag_th, TRUE);
|
||||
}
|
||||
tag_th->sche.prio = (tge_prio >= PRIO_MAX ? PRIO_MAX - 1 : tge_prio);
|
||||
tag_th->ipi_msg_node.msg = (umword_t)tag_th;
|
||||
|
||||
@@ -287,8 +287,14 @@ void CuSuiteRun(CuSuite* testSuite)
|
||||
for (i = 0 ; i < testSuite->count ; ++i)
|
||||
{
|
||||
CuTest* testCase = testSuite->list[i];
|
||||
printf("=======TEST [%s] start=======\n", testCase->name);
|
||||
CuTestRun(testCase);
|
||||
if (testCase->failed) { testSuite->failCount += 1; }
|
||||
if (testCase->failed) {
|
||||
testSuite->failCount += 1;
|
||||
printf("=======TEST [%s] failed=======\n", testCase->name);
|
||||
} else {
|
||||
printf("=======TEST [%s] sucess=======\n", testCase->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,8 +2,14 @@
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
long sys_be_open(va_list ap);
|
||||
long sys_be_open_at(va_list ap);
|
||||
long sys_be_close(va_list ap);
|
||||
long sys_be_ioctl(va_list ap);
|
||||
long sys_be_writev(va_list ap);
|
||||
long sys_be_write(va_list ap);
|
||||
long sys_be_read(va_list ap);
|
||||
|
||||
long sys_be_ftruncate(va_list ap);
|
||||
long sys_be_getdents(va_list ap);
|
||||
long sys_be_lseek(va_list ap);
|
||||
long sys_be_ioctl(va_list ap);
|
||||
|
||||
@@ -75,13 +75,8 @@ long syscall_backend(long sys_inx, ...);
|
||||
|
||||
void fs_backend_init(void);
|
||||
long be_lseek(long fd, long offset, long whence);
|
||||
long sys_be_lseek(va_list ap);
|
||||
int be_open(const char *path, int flags, mode_t mode);
|
||||
long sys_be_open(va_list ap);
|
||||
long sys_be_open_at(va_list ap);
|
||||
int be_close(int fd);
|
||||
long sys_be_close(va_list ap);
|
||||
long sys_be_getdents(va_list ap);
|
||||
long be_read(long fd, char *buf, long size);
|
||||
long be_write(long fd, char *buf, long size);
|
||||
long be_readv(long fd, const struct iovec *iov, long iovcnt);
|
||||
|
||||
@@ -17,6 +17,7 @@ static const sys_call_func sys_call_list[] = {
|
||||
[SYS_writev] = sys_be_writev,
|
||||
[SYS_ioctl] = sys_be_ioctl,
|
||||
[SYS_lseek] = sys_be_lseek,
|
||||
[SYS_ftruncate] = sys_be_ftruncate,
|
||||
[SYS_getdents64] = sys_be_getdents,
|
||||
[SYS_set_tid_address] = sys_set_tid_address,
|
||||
[SYS_clock_nanosleep] = sys_clock_nanosleep,
|
||||
|
||||
@@ -61,6 +61,9 @@ void be_exit(long exit_code)
|
||||
task_unmap(TASK_THIS, vpage_create_raw3(KOBJ_DELETE_RIGHT, 0, TASK_THIS)); //!< 删除当前task,以及申请得所有对象
|
||||
a_crash(); //!< 强制退出
|
||||
}
|
||||
while (1) {
|
||||
thread_ipc_wait(ipc_timeout_create2(0, 0), NULL, -1);
|
||||
}
|
||||
}
|
||||
|
||||
long sys_exit(va_list ap)
|
||||
|
||||
@@ -1,4 +1,13 @@
|
||||
|
||||
/**
|
||||
* @file fd_map.c
|
||||
* @author your name (1358745329@qq.com)
|
||||
* @brief fd映射层
|
||||
* @version 0.1
|
||||
* @date 2024-08-08
|
||||
*
|
||||
* @copyright Copyright (c) ATShining 2024
|
||||
*
|
||||
*/
|
||||
#include <u_types.h>
|
||||
#include <assert.h>
|
||||
#include <malloc.h>
|
||||
@@ -22,7 +31,14 @@ typedef struct fd_map
|
||||
} fd_map_t;
|
||||
|
||||
static fd_map_t fd_map;
|
||||
|
||||
/**
|
||||
* @brief 分配一个可用的fd
|
||||
*
|
||||
* @param svr_fd
|
||||
* @param priv_fd
|
||||
* @param type
|
||||
* @return int
|
||||
*/
|
||||
int fd_map_alloc(uint32_t svr_fd, uint32_t priv_fd, enum fd_type type)
|
||||
{
|
||||
int alloc_fd = 0;
|
||||
@@ -76,6 +92,13 @@ next:;
|
||||
|
||||
return alloc_fd;
|
||||
}
|
||||
/**
|
||||
* @brief 获取fd
|
||||
*
|
||||
* @param fd
|
||||
* @param new_entry
|
||||
* @return int
|
||||
*/
|
||||
int fd_map_get(int fd, fd_map_entry_t *new_entry)
|
||||
{
|
||||
assert(new_entry);
|
||||
@@ -94,6 +117,13 @@ int fd_map_get(int fd, fd_map_entry_t *new_entry)
|
||||
*new_entry = fd_map.row[row_inx]->entry[inx];
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* @brief 更新fd
|
||||
*
|
||||
* @param fd
|
||||
* @param new_entry
|
||||
* @return int
|
||||
*/
|
||||
int fd_map_update(int fd, fd_map_entry_t *new_entry)
|
||||
{
|
||||
if (fd >= FD_MAP_TOTAL)
|
||||
@@ -110,7 +140,13 @@ int fd_map_update(int fd, fd_map_entry_t *new_entry)
|
||||
fd_map.row[row_inx]->entry[inx].flags = flags;
|
||||
pthread_spin_unlock(&fd_map.lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 释放fd
|
||||
*
|
||||
* @param fd
|
||||
* @param ret_entry
|
||||
* @return int
|
||||
*/
|
||||
int fd_map_free(int fd, fd_map_entry_t *ret_entry)
|
||||
{
|
||||
if (fd >= FD_MAP_TOTAL)
|
||||
|
||||
@@ -25,12 +25,14 @@ int be_open(const char *path, int flags, mode_t mode)
|
||||
{
|
||||
int fd = fs_open(path, flags, mode);
|
||||
|
||||
if (fd < 0) {
|
||||
if (fd < 0)
|
||||
{
|
||||
return fd;
|
||||
}
|
||||
int user_fd = fd_map_alloc(0, fd, FD_FS);
|
||||
|
||||
if (user_fd < 0) {
|
||||
if (user_fd < 0)
|
||||
{
|
||||
be_close(user_fd);
|
||||
}
|
||||
return user_fd;
|
||||
@@ -61,15 +63,21 @@ int be_close(int fd)
|
||||
fd_map_entry_t u_fd;
|
||||
int ret = fd_map_free(fd, &u_fd);
|
||||
|
||||
if (ret < 0) {
|
||||
if (ret < 0)
|
||||
{
|
||||
return -EBADF;
|
||||
}
|
||||
switch (u_fd.type) {
|
||||
case FD_TTY: {
|
||||
} break;
|
||||
case FD_FS: {
|
||||
switch (u_fd.type)
|
||||
{
|
||||
case FD_TTY:
|
||||
{
|
||||
}
|
||||
break;
|
||||
case FD_FS:
|
||||
{
|
||||
return fs_close(u_fd.priv_fd);
|
||||
} break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -ENOSYS;
|
||||
}
|
||||
@@ -89,20 +97,28 @@ static int be_tty_read(char *buf, long size)
|
||||
int len;
|
||||
int r_len = 0;
|
||||
|
||||
if (size == 0) {
|
||||
if (size == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
task_get_pid(TASK_THIS, (umword_t *)(&pid));
|
||||
|
||||
while (r_len < size) {
|
||||
if (pid == 0) {
|
||||
while (r_len < size)
|
||||
{
|
||||
if (pid == 0)
|
||||
{
|
||||
len = ulog_read_bytes(u_get_global_env()->log_hd, buf + r_len, size - r_len);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
len = cons_read(buf + r_len, size - r_len);
|
||||
}
|
||||
if (len < 0) {
|
||||
if (len < 0)
|
||||
{
|
||||
return len;
|
||||
} else if (len == 0) {
|
||||
}
|
||||
else if (len == 0)
|
||||
{
|
||||
u_sleep_ms(10);
|
||||
continue;
|
||||
}
|
||||
@@ -116,16 +132,22 @@ long be_read(long fd, char *buf, long size)
|
||||
fd_map_entry_t u_fd;
|
||||
int ret = fd_map_get(fd, &u_fd);
|
||||
|
||||
if (ret < 0) {
|
||||
if (ret < 0)
|
||||
{
|
||||
return -EBADF;
|
||||
}
|
||||
switch (u_fd.type) {
|
||||
case FD_TTY: {
|
||||
switch (u_fd.type)
|
||||
{
|
||||
case FD_TTY:
|
||||
{
|
||||
return be_tty_read(buf, size);
|
||||
} break;
|
||||
case FD_FS: {
|
||||
}
|
||||
break;
|
||||
case FD_FS:
|
||||
{
|
||||
return fs_read(u_fd.priv_fd, buf, size);
|
||||
} break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -ENOSYS;
|
||||
}
|
||||
@@ -137,24 +159,33 @@ long be_write(long fd, char *buf, long size)
|
||||
fd_map_entry_t u_fd;
|
||||
int ret = fd_map_get(fd, &u_fd);
|
||||
|
||||
if (ret < 0) {
|
||||
if (ret < 0)
|
||||
{
|
||||
return -EBADF;
|
||||
}
|
||||
switch (u_fd.type) {
|
||||
case FD_TTY: {
|
||||
switch (u_fd.type)
|
||||
{
|
||||
case FD_TTY:
|
||||
{
|
||||
pid_t pid;
|
||||
|
||||
task_get_pid(TASK_THIS, (umword_t *)(&pid));
|
||||
if (pid == 0) {
|
||||
if (pid == 0)
|
||||
{
|
||||
ulog_write_bytes(u_get_global_env()->log_hd, buf, size);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
cons_write(buf, size);
|
||||
}
|
||||
return size;
|
||||
} break;
|
||||
case FD_FS: {
|
||||
}
|
||||
break;
|
||||
case FD_FS:
|
||||
{
|
||||
return fs_write(u_fd.priv_fd, buf, size);
|
||||
} break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -ENOSYS;
|
||||
}
|
||||
@@ -163,38 +194,51 @@ long be_write(long fd, char *buf, long size)
|
||||
long be_readv(long fd, const struct iovec *iov, long iovcnt)
|
||||
{
|
||||
long wlen = 0;
|
||||
for (int i = 0; i < iovcnt; i++) {
|
||||
for (int i = 0; i < iovcnt; i++)
|
||||
{
|
||||
fd_map_entry_t u_fd;
|
||||
int ret = fd_map_get(fd, &u_fd);
|
||||
|
||||
if (ret < 0) {
|
||||
if (ret < 0)
|
||||
{
|
||||
return -EBADF;
|
||||
}
|
||||
switch (u_fd.type) {
|
||||
case FD_TTY: {
|
||||
switch (u_fd.type)
|
||||
{
|
||||
case FD_TTY:
|
||||
{
|
||||
pid_t pid;
|
||||
int read_cn;
|
||||
|
||||
task_get_pid(TASK_THIS, (umword_t *)(&pid));
|
||||
if (pid == 0) {
|
||||
if (pid == 0)
|
||||
{
|
||||
read_cn = ulog_read_bytes(u_get_global_env()->log_hd, iov[i].iov_base, iov[i].iov_len);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
again_read:
|
||||
read_cn = cons_read(iov[i].iov_base, iov[i].iov_len);
|
||||
if (read_cn < 0) {
|
||||
if (read_cn < 0)
|
||||
{
|
||||
return read_cn;
|
||||
} else if (read_cn == 0) {
|
||||
}
|
||||
else if (read_cn == 0)
|
||||
{
|
||||
u_sleep_ms(10); // TODO:改成信号量
|
||||
goto again_read;
|
||||
}
|
||||
}
|
||||
wlen += read_cn;
|
||||
} break;
|
||||
case FD_FS: {
|
||||
}
|
||||
break;
|
||||
case FD_FS:
|
||||
{
|
||||
int rsize = fs_read(u_fd.priv_fd, iov[i].iov_base, iov[i].iov_len);
|
||||
|
||||
wlen += rsize;
|
||||
} break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -ENOSYS;
|
||||
}
|
||||
@@ -204,30 +248,40 @@ long be_readv(long fd, const struct iovec *iov, long iovcnt)
|
||||
long be_writev(long fd, const struct iovec *iov, long iovcnt)
|
||||
{
|
||||
long wlen = 0;
|
||||
for (int i = 0; i < iovcnt; i++) {
|
||||
for (int i = 0; i < iovcnt; i++)
|
||||
{
|
||||
fd_map_entry_t u_fd;
|
||||
int ret = fd_map_get(fd, &u_fd);
|
||||
|
||||
if (ret < 0) {
|
||||
if (ret < 0)
|
||||
{
|
||||
return -EBADF;
|
||||
}
|
||||
switch (u_fd.type) {
|
||||
case FD_TTY: {
|
||||
switch (u_fd.type)
|
||||
{
|
||||
case FD_TTY:
|
||||
{
|
||||
pid_t pid;
|
||||
|
||||
task_get_pid(TASK_THIS, (umword_t *)(&pid));
|
||||
if (pid == 0) {
|
||||
if (pid == 0)
|
||||
{
|
||||
ulog_write_bytes(u_get_global_env()->log_hd, iov[i].iov_base, iov[i].iov_len);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
cons_write(iov[i].iov_base, iov[i].iov_len);
|
||||
}
|
||||
wlen += iov[i].iov_len;
|
||||
} break;
|
||||
case FD_FS: {
|
||||
}
|
||||
break;
|
||||
case FD_FS:
|
||||
{
|
||||
int wsize = fs_write(u_fd.priv_fd, iov[i].iov_base, iov[i].iov_len);
|
||||
|
||||
wlen += wsize;
|
||||
} break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -ENOSYS;
|
||||
}
|
||||
@@ -288,16 +342,22 @@ long be_lseek(long fd, long offset, long whence)
|
||||
fd_map_entry_t u_fd;
|
||||
int ret = fd_map_get(fd, &u_fd);
|
||||
|
||||
if (ret < 0) {
|
||||
if (ret < 0)
|
||||
{
|
||||
return -EBADF;
|
||||
}
|
||||
switch (u_fd.type) {
|
||||
case FD_TTY: {
|
||||
switch (u_fd.type)
|
||||
{
|
||||
case FD_TTY:
|
||||
{
|
||||
return -ENOSYS;
|
||||
} break;
|
||||
case FD_FS: {
|
||||
}
|
||||
break;
|
||||
case FD_FS:
|
||||
{
|
||||
return fs_lseek(u_fd.priv_fd, offset, whence);
|
||||
} break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -ENOSYS;
|
||||
}
|
||||
@@ -321,16 +381,22 @@ long be_getdents(long fd, char *buf, size_t size)
|
||||
fd_map_entry_t u_fd;
|
||||
int ret = fd_map_get(fd, &u_fd);
|
||||
|
||||
if (ret < 0) {
|
||||
if (ret < 0)
|
||||
{
|
||||
return -EBADF;
|
||||
}
|
||||
switch (u_fd.type) {
|
||||
case FD_TTY: {
|
||||
switch (u_fd.type)
|
||||
{
|
||||
case FD_TTY:
|
||||
{
|
||||
return -ENOSYS;
|
||||
} break;
|
||||
case FD_FS: {
|
||||
}
|
||||
break;
|
||||
case FD_FS:
|
||||
{
|
||||
ret = fs_readdir(u_fd.priv_fd, (struct dirent *)buf);
|
||||
} break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -ENOSYS;
|
||||
}
|
||||
@@ -345,3 +411,15 @@ long sys_be_getdents(va_list ap)
|
||||
|
||||
return be_getdents(fd, buf, size);
|
||||
}
|
||||
long sys_be_ftruncate(va_list ap)
|
||||
{
|
||||
long fd;
|
||||
off_t off;
|
||||
int ret;
|
||||
|
||||
ARG_2_BE(ap, fd, long, off, off_t);
|
||||
|
||||
ret = fs_ftruncate(fd, off);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file futex_backend.c
|
||||
* @author ATShining (1358745329@qq.com)
|
||||
* @brief 该文件用ipc模拟一个futex锁
|
||||
* @brief futex锁
|
||||
* @version 0.1
|
||||
* @date 2023-09-09
|
||||
*
|
||||
@@ -70,7 +70,7 @@ _try_again:
|
||||
long sys_futex(va_list ap)
|
||||
{
|
||||
uint32_t *uaddr;
|
||||
long futex_op;
|
||||
long futex_op;
|
||||
long val;
|
||||
const struct timespec *timeout;
|
||||
long uaddr2;
|
||||
|
||||
Submodule mkrtos_user/lib/mkrtos-musl updated: 48d0cc99f2...69907aa35c
@@ -2,10 +2,13 @@
|
||||
|
||||
#include <stddef.h>
|
||||
#include <dirent.h>
|
||||
#include <u_types.h>
|
||||
int fs_open(const char *path, int flags, int mode);
|
||||
int fs_read(int fd, void *buf, size_t len);
|
||||
int fs_write(int fd, void *buf, size_t len);
|
||||
int fs_close(int fd);
|
||||
int fs_lseek(int fd, int offs, int whence);
|
||||
int fs_readdir(int _fd, struct dirent *dirent);
|
||||
int fs_read(sd_t fd, void *buf, size_t len);
|
||||
int fs_write(sd_t fd, void *buf, size_t len);
|
||||
int fs_close(sd_t fd);
|
||||
int fs_lseek(sd_t fd, int offs, int whence);
|
||||
int fs_ftruncate(sd_t _fd, off_t off);
|
||||
int fs_fsync(sd_t _fd);
|
||||
int fs_readdir(sd_t _fd, struct dirent *dirent);
|
||||
int fs_symlink(const char *src, const char *dst);
|
||||
|
||||
@@ -4,9 +4,11 @@
|
||||
#include <u_thread.h>
|
||||
|
||||
#if CONFIG_THREAD_MSG_BUG_LEN == 128
|
||||
#define FS_RPC_BUF_LEN 400
|
||||
#define rpc_ref_file_array_t rpc_ref_array_uint32_t_uint8_t_400_t
|
||||
#define rpc_file_array_t rpc_array_uint32_t_uint8_t_400_t
|
||||
#else
|
||||
#define FS_RPC_BUF_LEN 32
|
||||
#define rpc_ref_file_array_t rpc_ref_array_uint32_t_uint8_t_32_t
|
||||
#define rpc_file_array_t rpc_array_uint32_t_uint8_t_32_t
|
||||
#endif
|
||||
|
||||
@@ -46,6 +46,26 @@ sd_t fs_open(const char *path, int flags, int mode)
|
||||
|
||||
return mk_sd_init2(hd, msg_tag_get_val(tag)).raw;
|
||||
}
|
||||
/*close*/
|
||||
RPC_GENERATION_CALL1(fs_t, FS_PROT, FS_CLOSE, close,
|
||||
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, fd)
|
||||
int fs_close(sd_t _fd)
|
||||
{
|
||||
obj_handler_t hd = mk_sd_init_raw(_fd).hd;
|
||||
int fd = mk_sd_init_raw(_fd).fd;
|
||||
|
||||
rpc_int_t rpc_fd = {
|
||||
.data = fd,
|
||||
};
|
||||
msg_tag_t tag = fs_t_close_call(hd, &rpc_fd);
|
||||
|
||||
if (msg_tag_get_val(tag) < 0)
|
||||
{
|
||||
return msg_tag_get_val(tag);
|
||||
}
|
||||
|
||||
return msg_tag_get_val(tag);
|
||||
}
|
||||
/*read*/
|
||||
RPC_GENERATION_CALL3(fs_t, FS_PROT, FS_READ, read,
|
||||
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, fd,
|
||||
@@ -66,7 +86,7 @@ int fs_read(sd_t _fd, void *buf, size_t len)
|
||||
{
|
||||
int r_once_len = 0;
|
||||
|
||||
r_once_len = MIN(32, len - rlen);
|
||||
r_once_len = MIN(FS_RPC_BUF_LEN, len - rlen);
|
||||
rpc_ref_file_array_t rpc_buf = {
|
||||
.data = buf + rlen,
|
||||
.len = r_once_len,
|
||||
@@ -108,7 +128,7 @@ int fs_write(sd_t _fd, void *buf, size_t len)
|
||||
{
|
||||
int w_once_len = 0;
|
||||
|
||||
w_once_len = MIN(32, len - wlen);
|
||||
w_once_len = MIN(FS_RPC_BUF_LEN, len - wlen);
|
||||
rpc_ref_file_array_t rpc_buf = {
|
||||
.data = buf + wlen,
|
||||
.len = w_once_len,
|
||||
@@ -131,26 +151,6 @@ int fs_write(sd_t _fd, void *buf, size_t len)
|
||||
|
||||
return wlen;
|
||||
}
|
||||
/*close*/
|
||||
RPC_GENERATION_CALL1(fs_t, FS_PROT, FS_CLOSE, close,
|
||||
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, fd)
|
||||
int fs_close(sd_t _fd)
|
||||
{
|
||||
obj_handler_t hd = mk_sd_init_raw(_fd).hd;
|
||||
int fd = mk_sd_init_raw(_fd).fd;
|
||||
|
||||
rpc_int_t rpc_fd = {
|
||||
.data = fd,
|
||||
};
|
||||
msg_tag_t tag = fs_t_close_call(hd, &rpc_fd);
|
||||
|
||||
if (msg_tag_get_val(tag) < 0)
|
||||
{
|
||||
return msg_tag_get_val(tag);
|
||||
}
|
||||
|
||||
return msg_tag_get_val(tag);
|
||||
}
|
||||
/*lseek*/
|
||||
RPC_GENERATION_CALL3(fs_t, FS_PROT, FS_LSEEK, lseek,
|
||||
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, fd,
|
||||
@@ -180,6 +180,50 @@ int fs_lseek(sd_t _fd, int offs, int whence)
|
||||
|
||||
return msg_tag_get_val(tag);
|
||||
}
|
||||
/*ftruncate*/
|
||||
RPC_GENERATION_CALL2(fs_t, FS_PROT, FS_FTRUNCATE, ftruncate,
|
||||
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, fd,
|
||||
rpc_int64_t_t, rpc_int64_t_t, RPC_DIR_IN, RPC_TYPE_DATA, offs)
|
||||
int fs_ftruncate(sd_t _fd, off_t off)
|
||||
{
|
||||
obj_handler_t hd = mk_sd_init_raw(_fd).hd;
|
||||
int fd = mk_sd_init_raw(_fd).fd;
|
||||
|
||||
rpc_int_t rpc_fd = {
|
||||
.data = fd,
|
||||
};
|
||||
rpc_int64_t_t rpc_offs = {
|
||||
.data = off,
|
||||
};
|
||||
msg_tag_t tag = fs_t_ftruncate_call(hd, &rpc_fd, &rpc_offs);
|
||||
|
||||
if (msg_tag_get_val(tag) < 0)
|
||||
{
|
||||
return msg_tag_get_val(tag);
|
||||
}
|
||||
|
||||
return msg_tag_get_val(tag);
|
||||
}
|
||||
/*fsync*/
|
||||
RPC_GENERATION_CALL1(fs_t, FS_PROT, FS_SYNC, fsync,
|
||||
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, fd)
|
||||
int fs_fsync(sd_t _fd)
|
||||
{
|
||||
obj_handler_t hd = mk_sd_init_raw(_fd).hd;
|
||||
int fd = mk_sd_init_raw(_fd).fd;
|
||||
|
||||
rpc_int_t rpc_fd = {
|
||||
.data = fd,
|
||||
};
|
||||
msg_tag_t tag = fs_t_fsync_call(hd, &rpc_fd);
|
||||
|
||||
if (msg_tag_get_val(tag) < 0)
|
||||
{
|
||||
return msg_tag_get_val(tag);
|
||||
}
|
||||
|
||||
return msg_tag_get_val(tag);
|
||||
}
|
||||
/*readdir*/
|
||||
RPC_GENERATION_CALL2(fs_t, FS_PROT, FS_READDIR, readdir,
|
||||
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, fd,
|
||||
@@ -208,6 +252,7 @@ int fs_readdir(sd_t _fd, dirent_t *dirent)
|
||||
|
||||
return msg_tag_get_val(tag);
|
||||
}
|
||||
|
||||
RPC_GENERATION_CALL2(fs_t, FS_PROT, FS_SYMLINK, symlink,
|
||||
rpc_ref_file_array_t, rpc_file_array_t, RPC_DIR_IN, RPC_TYPE_DATA, src,
|
||||
rpc_ref_file_array_t, rpc_file_array_t, RPC_DIR_IN, RPC_TYPE_DATA, dst)
|
||||
|
||||
@@ -86,7 +86,7 @@ RPC_GENERATION_DISPATCH3(fs_t, FS_PROT, FS_LSEEK, lseek,
|
||||
/*ftruncate*/
|
||||
RPC_GENERATION_OP2(fs_t, FS_PROT, FS_FTRUNCATE, ftruncate,
|
||||
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, fd,
|
||||
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, offs)
|
||||
rpc_int64_t_t, rpc_int64_t_t, RPC_DIR_IN, RPC_TYPE_DATA, offs)
|
||||
{
|
||||
int ret = fs_svr_ftruncate(fd->data, offs->data);
|
||||
return ret;
|
||||
@@ -94,7 +94,7 @@ RPC_GENERATION_OP2(fs_t, FS_PROT, FS_FTRUNCATE, ftruncate,
|
||||
|
||||
RPC_GENERATION_DISPATCH2(fs_t, FS_PROT, FS_FTRUNCATE, ftruncate,
|
||||
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, fd,
|
||||
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, offs)
|
||||
rpc_int64_t_t, rpc_int64_t_t, RPC_DIR_IN, RPC_TYPE_DATA, offs)
|
||||
|
||||
/*fsync*/
|
||||
RPC_GENERATION_OP1(fs_t, FS_PROT, FS_SYNC, fsync,
|
||||
|
||||
@@ -182,6 +182,8 @@ static inline void rpc_memcpy(void *dst, void *src, size_t size)
|
||||
|
||||
RPC_TYPE_DEF_ALL(int) //!< 定义所有的
|
||||
RPC_TYPE_DEF_ALL(uint32_t) //!< 定义所有的
|
||||
RPC_TYPE_DEF_ALL(int64_t) //!< 定义所有的
|
||||
RPC_TYPE_DEF_ALL(uint64_t) //!< 定义所有的
|
||||
RPC_TYPE_DEF_ALL(size_t) //!< 定义所有的
|
||||
RPC_TYPE_DEF_ALL(umword_t) //!< 定义所有的
|
||||
RPC_TYPE_DEF_ALL(mword_t) //!< 定义所有的
|
||||
|
||||
@@ -62,12 +62,18 @@ int elf_load(umword_t elf_data, size_t size, addr_t *entry_addr, obj_handler_t d
|
||||
void *mem;
|
||||
msg_tag_t tag;
|
||||
|
||||
printf("%s:%d.\n", __func__, __LINE__);
|
||||
|
||||
tag = u_vmam_alloc(VMA_PROT, vma_addr_create(VPAGE_PROT_RWX, 0, 0), mem_size, 0, (addr_t *)(&mem));
|
||||
if (msg_tag_get_val(tag) < 0)
|
||||
{
|
||||
return msg_tag_get_val(tag);
|
||||
}
|
||||
printf("%s:%d mem:0x%p size:0x%x.\n", __func__, __LINE__, mem, mem_size);
|
||||
|
||||
memset(mem, 0, mem_size);
|
||||
printf("%s:%d.\n", __func__, __LINE__);
|
||||
|
||||
mword_t offset = 0;
|
||||
|
||||
elf_phdr = (Elf64_Phdr *)(elf_header->e_phoff + elf_data);
|
||||
|
||||
@@ -314,7 +314,7 @@ int app_load(const char *name, uenv_t *cur_env, pid_t *pid, char *argv[], int ar
|
||||
}
|
||||
|
||||
/*启动线程运行*/
|
||||
tag = thread_run_cpu(hd_thread, 2, 0);
|
||||
tag = thread_run_cpu(hd_thread, 2, -1);
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
task_unmap(TASK_THIS, vpage_create_raw3(0, 0, hd_thread));
|
||||
handler_free(hd_thread);
|
||||
|
||||
@@ -1,4 +1,13 @@
|
||||
|
||||
/**
|
||||
* @file u_rpc_svr.c
|
||||
* @author ATShining (1358745329@qq.com)
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2024-08-27
|
||||
*
|
||||
* @copyright Copyright (c) 2024
|
||||
*
|
||||
*/
|
||||
#include "u_ipc.h"
|
||||
#include "u_factory.h"
|
||||
#include "u_hd_man.h"
|
||||
|
||||
@@ -1,4 +1,13 @@
|
||||
|
||||
/**
|
||||
* @file u_sig.c
|
||||
* @author ATShining (1358745329@qq.com)
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2024-08-27
|
||||
*
|
||||
* @copyright Copyright (c) 2024
|
||||
*
|
||||
*/
|
||||
#include <u_thread_util.h>
|
||||
#include <u_util.h>
|
||||
#include <u_rpc_svr.h>
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
/**
|
||||
* @file u_sleep.c
|
||||
* @author ATShining (1358745329@qq.com)
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2024-08-27
|
||||
*
|
||||
* @copyright Copyright (c) 2024
|
||||
*
|
||||
*/
|
||||
#include "u_types.h"
|
||||
#include "u_hd_man.h"
|
||||
#include "u_prot.h"
|
||||
|
||||
@@ -1,4 +1,13 @@
|
||||
|
||||
/**
|
||||
* @file u_str.c
|
||||
* @author ATShining (1358745329@qq.com)
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2024-08-27
|
||||
*
|
||||
* @copyright Copyright (c) 2024
|
||||
*
|
||||
*/
|
||||
#include "u_types.h"
|
||||
#include "u_queue.h"
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -4,3 +4,4 @@
|
||||
void u_thread_del(obj_handler_t th_hd);
|
||||
int u_thread_create(obj_handler_t *th_hd, void *stack, void *msg_buf, void (*thread_func)(void));
|
||||
int u_thread_run(obj_handler_t th_hd, int prio);
|
||||
int u_thread_run_cpu(obj_handler_t th_hd, int prio, int cpu);
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
/**
|
||||
* @file u_queue.c
|
||||
* @author ATShining (1358745329@qq.com)
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2024-08-27
|
||||
*
|
||||
* @copyright Copyright (c) 2024
|
||||
*
|
||||
*/
|
||||
#include "u_types.h"
|
||||
#include "u_queue.h"
|
||||
#include <assert.h>
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
/**
|
||||
* @file u_thread_util.c
|
||||
* @author ATShining (1358745329@qq.com)
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2024-08-27
|
||||
*
|
||||
* @copyright Copyright (c) 2024
|
||||
*
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <u_factory.h>
|
||||
@@ -58,4 +68,8 @@ int u_thread_create(obj_handler_t *th_hd, void *stack, void *msg_buf, void (*thr
|
||||
int u_thread_run(obj_handler_t th_hd, int prio)
|
||||
{
|
||||
return msg_tag_get_val(thread_run(th_hd, prio));
|
||||
}
|
||||
int u_thread_run_cpu(obj_handler_t th_hd, int prio, int cpu)
|
||||
{
|
||||
return msg_tag_get_val(thread_run_cpu(th_hd, prio, cpu));
|
||||
}
|
||||
@@ -362,19 +362,33 @@ int fs_svr_readdir(int fd, dirent_t *dir)
|
||||
}
|
||||
int fs_svr_mkdir(char *path)
|
||||
{
|
||||
return -ENOSYS;
|
||||
FRESULT ret = f_mkdir(path);
|
||||
|
||||
return fatfs_err_conv(ret);
|
||||
}
|
||||
int fs_svr_unlink(char *path)
|
||||
{
|
||||
return -ENOSYS;
|
||||
FRESULT ret = f_unlink(path);
|
||||
|
||||
return fatfs_err_conv(ret);
|
||||
}
|
||||
int fs_svr_renmae(char *oldname, char *newname)
|
||||
{
|
||||
return -ENOSYS;
|
||||
return fatfs_err_conv(f_rename(oldname, newname));
|
||||
}
|
||||
int fs_svr_fstat(int fd, stat_t *stat)
|
||||
{
|
||||
return -ENOSYS;
|
||||
file_desc_t *file = file_get(fd);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
memset(stat, 0, sizeof(*stat));
|
||||
stat->st_size = file->type == 1 ? 0 : f_size(&file->fp);
|
||||
stat->st_mode = file->type == 1 ? S_IFDIR : S_IFREG;
|
||||
stat->st_blksize = 0;
|
||||
return 0;
|
||||
}
|
||||
int fs_svr_symlink(const char *src, const char *dst)
|
||||
{
|
||||
|
||||
@@ -20,6 +20,7 @@ target_link_libraries(init.elf
|
||||
sys_svr
|
||||
cpio
|
||||
util
|
||||
cutest
|
||||
--no-whole-archive
|
||||
${GCC_LIB_PATH}/libgcc.a
|
||||
)
|
||||
@@ -30,6 +31,7 @@ target_include_directories(
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/sys_util/inc
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/sys_svr/inc
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/cpio
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/cutest
|
||||
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/server/init/src
|
||||
)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "file_desc.h"
|
||||
static file_desc_t fd_list[FILE_DESC_NR];
|
||||
|
||||
file_desc_t *fd_alloc(ns_node_t *node)
|
||||
{
|
||||
|
||||
@@ -9,7 +9,6 @@ typedef struct file_desc
|
||||
ns_node_t *node_iter;
|
||||
} file_desc_t;
|
||||
|
||||
static file_desc_t fd_list[FILE_DESC_NR];
|
||||
file_desc_t *fd_alloc(ns_node_t *node);
|
||||
file_desc_t *fd_get(int fd);
|
||||
void fd_free(int fd);
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
|
||||
static void test(void)
|
||||
{
|
||||
test_main();
|
||||
#if 0
|
||||
u_sema_test();
|
||||
u_sema_test2();
|
||||
|
||||
@@ -74,10 +74,10 @@ int parse_cfg(const char *parse_cfg_file_name, uenv_t *env)
|
||||
}
|
||||
pid_t pid;
|
||||
char *args[] = {
|
||||
"xx",/**FIXME: */
|
||||
"-t"
|
||||
name,
|
||||
NULL
|
||||
};
|
||||
int ret = app_load(name, env, &pid, args, 2, NULL, 0);
|
||||
int ret = app_load(name, env, &pid, args, 1, NULL, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
printf("%s load fail, 0x%x\n", name, ret);
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
#include "u_types.h"
|
||||
#include "u_prot.h"
|
||||
#include "u_app.h"
|
||||
#include "u_factory.h"
|
||||
#include "u_mm.h"
|
||||
#include "u_task.h"
|
||||
#include "u_hd_man.h"
|
||||
#include "u_thread.h"
|
||||
#include "u_ipc.h"
|
||||
#include "cpiofs.h"
|
||||
#include "u_env.h"
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <elf.h>
|
||||
#include <stdio.h>
|
||||
umword_t app_stack_push(umword_t *stack, umword_t val)
|
||||
{
|
||||
*stack = val;
|
||||
stack++;
|
||||
return (umword_t)stack;
|
||||
}
|
||||
#define TEST_APP_NAME "shell"
|
||||
/**
|
||||
* @brief 加载一个app,并启动
|
||||
*
|
||||
*/
|
||||
void app_test(void)
|
||||
{
|
||||
msg_tag_t tag;
|
||||
int type;
|
||||
|
||||
umword_t addr;
|
||||
int ret = cpio_find_file((umword_t)0x8020000, (umword_t)0x8040000, TEST_APP_NAME, NULL, &type, &addr);
|
||||
assert(ret >= 0);
|
||||
assert(type == 0);
|
||||
|
||||
app_info_t *app = (app_info_t *)addr;
|
||||
printf("app addr is 0x%x\n", app);
|
||||
umword_t ram_base;
|
||||
obj_handler_t hd_task = handler_alloc();
|
||||
obj_handler_t hd_thread = handler_alloc();
|
||||
obj_handler_t hd_ipc = handler_alloc();
|
||||
|
||||
assert(hd_task != HANDLER_INVALID);
|
||||
assert(hd_thread != HANDLER_INVALID);
|
||||
|
||||
tag = factory_create_task(FACTORY_PROT, vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, hd_task));
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
tag = factory_create_thread(FACTORY_PROT, vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, hd_thread));
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
tag = factory_create_ipc(FACTORY_PROT, vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, hd_ipc));
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
printf("ipc hd is %d\n", hd_ipc);
|
||||
|
||||
tag = task_alloc_ram_base(hd_task, app->i.ram_size, &ram_base);
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
tag = task_map(hd_task, hd_task, TASK_PROT, 0);
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
tag = task_map(hd_task, LOG_PROT, LOG_PROT, 0);
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
tag = task_map(hd_task, hd_ipc, hd_ipc, 0);
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
tag = task_map(hd_task, hd_thread, THREAD_MAIN, 0);
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
tag = task_map(hd_task, FACTORY_PROT, FACTORY_PROT, 0);
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
tag = task_map(hd_task, MM_PROT, MM_PROT, 0);
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
|
||||
tag = thread_msg_buf_set(hd_thread, (void *)(ram_base + app->i.ram_size));
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
tag = thread_bind_task(hd_thread, hd_task);
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
ipc_bind(hd_ipc, hd_thread, 0);
|
||||
|
||||
void *sp_addr = (char *)ram_base + app->i.stack_offset - app->i.data_offset;
|
||||
void *sp_addr_top = (char *)sp_addr + app->i.stack_size;
|
||||
|
||||
umword_t usp_top = ((umword_t)((umword_t)sp_addr_top - 8) & ~0x7UL) - MSG_BUG_LEN;
|
||||
|
||||
/**处理传参*/
|
||||
umword_t *buf;
|
||||
thread_msg_buf_get(THREAD_MAIN, (umword_t *)(&buf), NULL);
|
||||
umword_t *buf_bk = buf;
|
||||
|
||||
// 传递的参数放到最后64字节,可以存放16-1个words.
|
||||
buf = (umword_t *)app_stack_push(buf, 1); //!< argc 24
|
||||
buf = (umword_t *)app_stack_push(buf, (umword_t)usp_top + 64); //!< argv[0]
|
||||
buf = (umword_t *)app_stack_push(buf, 0); //!< NULL
|
||||
buf = (umword_t *)app_stack_push(buf, (umword_t)usp_top + 96); //!< env[0...N]
|
||||
buf = (umword_t *)app_stack_push(buf, 0); //!< NULL
|
||||
|
||||
buf = (umword_t *)app_stack_push(buf, (umword_t)AT_PAGESZ); //!< auxvt[0...N]
|
||||
buf = (umword_t *)app_stack_push(buf, MK_PAGE_SIZE); //!< auxvt[0...N]
|
||||
buf = (umword_t *)app_stack_push(buf, (umword_t)usp_top + 96 + 16); //!< auxvt[0...N]
|
||||
buf = (umword_t *)app_stack_push(buf, 0xfe); //!< auxvt[0...N]
|
||||
|
||||
buf = (umword_t *)app_stack_push(buf, 0); //!< 0
|
||||
buf = (umword_t *)app_stack_push(buf, 0); //!< 0
|
||||
buf = (umword_t *)app_stack_push(buf, 0); //!< 0
|
||||
buf = (umword_t *)app_stack_push(buf, 0); //!< 0
|
||||
buf = (umword_t *)app_stack_push(buf, 0); //!< 0
|
||||
buf = (umword_t *)app_stack_push(buf, 0); //!< 0
|
||||
|
||||
printf("argc addr is 0x%x\n", buf);
|
||||
memcpy((char *)buf_bk + 64, TEST_APP_NAME, strlen(TEST_APP_NAME) + 1);
|
||||
memcpy((char *)buf_bk + 96, "PATH=/", strlen("PATH=/") + 1);
|
||||
uenv_t *uenv = (uenv_t *)((char *)buf_bk + 96 + 16);
|
||||
uenv->log_hd = LOG_PROT;
|
||||
|
||||
tag = thread_exec_regs(hd_thread, (umword_t)addr, (umword_t)sp_addr_top, ram_base, 1);
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
|
||||
/*启动线程运行*/
|
||||
tag = thread_run(hd_thread, 2);
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
|
||||
umword_t len;
|
||||
thread_msg_buf_get(THREAD_MAIN, (umword_t *)(&buf), NULL);
|
||||
strcpy((char *)buf, "hello shell.\n");
|
||||
thread_ipc_call(msg_tag_init4(0, ROUND_UP(strlen((char *)buf), WORD_BYTES), 0, 0), hd_ipc, ipc_timeout_create2(0, 0));
|
||||
printf("test ok\n");
|
||||
}
|
||||
@@ -11,7 +11,8 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <u_sleep.h>
|
||||
|
||||
#include <u_thread_util.h>
|
||||
#include <CuTest.h>
|
||||
#define DEBUG_IPC_CALL 1
|
||||
|
||||
static umword_t th1_hd = 0;
|
||||
@@ -52,8 +53,16 @@ static void thread_test_func(void)
|
||||
// buf[0] = ',';
|
||||
test_cn++;
|
||||
thread_ipc_reply(msg_tag_init4(0, ROUND_UP(strlen(buf), WORD_BYTES), 0, 0), ipc_timeout_create2(0, 0));
|
||||
if (test_cn >= 1000)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf("thread_test_func.\n");
|
||||
while (1)
|
||||
{
|
||||
u_sleep_ms(100000);
|
||||
}
|
||||
task_unmap(TASK_PROT, vpage_create_raw3(KOBJ_DELETE_RIGHT, 0, th1_hd));
|
||||
printf("Error\n");
|
||||
}
|
||||
@@ -69,8 +78,16 @@ static void thread_test_func2(void)
|
||||
strcpy(buf, "I am th2.\n");
|
||||
thread_ipc_call(msg_tag_init4(0, ROUND_UP(strlen(buf), WORD_BYTES), 0, 0), th1_hd, ipc_timeout_create2(0, 0));
|
||||
printf("th2:%s", buf);
|
||||
if (test_cn >= 1000)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf("thread_test_func2.\n");
|
||||
while (1)
|
||||
{
|
||||
u_sleep_ms(100000);
|
||||
}
|
||||
task_unmap(TASK_PROT, vpage_create_raw3(KOBJ_DELETE_RIGHT, 0, th2_hd));
|
||||
printf("Error\n");
|
||||
}
|
||||
@@ -88,8 +105,16 @@ static void thread_test_func3(void)
|
||||
strcpy(buf, "I am th3.\n");
|
||||
thread_ipc_call(msg_tag_init4(0, ROUND_UP(strlen(buf), WORD_BYTES), 0, 0), th1_hd, ipc_timeout_create2(0, 0));
|
||||
printf("th3:%s", buf);
|
||||
if (test_cn >= 1000)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf("thread_test_func3.\n");
|
||||
while (1)
|
||||
{
|
||||
u_sleep_ms(100000);
|
||||
}
|
||||
task_unmap(TASK_PROT, vpage_create_raw3(KOBJ_DELETE_RIGHT, 0, th3_hd));
|
||||
printf("Error\n");
|
||||
}
|
||||
@@ -106,8 +131,16 @@ static void thread_test_func4(void)
|
||||
strcpy(buf, "I am th4.\n");
|
||||
thread_ipc_call(msg_tag_init4(0, ROUND_UP(strlen(buf), WORD_BYTES), 0, 0), th1_hd, ipc_timeout_create2(0, 0));
|
||||
printf("th4:%s", buf);
|
||||
if (test_cn >= 1000)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf("thread_test_func4.\n");
|
||||
while (1)
|
||||
{
|
||||
u_sleep_ms(100000);
|
||||
}
|
||||
task_unmap(TASK_PROT, vpage_create_raw3(KOBJ_DELETE_RIGHT, 0, th3_hd));
|
||||
printf("Error\n");
|
||||
}
|
||||
@@ -115,7 +148,7 @@ static void thread_test_func4(void)
|
||||
* @brief 启动两个线程并进行ipc测试
|
||||
*
|
||||
*/
|
||||
void ipc_test(void)
|
||||
static void ipc_test(CuTest *cu)
|
||||
{
|
||||
msg_tag_t tag;
|
||||
th1_hd = handler_alloc();
|
||||
@@ -179,6 +212,22 @@ void ipc_test(void)
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
tag = thread_run_cpu(th4_hd, 2, 0);
|
||||
|
||||
while (test_cn++ < 1000)
|
||||
while (test_cn < 1000)
|
||||
;
|
||||
/*
|
||||
TODO:存在bug
|
||||
u_thread_del(th1_hd);
|
||||
u_thread_del(th2_hd);
|
||||
u_thread_del(th3_hd);
|
||||
u_thread_del(th4_hd);
|
||||
*/
|
||||
}
|
||||
|
||||
CuSuite *ipc_test_suite(void)
|
||||
{
|
||||
CuSuite *suite = CuSuiteNew();
|
||||
|
||||
SUITE_ADD_TEST(suite, ipc_test);
|
||||
|
||||
return suite;
|
||||
}
|
||||
|
||||
@@ -2,17 +2,27 @@
|
||||
#include "u_prot.h"
|
||||
#include "u_log.h"
|
||||
#include <stdio.h>
|
||||
#include <CuTest.h>
|
||||
|
||||
void ulog_test(void)
|
||||
static void ulog_test(CuTest *tc)
|
||||
{
|
||||
uint8_t data[10];
|
||||
|
||||
ulog_write_str(LOG_PROT, "Please key..\n");
|
||||
|
||||
#if 0
|
||||
int len = ulog_read_bytes(LOG_PROT, data, sizeof(data) - 1);
|
||||
if (len > 0)
|
||||
{
|
||||
data[len] = 0;
|
||||
printf("%s\n", data);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
CuSuite *ulog_test_suite(void)
|
||||
{
|
||||
CuSuite *suite = CuSuiteNew();
|
||||
|
||||
SUITE_ADD_TEST(suite, ulog_test);
|
||||
|
||||
return suite;
|
||||
}
|
||||
@@ -1,24 +1,48 @@
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
void malloc_test(void)
|
||||
#include <CuTest.h>
|
||||
#include <stdio.h>
|
||||
#include <u_types.h>
|
||||
static uint8_t *mem[1000];
|
||||
static void malloc_test(CuTest *cu)
|
||||
{
|
||||
#define TEST_MEM_SIZE 1024 * 1024 * 4
|
||||
#define TEST_MEM_SIZE 1024 * 1024 * 1
|
||||
void *mem2 = malloc(TEST_MEM_SIZE);
|
||||
assert(mem2);
|
||||
printf("alloc mem 0x%lx\n", mem2);
|
||||
|
||||
CuAssert(cu, "malloc failed\n", mem2 != NULL);
|
||||
memset(mem2, 0, TEST_MEM_SIZE);
|
||||
free(mem2);
|
||||
printf("free mem 0x%lx\n", mem2);
|
||||
#undef TEST_MEM_SIZE
|
||||
|
||||
void *mem[1000];
|
||||
for (int i = 0; i < 1000; i++)
|
||||
{
|
||||
mem[i] = malloc(4096);
|
||||
assert(mem[i]);
|
||||
memset(mem, 0, 4096);
|
||||
CuAssert(cu, "malloc failed\n", mem[i] != NULL);
|
||||
// memset(mem[i], 0, 4096);
|
||||
for (int j = 0; j < 4096; j++)
|
||||
{
|
||||
mem[i][j] = j % 256;
|
||||
}
|
||||
// printf("alloc %d 0x%lx\n", i, mem[i]);
|
||||
}
|
||||
for (int i = 0; i < 1000; i++)
|
||||
{
|
||||
for (int j = 0; j < 4096; j++)
|
||||
{
|
||||
CuAssert(cu, "mem failed.\n", mem[i][j] == j % 256);
|
||||
}
|
||||
free(mem[i]);
|
||||
// printf("free %d 0x%lx\n", i, mem[i]);
|
||||
}
|
||||
}
|
||||
CuSuite *malloc_test_suite(void)
|
||||
{
|
||||
CuSuite *suite = CuSuiteNew();
|
||||
|
||||
SUITE_ADD_TEST(suite, malloc_test);
|
||||
|
||||
return suite;
|
||||
}
|
||||
|
||||
@@ -11,16 +11,18 @@
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#define DEBUG_IPC_CALL 1
|
||||
#include <CuTest.h>
|
||||
#include <pthread.h>
|
||||
|
||||
static umword_t th1_hd = 0;
|
||||
static umword_t th2_hd = 0;
|
||||
#define STACK_SIZE PAGE_SIZE
|
||||
|
||||
static char msg_buf0[MSG_BUG_LEN];
|
||||
static char msg_buf1[MSG_BUG_LEN];
|
||||
#define STACK_SIZE 1024
|
||||
static __attribute__((aligned(8))) uint8_t stack0[STACK_SIZE];
|
||||
static __attribute__((aligned(8))) uint8_t stack1[STACK_SIZE];
|
||||
static pthread_t th1;
|
||||
static pthread_t th2;
|
||||
|
||||
static __attribute__((aligned(PAGE_SIZE))) char msg_buf0[MSG_BUG_LEN];
|
||||
static __attribute__((aligned(PAGE_SIZE))) char msg_buf1[MSG_BUG_LEN];
|
||||
static __attribute__((aligned(PAGE_SIZE))) uint8_t stack0[STACK_SIZE * 2];
|
||||
static __attribute__((aligned(PAGE_SIZE))) uint8_t stack1[STACK_SIZE * 2];
|
||||
|
||||
static void hard_sleep(void)
|
||||
{
|
||||
@@ -28,74 +30,64 @@ static void hard_sleep(void)
|
||||
for (volatile int i; i < 10000000; i++)
|
||||
;
|
||||
}
|
||||
static void thread_test_func(void)
|
||||
#define TEST_STR "I am th2.\n"
|
||||
static void *thread_test_func(void *arg)
|
||||
{
|
||||
char *buf;
|
||||
umword_t len;
|
||||
ipc_msg_t *ipc_msg;
|
||||
obj_handler_t log_hd = handler_alloc();
|
||||
thread_msg_buf_get(th1_hd, (umword_t *)(&buf), NULL);
|
||||
thread_msg_buf_get(-1, (umword_t *)(&buf), NULL);
|
||||
ipc_msg = (ipc_msg_t *)buf;
|
||||
ipc_msg->map_buf[0] = vpage_create_raw3(0, 0, log_hd).raw;
|
||||
thread_ipc_wait(ipc_timeout_create2(0, 0), NULL, -1);
|
||||
printf("srv recv:%s", buf);
|
||||
assert(strcmp(TEST_STR, buf) == 0);
|
||||
ulog_write_str(log_hd, "map test success.\n");
|
||||
hard_sleep();
|
||||
thread_ipc_reply(msg_tag_init4(0, ROUND_UP(strlen(buf), WORD_BYTES), 0, 0), ipc_timeout_create2(0, 0));
|
||||
printf("thread_test_func.\n");
|
||||
handler_free(log_hd);
|
||||
handler_free(th1_hd);
|
||||
task_unmap(TASK_PROT, vpage_create_raw3(KOBJ_DELETE_RIGHT, 0, th1_hd));
|
||||
printf("Error\n");
|
||||
return NULL;
|
||||
}
|
||||
static void thread_test_func2(void)
|
||||
static void *thread_test_func2(void *arg)
|
||||
{
|
||||
char *buf;
|
||||
umword_t len;
|
||||
ipc_msg_t *ipc_msg;
|
||||
|
||||
thread_msg_buf_get(th2_hd, (umword_t *)(&buf), NULL);
|
||||
thread_msg_buf_get(-1, (umword_t *)(&buf), NULL);
|
||||
ipc_msg = (ipc_msg_t *)buf;
|
||||
strcpy((char *)(ipc_msg->msg_buf), "I am th2.\n");
|
||||
strcpy((char *)(ipc_msg->msg_buf), TEST_STR);
|
||||
ipc_msg->map_buf[0] = vpage_create_raw3(KOBJ_DELETE_RIGHT, VPAGE_FLAGS_MAP, LOG_PROT).raw;
|
||||
thread_ipc_call(msg_tag_init4(0, ROUND_UP(strlen((char *)(ipc_msg->msg_buf)), WORD_BYTES), 1, 0), th1_hd, ipc_timeout_create2(0, 0));
|
||||
thread_ipc_call(msg_tag_init4(0, ROUND_UP(strlen((char *)(ipc_msg->msg_buf)), WORD_BYTES), 1, 0),
|
||||
pthread_hd_get(th1), ipc_timeout_create2(0, 0));
|
||||
printf("th2:%s", buf);
|
||||
assert(strcmp(TEST_STR, buf) == 0);
|
||||
printf("thread_test_func2.\n");
|
||||
handler_free(th1_hd);
|
||||
task_unmap(TASK_PROT, vpage_create_raw3(KOBJ_DELETE_RIGHT, 0, th2_hd));
|
||||
printf("Error\n");
|
||||
return NULL;
|
||||
}
|
||||
/**
|
||||
* @brief 启动两个线程并进行ipc测试
|
||||
*
|
||||
*/
|
||||
void map_test(void)
|
||||
static void map_test(CuTest *test)
|
||||
{
|
||||
th1_hd = handler_alloc();
|
||||
assert(th1_hd != HANDLER_INVALID);
|
||||
th2_hd = handler_alloc();
|
||||
assert(th2_hd != HANDLER_INVALID);
|
||||
int ret;
|
||||
|
||||
msg_tag_t tag;
|
||||
tag = factory_create_thread(FACTORY_PROT, vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, th1_hd));
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
tag = thread_msg_buf_set(th1_hd, msg_buf0);
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
tag = thread_exec_regs(th1_hd, (umword_t)thread_test_func, (umword_t)stack0 + STACK_SIZE, TASK_RAM_BASE(), 0);
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
tag = thread_bind_task(th1_hd, TASK_THIS);
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
tag = thread_run(th1_hd, 2);
|
||||
ret = pthread_create(&th1, NULL, thread_test_func, NULL);
|
||||
CuAssert(test, "pthread create error.\n", ret == 0);
|
||||
pthread_create(&th2, NULL, thread_test_func2, NULL);
|
||||
CuAssert(test, "pthread create error.\n", ret == 0);
|
||||
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
tag = factory_create_thread(FACTORY_PROT, vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, th2_hd));
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
tag = thread_msg_buf_set(th2_hd, msg_buf1);
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
tag = thread_exec_regs(th2_hd, (umword_t)thread_test_func2, (umword_t)stack1 + STACK_SIZE, TASK_RAM_BASE(), 0);
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
tag = thread_bind_task(th2_hd, TASK_THIS);
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
tag = thread_run(th2_hd, 2);
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
pthread_join(th1, NULL);
|
||||
pthread_join(th2, NULL);
|
||||
}
|
||||
CuSuite *map_test_suite(void)
|
||||
{
|
||||
CuSuite *suite = CuSuiteNew();
|
||||
|
||||
SUITE_ADD_TEST(suite, map_test);
|
||||
|
||||
return suite;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include "u_types.h"
|
||||
#include <stdio.h>
|
||||
void printf_test(void)
|
||||
|
||||
#include <CuTest.h>
|
||||
static void printf_test(CuTest *tc)
|
||||
{
|
||||
printf("print test0.\n");
|
||||
printf("print test1.\n");
|
||||
@@ -17,3 +19,12 @@ void printf_test(void)
|
||||
printf("%c %d %lf\n", 'a', 1234, 1.1);
|
||||
}
|
||||
}
|
||||
|
||||
CuSuite *printf_test_suite(void)
|
||||
{
|
||||
CuSuite *suite = CuSuiteNew();
|
||||
|
||||
SUITE_ADD_TEST(suite, printf_test);
|
||||
|
||||
return suite;
|
||||
}
|
||||
|
||||
39
mkrtos_user/server/init/src/test/pthread_base_test.c
Normal file
39
mkrtos_user/server/init/src/test/pthread_base_test.c
Normal file
@@ -0,0 +1,39 @@
|
||||
#include "test.h"
|
||||
#include "u_factory.h"
|
||||
#include "u_hd_man.h"
|
||||
#include "u_ipc.h"
|
||||
#include "u_log.h"
|
||||
#include "u_mm.h"
|
||||
#include "u_prot.h"
|
||||
#include "u_sleep.h"
|
||||
#include "u_task.h"
|
||||
#include "u_thread.h"
|
||||
#include <CuTest.h>
|
||||
#include <assert.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#define TEST_THREAD_NUM 50
|
||||
|
||||
static pthread_t th_test;
|
||||
|
||||
static void *thread_test_func(void *arg)
|
||||
{
|
||||
printf(".\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void thread_base_test(CuTest *cu)
|
||||
{
|
||||
CuAssert(cu, "pthread create error \n",
|
||||
pthread_create(&th_test, NULL, thread_test_func, NULL) == 0);
|
||||
CuAssert(cu, "pthread join error\n",
|
||||
pthread_join(th_test, NULL) == 0);
|
||||
}
|
||||
CuSuite *pthread_base_test_suite(void)
|
||||
{
|
||||
CuSuite *suite = CuSuiteNew();
|
||||
|
||||
SUITE_ADD_TEST(suite, thread_base_test);
|
||||
|
||||
return suite;
|
||||
}
|
||||
@@ -5,12 +5,14 @@
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <CuTest.h>
|
||||
|
||||
static pthread_cond_t cond;
|
||||
static pthread_mutex_t mutex;
|
||||
static int cond_value;
|
||||
static int quit;
|
||||
|
||||
void *thread_signal(void *arg)
|
||||
static void *thread_signal(void *arg)
|
||||
{
|
||||
while (!quit)
|
||||
{
|
||||
@@ -23,7 +25,7 @@ void *thread_signal(void *arg)
|
||||
}
|
||||
}
|
||||
|
||||
void *thread_wait(void *arg)
|
||||
static void *thread_wait(void *arg)
|
||||
{
|
||||
while (!quit)
|
||||
{
|
||||
@@ -41,9 +43,9 @@ void *thread_wait(void *arg)
|
||||
}
|
||||
}
|
||||
|
||||
pthread_t tid1;
|
||||
pthread_t tid2;
|
||||
int pthread_cond_lock_test(void)
|
||||
static pthread_t tid1;
|
||||
static pthread_t tid2;
|
||||
static void pthread_cond_lock_test(CuTest *cu)
|
||||
{
|
||||
|
||||
pthread_cond_init(&cond, NULL);
|
||||
@@ -61,5 +63,12 @@ int pthread_cond_lock_test(void)
|
||||
pthread_cond_destroy(&cond);
|
||||
pthread_mutex_destroy(&mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
CuSuite *pthread_cond_lock_test_suite(void)
|
||||
{
|
||||
CuSuite *suite = CuSuiteNew();
|
||||
|
||||
SUITE_ADD_TEST(suite, pthread_cond_lock_test);
|
||||
|
||||
return suite;
|
||||
}
|
||||
|
||||
@@ -14,15 +14,15 @@
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define TEST_CNT 50
|
||||
#include <CuTest.h>
|
||||
#define TEST_CNT 10
|
||||
static pthread_mutex_t lock;
|
||||
static pthread_t pth;
|
||||
static pthread_t pth2;
|
||||
|
||||
#define STACK_SIZE 4096
|
||||
static __attribute__((aligned(8))) uint8_t stack0[STACK_SIZE];
|
||||
static __attribute__((aligned(8))) uint8_t stack1[STACK_SIZE];
|
||||
#define STACK_SIZE PAGE_SIZE
|
||||
static __attribute__((aligned(PAGE_SIZE))) uint8_t stack0[STACK_SIZE * 2];
|
||||
static __attribute__((aligned(PAGE_SIZE))) uint8_t stack1[STACK_SIZE * 2];
|
||||
|
||||
static void hard_sleep(void)
|
||||
{
|
||||
@@ -31,6 +31,8 @@ static void hard_sleep(void)
|
||||
}
|
||||
static void *thread_test_func(void *arg)
|
||||
{
|
||||
usleep(50000);
|
||||
|
||||
int i = TEST_CNT;
|
||||
while (i--)
|
||||
{
|
||||
@@ -43,6 +45,7 @@ static void *thread_test_func(void *arg)
|
||||
}
|
||||
static void *thread_test_func2(void *arg)
|
||||
{
|
||||
|
||||
int i = TEST_CNT;
|
||||
while (i--)
|
||||
{
|
||||
@@ -57,17 +60,25 @@ static void *thread_test_func2(void *arg)
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void pthread_lock_test(void)
|
||||
static void pthread_lock_test(CuTest *cu)
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
|
||||
pthread_mutex_init(&lock, NULL);
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setstack(&attr, stack0, STACK_SIZE);
|
||||
pthread_create(&pth, &attr, thread_test_func, NULL);
|
||||
CuAssert(cu, "pthread create error.\n", pthread_create(&pth, &attr, thread_test_func, NULL) == 0);
|
||||
pthread_attr_setstack(&attr, stack1, STACK_SIZE);
|
||||
pthread_create(&pth2, &attr, thread_test_func2, NULL);
|
||||
CuAssert(cu, "pthread create error.\n", pthread_create(&pth2, &attr, thread_test_func2, NULL) == 0);
|
||||
pthread_join(pth, NULL);
|
||||
pthread_join(pth2, NULL);
|
||||
printf("%s:%d test ok.\n", __func__, __LINE__);
|
||||
}
|
||||
CuSuite *pthread_lock_test_suite(void)
|
||||
{
|
||||
CuSuite *suite = CuSuiteNew();
|
||||
|
||||
SUITE_ADD_TEST(suite, pthread_lock_test);
|
||||
|
||||
return suite;
|
||||
}
|
||||
|
||||
@@ -3,9 +3,13 @@
|
||||
#include "u_sema.h"
|
||||
#include "u_hd_man.h"
|
||||
#include "u_task.h"
|
||||
#include <u_sleep.h>
|
||||
#include <assert.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <CuTest.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int u_sema_test(void)
|
||||
{
|
||||
msg_tag_t tag;
|
||||
@@ -22,55 +26,86 @@ int u_sema_test(void)
|
||||
handler_free_umap(sema_hd);
|
||||
return 0;
|
||||
}
|
||||
#include <u_sleep.h>
|
||||
static pthread_t pth1;
|
||||
static pthread_t pth2;
|
||||
static pthread_t pth3;
|
||||
static obj_handler_t sema_hd2;
|
||||
|
||||
#define TEST_CN 10
|
||||
static void *thread_th1(void *arg)
|
||||
{
|
||||
int j = 0;
|
||||
while (1)
|
||||
{
|
||||
printf("sema_up start\n");
|
||||
u_sema_up(sema_hd2);
|
||||
u_sleep_ms(100);
|
||||
printf("sema_up end\n");
|
||||
if (j == TEST_CN * 2 + 2)
|
||||
{
|
||||
break;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
printf("%s sema up exit.\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
static void *thread_th2(void *arg)
|
||||
{
|
||||
int j = 0;
|
||||
while (1)
|
||||
{
|
||||
printf("sema_down start\n");
|
||||
u_sema_down(sema_hd2);
|
||||
u_sleep_ms(50);
|
||||
printf("sema_down end\n");
|
||||
if (j == TEST_CN)
|
||||
{
|
||||
break;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
printf("%s sema down exit.\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
static void *thread_th3(void *arg)
|
||||
{
|
||||
int j = 0;
|
||||
while (1)
|
||||
{
|
||||
printf("sema_down2 start\n");
|
||||
u_sema_down(sema_hd2);
|
||||
u_sleep_ms(50);
|
||||
printf("sema_down2 end\n");
|
||||
if (j == TEST_CN)
|
||||
{
|
||||
break;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
printf("%s sema down exit.\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
int u_sema_test2(void)
|
||||
static void u_sema_test2(CuTest *tc)
|
||||
{
|
||||
msg_tag_t tag;
|
||||
|
||||
sema_hd2 = handler_alloc();
|
||||
assert(sema_hd2 != HANDLER_INVALID);
|
||||
CuAssert(tc, "hd alloc fail.\n", sema_hd2 != HANDLER_INVALID);
|
||||
tag = facotry_create_sema(FACTORY_PROT,
|
||||
vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, sema_hd2), 0, 1);
|
||||
assert(msg_tag_get_val(tag) >= 0);
|
||||
CuAssert(tc, "hd alloc fail.\n", msg_tag_get_val(tag) >= 0);
|
||||
pthread_create(&pth1, NULL, thread_th1, NULL);
|
||||
pthread_create(&pth1, NULL, thread_th2, NULL);
|
||||
pthread_create(&pth2, NULL, thread_th2, NULL);
|
||||
pthread_create(&pth3, NULL, thread_th3, NULL);
|
||||
pthread_join(pth1, NULL);
|
||||
pthread_join(pth2, NULL);
|
||||
pthread_join(pth3, NULL);
|
||||
}
|
||||
CuSuite *sema_test_suite(void)
|
||||
{
|
||||
CuSuite *suite = CuSuiteNew();
|
||||
|
||||
SUITE_ADD_TEST(suite, u_sema_test2);
|
||||
|
||||
return suite;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,20 @@
|
||||
#pragma once
|
||||
#include <CuTest.h>
|
||||
|
||||
CuSuite* printf_test_suite(void);
|
||||
CuSuite *ulog_test_suite(void);
|
||||
CuSuite *sema_test_suite(void);
|
||||
CuSuite *vmm_test_suite(void);
|
||||
|
||||
CuSuite *malloc_test_suite(void);
|
||||
CuSuite *pthread_press_test_suite(void);
|
||||
CuSuite *pthread_cond_lock_test_suite(void);
|
||||
CuSuite *pthread_lock_test_suite(void);
|
||||
CuSuite *map_test_suite(void);
|
||||
CuSuite *pthread_base_test_suite(void);
|
||||
CuSuite *thread_base_test_suite(void);
|
||||
CuSuite *ipc_test_suite(void);
|
||||
void test_main(void);
|
||||
|
||||
void mm_test(void);
|
||||
void ulog_test(void);
|
||||
@@ -12,7 +28,6 @@ void thread_exit_test(void);
|
||||
void map_test(void);
|
||||
void ipc_obj_test(void);
|
||||
void irq_test(void);
|
||||
void thread_press_test(void);
|
||||
void kobj_create_press_test(void);
|
||||
void sleep_tick(int tick);
|
||||
void pthread_lock_test(void);
|
||||
|
||||
33
mkrtos_user/server/init/src/test/test_main.c
Normal file
33
mkrtos_user/server/init/src/test/test_main.c
Normal file
@@ -0,0 +1,33 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "CuTest.h"
|
||||
#include "test.h"
|
||||
static void RunAllTests(void)
|
||||
{
|
||||
CuString *output = CuStringNew();
|
||||
CuSuite* suite = CuSuiteNew();
|
||||
|
||||
CuSuiteAddSuite(suite, ipc_test_suite());
|
||||
CuSuiteAddSuite(suite, ulog_test_suite());
|
||||
CuSuiteAddSuite(suite, printf_test_suite());
|
||||
CuSuiteAddSuite(suite, vmm_test_suite());
|
||||
CuSuiteAddSuite(suite, malloc_test_suite());
|
||||
CuSuiteAddSuite(suite, map_test_suite());
|
||||
CuSuiteAddSuite(suite, thread_base_test_suite());
|
||||
|
||||
CuSuiteAddSuite(suite, sema_test_suite());
|
||||
CuSuiteAddSuite(suite, pthread_base_test_suite());
|
||||
CuSuiteAddSuite(suite, pthread_press_test_suite());
|
||||
CuSuiteAddSuite(suite, pthread_lock_test_suite());
|
||||
CuSuiteAddSuite(suite, pthread_cond_lock_test_suite());
|
||||
|
||||
CuSuiteRun(suite);
|
||||
CuSuiteSummary(suite, output);
|
||||
CuSuiteDetails(suite, output);
|
||||
printf("%s\n", output->buffer);
|
||||
}
|
||||
|
||||
void test_main(void)
|
||||
{
|
||||
RunAllTests();
|
||||
}
|
||||
72
mkrtos_user/server/init/src/test/thread_base_test.c
Normal file
72
mkrtos_user/server/init/src/test/thread_base_test.c
Normal file
@@ -0,0 +1,72 @@
|
||||
|
||||
|
||||
#include "test.h"
|
||||
#include "u_factory.h"
|
||||
#include "u_hd_man.h"
|
||||
#include "u_ipc.h"
|
||||
#include "u_log.h"
|
||||
#include "u_mm.h"
|
||||
#include "u_prot.h"
|
||||
#include "u_sleep.h"
|
||||
#include "u_task.h"
|
||||
#include "u_thread.h"
|
||||
#include <CuTest.h>
|
||||
#include <assert.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <u_thread_util.h>
|
||||
#define TEST_THREAD_NUM 50
|
||||
#define STACK_SIZE (4096 * 2)
|
||||
static obj_handler_t th_hd;
|
||||
static __attribute__((aligned(PAGE_SIZE))) uint8_t stack0[STACK_SIZE];
|
||||
|
||||
#define HAND_SLEEP_DELAY 1000000000
|
||||
static void thread_hard_sleep(volatile int i)
|
||||
{
|
||||
volatile int j;
|
||||
|
||||
for (j = 0; j < i; j++)
|
||||
;
|
||||
}
|
||||
|
||||
static void thread_test_func(void)
|
||||
{
|
||||
while (1) {
|
||||
u_sleep_ms(100000000);
|
||||
}
|
||||
}
|
||||
static void thread_test_func_hard_sleep(void)
|
||||
{
|
||||
while (1) {
|
||||
thread_hard_sleep(HAND_SLEEP_DELAY);
|
||||
}
|
||||
}
|
||||
|
||||
static void thread_base_test(CuTest *cu)
|
||||
{
|
||||
int ret;
|
||||
|
||||
for (int i = 0; i < CONFIG_CPU; i++) {
|
||||
ret = u_thread_create(&th_hd, stack0 + STACK_SIZE, NULL, thread_test_func);
|
||||
CuAssert(cu, "u_thread_create failed.\n", ret >= 0);
|
||||
u_thread_run_cpu(th_hd, 2, i);
|
||||
u_sleep_ms(100);
|
||||
u_thread_del(th_hd);
|
||||
}
|
||||
|
||||
for (int i = 0; i < CONFIG_CPU; i++) {
|
||||
ret = u_thread_create(&th_hd, stack0 + STACK_SIZE, NULL, thread_test_func);
|
||||
CuAssert(cu, "u_thread_create failed.\n", ret >= 0);
|
||||
u_thread_run_cpu(th_hd, 2, i);
|
||||
thread_hard_sleep(HAND_SLEEP_DELAY/3);
|
||||
u_thread_del(th_hd);
|
||||
}
|
||||
}
|
||||
CuSuite *thread_base_test_suite(void)
|
||||
{
|
||||
CuSuite *suite = CuSuiteNew();
|
||||
|
||||
SUITE_ADD_TEST(suite, thread_base_test);
|
||||
|
||||
return suite;
|
||||
}
|
||||
@@ -10,35 +10,36 @@
|
||||
#include <stdio.h>
|
||||
#include "test.h"
|
||||
#include "u_sleep.h"
|
||||
static umword_t th1_hd = 0;
|
||||
static int i = 100;
|
||||
#include <pthread.h>
|
||||
#include <CuTest.h>
|
||||
#define TEST_THREAD_NUM 50
|
||||
|
||||
#define STACK_SIZE 1024
|
||||
static __attribute__((aligned(8))) uint8_t stack0[STACK_SIZE];
|
||||
static pthread_t th_array[TEST_THREAD_NUM];
|
||||
|
||||
static void thread_test_func(void)
|
||||
static void *thread_test_func(void *arg)
|
||||
{
|
||||
ulog_write_str(LOG_PROT, ".");
|
||||
handler_free_umap(th1_hd);
|
||||
printf("Error\n");
|
||||
printf(".\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void thread_press_test(void)
|
||||
static void thread_press_test(CuTest *cu)
|
||||
{
|
||||
while (i--)
|
||||
for (int i = 0; i < TEST_THREAD_NUM; i++)
|
||||
{
|
||||
th1_hd = handler_alloc();
|
||||
assert(th1_hd != HANDLER_INVALID);
|
||||
msg_tag_t tag;
|
||||
|
||||
tag = factory_create_thread(FACTORY_PROT, vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, th1_hd));
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
tag = thread_exec_regs(th1_hd, (umword_t)thread_test_func, (umword_t)stack0 + STACK_SIZE, TASK_RAM_BASE(), 0);
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
tag = thread_bind_task(th1_hd, TASK_THIS);
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
tag = thread_run(th1_hd, 2);
|
||||
ulog_write_str(LOG_PROT, "\n");
|
||||
u_sleep_ms(10);
|
||||
CuAssert(cu, "pthread create error \n",
|
||||
pthread_create(&th_array[i], NULL, thread_test_func, NULL) == 0);
|
||||
}
|
||||
for (int i = 0; i < TEST_THREAD_NUM; i++)
|
||||
{
|
||||
CuAssert(cu, "pthread join error\n",
|
||||
pthread_join(th_array[i], NULL) == 0);
|
||||
}
|
||||
}
|
||||
CuSuite *pthread_press_test_suite(void)
|
||||
{
|
||||
CuSuite *suite = CuSuiteNew();
|
||||
|
||||
SUITE_ADD_TEST(suite, thread_press_test);
|
||||
|
||||
return suite;
|
||||
}
|
||||
|
||||
82
mkrtos_user/server/init/src/test/vmam_test.c
Normal file
82
mkrtos_user/server/init/src/test/vmam_test.c
Normal file
@@ -0,0 +1,82 @@
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <CuTest.h>
|
||||
#include <u_factory.h>
|
||||
#include <u_hd_man.h>
|
||||
#include <u_vmam.h>
|
||||
#include <stdio.h>
|
||||
static void vmm_large_block_test(CuTest *cu)
|
||||
{
|
||||
addr_t addr;
|
||||
msg_tag_t tag;
|
||||
#define TEST_CN 100
|
||||
#define TEST_MM_SIZE (1024 * 1024 * 1)
|
||||
for (int i = 0; i < TEST_CN; i++)
|
||||
{
|
||||
tag = u_vmam_alloc(VMA_PROT, vma_addr_create(VPAGE_PROT_RWX, 0, 0), TEST_MM_SIZE, 0, &addr);
|
||||
CuAssert(cu, "vmam alloc faile.\n", msg_tag_get_val(tag) >= 0);
|
||||
memset((void *)addr, 0, TEST_MM_SIZE);
|
||||
u_vmam_free(VMA_PROT, addr, TEST_MM_SIZE);
|
||||
}
|
||||
#undef TEST_MM_SIZE
|
||||
#undef TEST_CN
|
||||
}
|
||||
static void vmm_small_block_test(CuTest *cu)
|
||||
{
|
||||
addr_t addr;
|
||||
msg_tag_t tag;
|
||||
#define TEST_CN 100
|
||||
#define TEST_MM_SIZE (PAGE_SIZE)
|
||||
for (int i = 0; i < TEST_CN; i++)
|
||||
{
|
||||
tag = u_vmam_alloc(VMA_PROT, vma_addr_create(VPAGE_PROT_RWX, 0, 0), TEST_MM_SIZE, 0, &addr);
|
||||
CuAssert(cu, "vmam alloc faile.\n", msg_tag_get_val(tag) >= 0);
|
||||
memset((void *)addr, 0, TEST_MM_SIZE);
|
||||
u_vmam_free(VMA_PROT, addr, TEST_MM_SIZE);
|
||||
}
|
||||
#undef TEST_MM_SIZE
|
||||
#undef TEST_CN
|
||||
}
|
||||
#define TEST_MEM_CN 100
|
||||
static void *test_main[TEST_MEM_CN];
|
||||
static void vmm_press_block_test(CuTest *cu)
|
||||
{
|
||||
addr_t addr;
|
||||
msg_tag_t tag;
|
||||
#define TEST_MM_SIZE (PAGE_SIZE)
|
||||
for (int i = 0; i < TEST_MEM_CN; i++)
|
||||
{
|
||||
tag = u_vmam_alloc(VMA_PROT, vma_addr_create(VPAGE_PROT_RWX, 0, 0), TEST_MM_SIZE, 0, &addr);
|
||||
CuAssert(cu, "vmam alloc faile.\n", msg_tag_get_val(tag) >= 0);
|
||||
memset((void *)addr, 0x55, TEST_MM_SIZE);
|
||||
// printf("alloc umem:0x%lx\n", addr);
|
||||
test_main[i] = (void *)addr;
|
||||
}
|
||||
for (int i = 0; i < TEST_MEM_CN; i++)
|
||||
{
|
||||
for (int j = 0; j < TEST_MM_SIZE; j++)
|
||||
{
|
||||
uint8_t *tmp_mm = test_main[i];
|
||||
if (tmp_mm[j] != 0x55)
|
||||
{
|
||||
printf("mem test fail. i:%d j:%d\n", i, j);
|
||||
}
|
||||
assert(tmp_mm[j] == 0x55);
|
||||
}
|
||||
u_vmam_free(VMA_PROT, (addr_t)(test_main[i]), TEST_MM_SIZE);
|
||||
}
|
||||
|
||||
#undef TEST_MM_SIZE
|
||||
#undef TEST_MEM_CN
|
||||
}
|
||||
CuSuite *vmm_test_suite(void)
|
||||
{
|
||||
CuSuite *suite = CuSuiteNew();
|
||||
|
||||
SUITE_ADD_TEST(suite, vmm_large_block_test);
|
||||
SUITE_ADD_TEST(suite, vmm_small_block_test);
|
||||
SUITE_ADD_TEST(suite, vmm_press_block_test);
|
||||
|
||||
return suite;
|
||||
}
|
||||
@@ -10,12 +10,10 @@ int main(int argc, char *args[])
|
||||
{
|
||||
task_set_obj_name(TASK_THIS, TASK_THIS, "tk_sh");
|
||||
task_set_obj_name(TASK_THIS, THREAD_MAIN, "th_sh");
|
||||
// u_sleep_ms(100);
|
||||
for (int i = 0; i < argc; i++)
|
||||
{
|
||||
printf("args[%d]:%s\n ", i, args[i]);
|
||||
printf("args[%d]:%s\n", i, args[i]);
|
||||
}
|
||||
// pm_run_app("lcd_drv", 0);
|
||||
userShellInit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user