如图:
- 1、正确的,下意识认为的
- 2、bug的,实际发生的。
测试代码:
#include "gtest/gtest.h"
#include "mockcpp/mokc.h"
#include "linux/list.h"
#include <cstdlib>
#define TEST_PRINT
#ifdef TEST_PRINT
#define TEST_LOG_PRINT(x) std::cout << "res is [" << x << "]"
#define TEST_LOG_PRINT2(x) std::cout << "res is [" << x << "]\n"
#endif // TEST_PRINT
TEST(linux_list, basic)
{
head_t list;
// Act#01: 空链表 ---> 指向自身
INIT_LIST_HEAD(&list);
// assert#01:
EXPECT_EQ(list.prev, &list);
EXPECT_EQ(list.next, &list);
}
TEST(linux_list, add_tail)
{
struct TestBuffer
{
int val;
list_head list;
};
// Act: 链表链接10个元素: 0 1 2 ... 9
list_head *head = NULL;
for (int i = 0; i < 10; i++)
{
TestBuffer *buff = (TestBuffer *)malloc(sizeof(*buff));
buff->val = i;
INIT_LIST_HEAD(&buff->list);
if (i == 0)
head = &buff->list;
else
{
list_add_tail(&buff->list, head);
}
}
// Assert: 注意,第1个元素被当做表头了,所以遍历不到。
TestBuffer *cusor = NULL;
int i = 1;
TEST_LOG_PRINT2("fff");
list_for_each_entry(cusor, head, list)
{
EXPECT_EQ(cusor->val, i++);
TEST_LOG_PRINT(cusor->val);
}
std::cout << "\n";
}
List相关:简化版linux/list.h
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _LINUX_LIST_H
#define _LINUX_LIST_H
struct list_head {
struct list_head *next, *prev;
};
`/**
* INIT_LIST_HEAD - Initialize a list_head structure
* @list: list_head structure to be initialized.
*
* Initializes the list_head to point to itself. If it is a list header,
* the result is an empty list.
*/
static inline void INIT_LIST_HEAD(struct list_head *list)
{
WRITE_ONCE(list->next, list);
WRITE_ONCE(list->prev, list);
}
/**
* list_add_tail - add a new entry
* @new: new entry to be added
* @head: list head to add it before
*
* Insert a new entry before the specified head.
* This is useful for implementing queues.
*/
static inline void list_add_tail(struct list_head *new, struct list_head *head)
{
__list_add(new, head->prev, head);
}
/*
* Insert a new entry between two known consecutive entries.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_add(struct list_head *new,
struct list_head *prev,
struct list_head *next)
{
if (!__list_add_valid(new, prev, next))
return;
next->prev = new;
new->next = next;
new->prev = prev;
WRITE_ONCE(prev->next, new);
}
``