网络服务支持
This commit is contained in:
@@ -3,6 +3,8 @@
|
||||
#include "thread.h"
|
||||
#include "futex.h"
|
||||
#include "thread_knl.h"
|
||||
#include "sleep.h"
|
||||
|
||||
static umword_t sys_tick_cnt;
|
||||
|
||||
umword_t sys_tick_cnt_get(void)
|
||||
@@ -19,7 +21,10 @@ void SysTick_Handler(void)
|
||||
atomic_inc(&thread_get_current()->time_count);
|
||||
}
|
||||
sys_tick_cnt++;
|
||||
#if 0
|
||||
thread_timeout_check(1);
|
||||
#endif
|
||||
thread_check_timeout();
|
||||
futex_timeout_times_tick();
|
||||
cpulock_set(status);
|
||||
thread_calc_cpu_usage();
|
||||
|
||||
@@ -32,6 +32,7 @@ typedef struct task
|
||||
void *nofity_point; //!< commint point func.
|
||||
addr_t nofity_stack; //!< nofity_point_stack.
|
||||
mutex_t nofity_lock;
|
||||
sema_t notify_sema; //!< sema
|
||||
addr_t nofity_msg_buf; //!<
|
||||
umword_t *nofity_map_buf;
|
||||
umword_t *nofity_bitmap; //!<
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
static slab_t *sema_slab;
|
||||
#endif
|
||||
|
||||
enum SEMA_OP {
|
||||
enum SEMA_OP
|
||||
{
|
||||
SEMA_UP,
|
||||
SEMA_DOWN,
|
||||
};
|
||||
@@ -28,7 +29,8 @@ static void sema_mem_init(void)
|
||||
#endif
|
||||
}
|
||||
INIT_KOBJ_MEM(sema_mem_init);
|
||||
typedef struct sema_wait_item {
|
||||
typedef struct sema_wait_item
|
||||
{
|
||||
slist_head_t node;
|
||||
thread_t *thread;
|
||||
} sema_wait_item_t;
|
||||
@@ -45,29 +47,47 @@ void sema_up(sema_t *obj)
|
||||
umword_t status;
|
||||
|
||||
status = spinlock_lock(&obj->lock);
|
||||
if (slist_is_empty(&obj->suspend_head)) {
|
||||
if (obj->cnt < obj->max_cnt) {
|
||||
if (slist_is_empty(&obj->suspend_head))
|
||||
{
|
||||
if (obj->cnt < obj->max_cnt)
|
||||
{
|
||||
obj->cnt++;
|
||||
}
|
||||
// printk("up0 sema cnt:%d max:%d.\n", obj->cnt, obj->max_cnt);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
slist_head_t *first_wait_node;
|
||||
sema_wait_item_t *first_wait;
|
||||
|
||||
first_wait_node = slist_first(&obj->suspend_head);
|
||||
first_wait = container_of(first_wait_node, sema_wait_item_t, node);
|
||||
slist_del(first_wait_node);
|
||||
if (ref_counter_dec_and_release(&first_wait->thread->ref, &first_wait->thread->kobj) != 1) {
|
||||
// thread_ready_remote(first_wait->thread, FALSE);
|
||||
thread_sleep_del_and_wakeup(first_wait->thread);
|
||||
// assert(first_wait->thread->status == THREAD_SUSPEND);
|
||||
if (thread_get_status(first_wait->thread) == THREAD_SUSPEND)
|
||||
{
|
||||
slist_del(first_wait_node);
|
||||
if (ref_counter_dec_and_release(&first_wait->thread->ref, &first_wait->thread->kobj) != 1)
|
||||
{
|
||||
// thread_ready_remote(first_wait->thread, FALSE);
|
||||
thread_sleep_del_and_wakeup(first_wait->thread);
|
||||
}
|
||||
}
|
||||
if (obj->cnt < obj->max_cnt) {
|
||||
else
|
||||
{
|
||||
// 超时退出,但是切出来的时候切到了唤醒线程中,所以这里不是suspend状态。
|
||||
thread_sleep_del(first_wait->thread);
|
||||
}
|
||||
if (obj->cnt < obj->max_cnt)
|
||||
{
|
||||
obj->cnt++;
|
||||
}
|
||||
// printk("up1 sema cnt:%d max:%d.\n", obj->cnt, obj->max_cnt);
|
||||
}
|
||||
spinlock_set(&obj->lock, status);
|
||||
preemption();
|
||||
if (cpulock_get_status())
|
||||
{
|
||||
preemption();
|
||||
}
|
||||
}
|
||||
umword_t sema_down(sema_t *obj, umword_t ticks)
|
||||
{
|
||||
@@ -79,25 +99,31 @@ umword_t sema_down(sema_t *obj, umword_t ticks)
|
||||
|
||||
again:
|
||||
status = spinlock_lock(&obj->lock);
|
||||
if (obj->cnt == 0) {
|
||||
if (obj->cnt == 0)
|
||||
{
|
||||
sema_wait_item_init(&wait_item, th);
|
||||
ref_counter_inc(&th->ref);
|
||||
slist_add_append(&obj->suspend_head, &wait_item.node);
|
||||
remain_sleep = thread_sleep(ticks);
|
||||
if (remain_sleep == 0 && ticks != 0) {
|
||||
if (remain_sleep == 0 && ticks != 0)
|
||||
{
|
||||
// 超时退出的,直接从列表中删除
|
||||
assert(slist_in_list(&wait_item.node));
|
||||
slist_del(&wait_item.node);
|
||||
ref_counter_dec(&th->ref);
|
||||
}
|
||||
if (!(remain_sleep == 0 && ticks != 0)) {
|
||||
else
|
||||
{
|
||||
spinlock_set(&obj->lock, status);
|
||||
if (cpulock_get_status()) {
|
||||
if (cpulock_get_status())
|
||||
{
|
||||
preemption();
|
||||
}
|
||||
goto again;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(obj->cnt > 0);
|
||||
obj->cnt--;
|
||||
// printk("down sema cnt:%d max:%d.\n", obj->cnt, obj->max_cnt);
|
||||
@@ -113,16 +139,21 @@ static void sema_syscall(kobject_t *kobj, syscall_prot_t sys_p,
|
||||
msg_tag_t tag = msg_tag_init4(0, 0, 0, -EINVAL);
|
||||
task_t *task = thread_get_current_task();
|
||||
|
||||
if (sys_p.prot != SEMA_PROT) {
|
||||
if (sys_p.prot != SEMA_PROT)
|
||||
{
|
||||
f->regs[0] = msg_tag_init4(0, 0, 0, -EPROTO).raw;
|
||||
return;
|
||||
}
|
||||
switch (sys_p.op) {
|
||||
case SEMA_UP: {
|
||||
switch (sys_p.op)
|
||||
{
|
||||
case SEMA_UP:
|
||||
{
|
||||
sema_up(sema);
|
||||
tag = msg_tag_init4(0, 0, 0, 0);
|
||||
} break;
|
||||
case SEMA_DOWN: {
|
||||
}
|
||||
break;
|
||||
case SEMA_DOWN:
|
||||
{
|
||||
umword_t ret;
|
||||
|
||||
ret = sema_down(sema, f->regs[0]);
|
||||
@@ -142,7 +173,8 @@ static sema_t *sema_create(ram_limit_t *lim, umword_t cnt, umword_t max)
|
||||
#else
|
||||
kobj = mm_limit_alloc(lim, sizeof(sema_t));
|
||||
#endif
|
||||
if (!kobj) {
|
||||
if (!kobj)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
sema_init(kobj, cnt, max);
|
||||
@@ -166,10 +198,12 @@ static void sema_release_stage1(kobject_t *kobj)
|
||||
first_wait_node = slist_first(&obj->suspend_head);
|
||||
first_wait = container_of(first_wait_node, sema_wait_item_t, node);
|
||||
slist_del(first_wait_node);
|
||||
if (ref_counter_dec_and_release(&first_wait->thread->ref, &first_wait->thread->kobj) != 1) {
|
||||
if (ref_counter_dec_and_release(&first_wait->thread->ref, &first_wait->thread->kobj) != 1)
|
||||
{
|
||||
thread_ready_remote(first_wait->thread, FALSE);
|
||||
}
|
||||
if (obj->cnt < obj->max_cnt) {
|
||||
if (obj->cnt < obj->max_cnt)
|
||||
{
|
||||
obj->cnt++;
|
||||
}
|
||||
}
|
||||
@@ -188,13 +222,16 @@ static void sema_release_stage2(kobject_t *kobj)
|
||||
|
||||
void sema_init(sema_t *obj, int cnt, int max)
|
||||
{
|
||||
if (max <= 0) {
|
||||
if (max <= 0)
|
||||
{
|
||||
max = 1;
|
||||
}
|
||||
if (cnt < 0) {
|
||||
if (cnt < 0)
|
||||
{
|
||||
cnt = 0;
|
||||
}
|
||||
if (cnt > max) {
|
||||
if (cnt > max)
|
||||
{
|
||||
cnt = max;
|
||||
}
|
||||
obj->cnt = cnt;
|
||||
@@ -213,7 +250,8 @@ static kobject_t *sema_func(ram_limit_t *lim, umword_t arg0, umword_t arg1,
|
||||
umword_t arg2, umword_t arg3)
|
||||
{
|
||||
sema_t *sema = sema_create(lim, arg0, arg1);
|
||||
if (!sema) {
|
||||
if (!sema)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return &sema->kobj;
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "mpu.h"
|
||||
#include "init.h"
|
||||
#include "dlist.h"
|
||||
#include "printk.h"
|
||||
#if IS_ENABLED(CONFIG_BUDDY_SLAB)
|
||||
#include <slab.h>
|
||||
static slab_t *share_mem_slab;
|
||||
@@ -261,6 +262,7 @@ static int share_mem_alloc_pmem(share_mem_t *obj)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
printk("share mem:[0x%x 0x%x]\n", obj->mem, (char *)obj->mem + obj->size);
|
||||
memset(obj->mem, 0, obj->size);
|
||||
break;
|
||||
case SHARE_MEM_CNT_DPD:
|
||||
@@ -464,7 +466,7 @@ static void share_mem_release_stage2(kobject_t *kobj)
|
||||
{
|
||||
share_mem_t *sm = container_of(kobj, share_mem_t, kobj);
|
||||
|
||||
assert(dlist_is_empty(&sm->task_head));//TODO:有bug
|
||||
assert(dlist_is_empty(&sm->task_head)); // TODO:有bug
|
||||
|
||||
#if IS_ENABLED(CONFIG_MMU)
|
||||
share_mem_free_pmem(sm);
|
||||
|
||||
@@ -53,8 +53,8 @@ void thread_check_timeout(void)
|
||||
if (pos->times == 0)
|
||||
{
|
||||
assert(pos->th->status == THREAD_SUSPEND);
|
||||
thread_ready(pos->th, TRUE);
|
||||
slist_del(&pos->node);
|
||||
thread_ready(pos->th, TRUE);
|
||||
}
|
||||
} // !< 如果是0,则一直休眠
|
||||
pos = next;
|
||||
@@ -74,7 +74,7 @@ thread_wait_entry_t *thread_sleep_del(thread_t *th)
|
||||
pos, (slist_head_t *)&wait_list,
|
||||
node)
|
||||
{
|
||||
assert(pos->th->status == THREAD_SUSPEND);
|
||||
// assert(pos->th->status == THREAD_SUSPEND);
|
||||
thread_wait_entry_t *next = slist_next_entry(
|
||||
pos, (slist_head_t *)wait_list,
|
||||
node);
|
||||
@@ -119,6 +119,5 @@ umword_t thread_sleep(umword_t tick)
|
||||
thread_suspend(cur_th);
|
||||
spinlock_set(&lock, status);
|
||||
preemption();
|
||||
|
||||
return entry.times;
|
||||
}
|
||||
@@ -432,6 +432,7 @@ static void task_syscall_func(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t i
|
||||
tag_task->nofity_bitmap_len = (f->regs[4]);
|
||||
tag_task->nofity_msg_buf = (addr_t)f->regs[5];
|
||||
tag_task->nofity_map_buf = (umword_t *)((addr_t)f->regs[5] + THREAD_MSG_BUG_LEN);
|
||||
sema_init(&tag_task->notify_sema, tag_task->nofity_bitmap_len, tag_task->nofity_bitmap_len);
|
||||
tag = msg_tag_init4(0, 0, 0, 0);
|
||||
}
|
||||
break;
|
||||
@@ -578,7 +579,7 @@ task_t *task_create(ram_limit_t *lim, int is_knl)
|
||||
return NULL;
|
||||
}
|
||||
task_init(tk, lim, is_knl);
|
||||
// printk("create task is 0x%x\n", tk);
|
||||
printk("create task is 0x%x\n", tk);
|
||||
return tk;
|
||||
}
|
||||
|
||||
|
||||
@@ -432,6 +432,7 @@ void thread_ready_remote(thread_t *th, bool_t is_sche)
|
||||
*/
|
||||
void thread_ready(thread_t *th, bool_t is_sche)
|
||||
{
|
||||
assert(th);
|
||||
bool_t ret;
|
||||
umword_t status = cpulock_lock();
|
||||
|
||||
@@ -1198,22 +1199,12 @@ msg_tag_t thread_fast_ipc_call(thread_t *to_th, entry_frame_t *f, umword_t user_
|
||||
printk("task:0x%x, notify point is not set.\n", to_task);
|
||||
return msg_tag_init4(0, 0, 0, -EIO);
|
||||
}
|
||||
_to_unlock:
|
||||
if (GET_LSB(*to_task->nofity_bitmap, to_task->nofity_bitmap_len) == GET_LSB((~0ULL), to_task->nofity_bitmap_len))
|
||||
{
|
||||
thread_sched(TRUE); /*TODO:应该挂起,并在释放时唤醒*/
|
||||
preemption();
|
||||
goto _to_unlock;
|
||||
}
|
||||
sema_down(&to_task->notify_sema, 0);
|
||||
mutex_lock(&to_task->nofity_lock, 0);
|
||||
if (GET_LSB(*to_task->nofity_bitmap, to_task->nofity_bitmap_len) == GET_LSB((~0ULL), to_task->nofity_bitmap_len))
|
||||
{
|
||||
mutex_unlock(&to_task->nofity_lock);
|
||||
thread_sched(TRUE); /*TODO:应该挂起,并在释放时唤醒*/
|
||||
preemption();
|
||||
goto _to_unlock;
|
||||
}
|
||||
umword_t cpu_status = cpulock_lock();
|
||||
assert(cur_th->magic == THREAD_MAGIC);
|
||||
|
||||
to_task = thread_get_bind_task(to_th);
|
||||
ref_counter_inc((&to_task->ref_cn));
|
||||
//!< 执行目标线程时用的是当前线程的资源,这里还需要备份当前线程的上下文。
|
||||
ret = thread_fast_ipc_save(cur_th, to_task, (void *)(to_task->nofity_stack - 4 * 8 /*FIXME:改成宏*/)); //!< 备份栈和usp
|
||||
@@ -1252,6 +1243,7 @@ _to_unlock:
|
||||
pf_t *cur_pf = ((pf_t *)((char *)cur_th + CONFIG_THREAD_BLOCK_SIZE + 8)) - 1;
|
||||
// 重新设置r9寄存器
|
||||
cur_pf->regs[5] = (umword_t)(to_task->mm_space.mm_block);
|
||||
cur_th->sp.user_sp = cur_pf;
|
||||
|
||||
//! 寄存器传参数
|
||||
f->regs[0] = in_tag.raw;
|
||||
@@ -1274,12 +1266,14 @@ _to_unlock:
|
||||
{
|
||||
ref_counter_dec_and_release(&to_task->ref_cn, &to_task->kobj);
|
||||
mutex_unlock(&to_task->nofity_lock);
|
||||
sema_up(&to_task->notify_sema);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ref_counter_dec_and_release(&to_task->ref_cn, &to_task->kobj);
|
||||
mutex_unlock(&to_task->nofity_lock);
|
||||
sema_up(&to_task->notify_sema);
|
||||
}
|
||||
cpulock_set(cpu_status);
|
||||
|
||||
@@ -1293,6 +1287,7 @@ msg_tag_t thread_fast_ipc_replay(entry_frame_t *f)
|
||||
task_t *old_task = thread_get_bind_task(cur_th);
|
||||
int ret;
|
||||
|
||||
assert(cur_th->magic == THREAD_MAGIC);
|
||||
*(cur_task->nofity_bitmap) &= ~(1 << MIN(f->regs[2], cur_task->nofity_bitmap_len)); //!< 解锁bitmap
|
||||
slist_del(&cur_th->com->fast_ipc_node); // 从链表中删除
|
||||
|
||||
@@ -1347,6 +1342,7 @@ msg_tag_t thread_fast_ipc_replay(entry_frame_t *f)
|
||||
in_tag = msg_tag_init4(0, 0, 0, ret);
|
||||
}
|
||||
cpulock_set(cpu_status);
|
||||
sema_up(&old_task->notify_sema);
|
||||
if (thread_is_knl(cur_th))
|
||||
{
|
||||
arch_to_sche();
|
||||
|
||||
@@ -272,7 +272,7 @@ bool_t task_knl_kill(thread_t *kill_thread, bool_t is_knl)
|
||||
task_t *task = container_of(kill_thread->task, task_t, kobj);
|
||||
if (!is_knl)
|
||||
{
|
||||
printk("kill %s task:0x%x, pid:%d\n", kobject_get_name(&task->kobj), task, task->pid);
|
||||
printk("kill %s th:0x%x task:0x%x, pid:%d\n", kobject_get_name(&task->kobj), kill_thread, task, task->pid);
|
||||
umword_t status2;
|
||||
|
||||
status2 = spinlock_lock(&del_lock);
|
||||
|
||||
Reference in New Issue
Block a user