xiuos3/kernel/thread/id.c

143 lines
3.1 KiB
C

/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file: id.c
* @brief: the management with id for all kernel object
* @version: 1.0
* @author: AIIT XUOS Lab
* @date: 2020/4/15
*
*/
#include <xiuos.h>
static int AllocId(struct IdManager *manager)
{
int index = 0;
int end = 0;
int id = 0;
uint8 entry = 0;
NULL_PARAM_CHECK(manager);
end = (manager->id_max + 7) / 8;
for (index = 0; index < end; index++)
if (manager->id_map[index] != 0xff)
break;
if (index == end)
return -1;
id = index * 8;
entry = manager->id_map[index];
while (entry & 0x1) {
id++;
entry >>= 1;
}
if (id >= manager->id_max)
return -1;
manager->id_map[index] |= (0x1 << (id % 8));
return id;
}
static void FreeId(struct IdManager *manager, uint16 id)
{
NULL_PARAM_CHECK(manager);
manager->id_map[id / 8] &= ~(0x1 << (id % 8));
}
static void InsertObj(struct IdManager *manager, struct IdNode *idnode)
{
NULL_PARAM_CHECK(manager);
NULL_PARAM_CHECK(idnode);
DoubleLinklistType *head = &manager->htable[idnode->id % manager->hoffset];
if (head->node_prev == NONE)
InitDoubleLinkList(head);
DoubleLinkListInsertNodeAfter(head, &idnode->link);
}
static struct IdNode *GetObj(struct IdManager *manager, uint16 id)
{
NULL_PARAM_CHECK(manager);
DoubleLinklistType *head = &manager->htable[id % manager->hoffset];
DoubleLinklistType *node = NONE;
struct IdNode *idnode = NONE;
if (head->node_prev == NONE) {
InitDoubleLinkList(head);
return NONE;
}
DOUBLE_LINKLIST_FOR_EACH(node, head) {
idnode =CONTAINER_OF(node, struct IdNode, link);
if (idnode->id == id)
break;
idnode = NONE;
}
return idnode;
}
static struct IdNode *RemoveObj(struct IdManager *manager, struct IdNode *idnode)
{
NULL_PARAM_CHECK(manager);
NULL_PARAM_CHECK(idnode);
DoubleLinkListRmNode(&idnode->link);
}
int IdInsertObj(struct IdManager *manager, struct IdNode *idnode)
{
int id = 0;
NULL_PARAM_CHECK(manager);
NULL_PARAM_CHECK(idnode);
if ((id = AllocId(manager)) < 0)
return -1;
idnode->id = id;
InsertObj(manager, idnode);
return id;
}
struct IdNode *IdGetObj(struct IdManager *manager, uint16 id)
{
if (manager == NONE || id >= manager->id_max)
return NONE;
return GetObj(manager, id);
}
void IdRemoveObj(struct IdManager *manager, uint16 id)
{
NULL_PARAM_CHECK(manager);
struct IdNode *idnode = IdGetObj(manager, id);
if (idnode == NONE)
return;
FreeId(manager, idnode->id);
RemoveObj(manager, idnode);
idnode->id = -1;
}