我正在用C实现一个跳过列表。 但是,skiplist_insert函数不起作用。插入列表的节点中的taskArray没有正确的任务。 我真的不知道为什么。 有人可以指出我正确的方向吗? 我已经被这个问题困扰了好几天了。
找到原始实现here。 malloc函数被OSMemCreate和OSMemGet取代,因为它将用于不允许使用malloc的实时OS。
这就是我使用代码的方式(为简单起见,将其截断):
skiplist_init(&rTaskList);
task recTask = {(period+tickCnt) % MAXTICKCNT,
overflow,
TCB,
name,
taskptr,
prio,
stk,
stksize};
arr.count = 1;
arr.tasks=&recTask;
skiplist_insert(rTaskList, 0, arr);
这是实现本身
typedef struct task{
CPU_INT16U period;
CPU_INT08U overflow_flag;
OS_TCB * TCB;
CPU_CHAR * name;
OS_TASK_PTR taskptr;
OS_PRIO prio;
CPU_STK * stk;
CPU_STK_SIZE stksize;
}task;
typedef struct taskArray{
CPU_INT32U count;
task * tasks;
}taskArray;
typedef struct snode {
int key;
taskArray arr;
OS_MEM * MyPartitionPtr;
OS_MEM * ForwardPartitionPtr;
struct snode **forward;
} snode;
typedef struct skiplist {
int level;
struct snode *header;
} skiplist;
skiplist *skiplist_init(skiplist *list) {
int i;
OS_ERR err;
CPU_INT08U MyPartitionStorage[12][100];
CPU_INT08U MyPartitionStorage2[12][100];
OS_MEM MyPartition;
OS_MEM ForwardPartition;
// Memory management
OSMemCreate((OS_MEM *)&MyPartition,
(CPU_CHAR *)"My Partition",
(void *)&MyPartitionStorage[0][0],
(OS_MEM_QTY ) 12,
(OS_MEM_SIZE)100,
(OS_ERR *)&err);
snode *header = (snode *)OSMemGet((OS_MEM *)&MyPartition,
(OS_ERR *)&err);
list->header = header;
header->key = INT_MAX;
header->MyPartitionPtr = &MyPartition; // update mem ptr
// Replace malloc function
OSMemCreate((OS_MEM *)&ForwardPartition,
(CPU_CHAR *)"My Partition",
(void *)&MyPartitionStorage2[0][0],
(OS_MEM_QTY ) 12,
(OS_MEM_SIZE)100,
(OS_ERR *)&err);
header->forward = (snode **)OSMemGet((OS_MEM *)&ForwardPartition,
(OS_ERR *)&err);
if (err != OS_ERR_NONE){
true; // for catching memory allocation errors
}
header->ForwardPartitionPtr = &ForwardPartition; // update mem ptr
for (i = 0; i <= SKIPLIST_MAX_LEVEL; i++) {
header->forward[i] = list->header;
}
list->level = 1;
return list;
}
static int rand_level() {
int level = 1;
while (rand() < RAND_MAX / 2 && level < SKIPLIST_MAX_LEVEL)
level++;
return level;
}
int skiplist_insert(skiplist *list, int key, taskArray arr) {
OS_ERR err;
OS_MEM MyPartition;
OS_MEM ForwardPartition;
CPU_INT08U MyPartitionStorage[12][100];
CPU_INT08U MyPartitionStorage2[12][100];
snode *update[SKIPLIST_MAX_LEVEL + 1];
snode *x = list->header;
int i, level;
for (i = list->level; i >= 1; i--) {
while (x->forward[i]->key < key)
x = x->forward[i];
update[i] = x;
}
x = x->forward[1];
if (key == x->key) {
x->arr = arr;
return 0;
} else {
level = rand_level();
if (level > list->level) {
for (i = list->level + 1; i <= level; i++) {
update[i] = list->header;
}
list->level = level;
}
//Mem alloc
OSMemCreate((OS_MEM *)&MyPartition,
(CPU_CHAR *)"My Partition",
(void *)&MyPartitionStorage[0][0],
(OS_MEM_QTY ) 12,
(OS_MEM_SIZE)100,
(OS_ERR *)&err);
x = (snode *)OSMemGet((OS_MEM *)&MyPartition,
(OS_ERR *)&err);
x->key = key;
x->arr = arr;
x->MyPartitionPtr = &MyPartition; // update ptr
// replace malloc function
OSMemCreate((OS_MEM *)&ForwardPartition,
(CPU_CHAR *)"Forward Partition",
(void *)&MyPartitionStorage2[0][0],
(OS_MEM_QTY ) 12,
(OS_MEM_SIZE)100,
(OS_ERR *)&err);
x->forward = (snode **)OSMemGet((OS_MEM *)&ForwardPartition,
(OS_ERR *)&err);
x->ForwardPartitionPtr = &ForwardPartition;
for (i = 1; i <= level; i++) {
x->forward[i] = update[i]->forward[i];
update[i]->forward[i] = x;
}
}
return 0;
}