首页 > 系统相关 >Linux源码list.h用户态改编

Linux源码list.h用户态改编

时间:2022-09-27 17:57:01浏览次数:72  
标签:head struct list pos next 源码 Linux entry

前言

操作系统课程的第一个作业:理解list.h的设计思想和技巧并用list.h实现一个进程管理程序。
我的Linux环境为WSL-Ubuntu,该环境中/usr/include/linux目录下无list.h文件,无法使用系统态的list.h
查阅大量博客得到的其他博主改编的list.h,复制到vscode中仍然大量报错。
故阅读list.h源码,改编成用户态的mylist.h

作业中需要的API不多,所以mylist.h很大程度上对list.h做了删减。

list.h 源码地址

WSL2-Linux-Kernel/list.h at linux-msft-wsl-5.15.y · microsoft/WSL2-Linux-Kernel (github.com)

mylist.h 源码

点击查看代码
/*
 * @Descripttion: A short copy from list.h
 * @Author: xiongty
 * @Date: 2022-09-25 15:11:25
 * @LastEditors: xiongty
 * @LastEditTime: 2022-09-25 18:44:03
 */

/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _LINUX_LIST_H
#define _LINUX_LIST_H

#ifndef NULL
#define NULL 0
#endif 

#ifndef offsetof
#define offsetof(type, member) ((long) &((type *) 0)->member)
#endif
 

#ifndef container_of
#define container_of(ptr, type, member) ({  \
	const typedef (((type *)0)->member)* __mptr = (ptr);  \
    ((type *) ((char *) __mptr - offsetof(type, member))); \
})
#endif

/*
 * Circular doubly linked list implementation.
 *
 * Some of the internal functions ("__xxx") are useful when
 * manipulating whole lists rather than single entries, as
 * sometimes we already know the next/prev entries and we can
 * generate better code by using them directly rather than
 * using the generic single-entry routines.
 */

struct list_head {
    struct list_head *next;
    struct list_head *prev;
};

#define LIST_HEAD_INIT(name) { &(name), &(name) }

#define LIST_HEAD(name) \
	struct list_head name = LIST_HEAD_INIT(name)

/**
 * 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)
{
	list->prev = list;
    list->next = list;
}

/*
 * 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 *node,
			      struct list_head *prev,
			      struct list_head *next)
{
	node->next = next;
    next->prev = node;
	node->prev = prev;
    prev->next = node;
}

/**
 * list_add - add a new entry
 * @node: new entry to be added
 * @head: list head to add it after
 *
 * Insert a new entry after the specified head.
 * This is good for implementing stacks.
 */
static inline void list_add(struct list_head *node, struct list_head *head)
{
	__list_add(node, head, head->next);
}


/**
 * list_add_tail - add a new entry
 * @node: 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 *node, struct list_head *head)
{
	__list_add(node, head->prev, head);
}

/*
 * Delete a list entry by making the prev/next entries
 * point to each other.
 *
 * This is only for internal list manipulation where we know
 * the prev/next entries already!
 */
static inline void __list_del(struct list_head * prev, struct list_head * next)
{
	next->prev = prev;
	prev->next = next;
}

/**
 * list_del - deletes entry from list.
 * @entry: the element to delete from the list.
 * Note: list_empty() on entry does not return true after this, the entry is
 * in an undefined state.
 */
static inline void list_del(struct list_head *entry)
{
	__list_del(entry->prev,entry->next);
    entry->prev = NULL;
    entry->next = NULL;
}


/**
 * list_is_first -- tests whether @list is the first entry in list @head
 * @list: the entry to test
 * @head: the head of the list
 */
static inline int list_is_first(const struct list_head *list, const struct list_head *head)
{
	return list->prev == head;
}

/**
 * list_is_last - tests whether @list is the last entry in list @head
 * @list: the entry to test
 * @head: the head of the list
 */
static inline int list_is_last(const struct list_head *list, const struct list_head *head)
{
	return list->next == head;
}

/**
 * list_is_head - tests whether @list is the list @head
 * @list: the entry to test
 * @head: the head of the list
 */
static inline int list_is_head(const struct list_head *list, const struct list_head *head)
{
	return list == head;
}

/**
 * list_empty - tests whether a list is empty
 * @head: the list to test.
 */
static inline int list_empty(const struct list_head *head)
{
	return head->next == head;
}

/**
 * list_entry - get the struct for this entry
 * @ptr:	the &struct list_head pointer.
 * @type:	the type of the struct this is embedded in.
 * @member:	the name of the list_head within the struct.
 */
#define list_entry(ptr, type, member) \
	container_of(ptr, type, member)

/**
 * list_for_each	-	iterate over a list
 * @pos:	the &struct list_head to use as a loop cursor.
 * @head:	the head for your list.
 */
#define list_for_each(pos, head) \
	for (pos = (head)->next; !list_is_head(pos, (head)); pos = pos->next)

/**
 * list_for_each_safe - iterate over a list safe against removal of list entry
 * @pos:	the &struct list_head to use as a loop cursor.
 * @n:		another &struct list_head to use as temporary storage
 * @head:	the head for your list.
 */
#define list_for_each_safe(pos, n, head) \
	for (pos = (head)->next, n = pos->next; \
	     !list_is_head(pos, (head)); \
	     pos = n, n = pos->next)

/**
 * list_entry_is_head - test if the entry points to the head of the list
 * @pos:	the type * to cursor
 * @head:	the head for your list.
 * @member:	the name of the list_head within the struct.
 */
#define list_entry_is_head(pos, head, member)				\
	(&pos->member == (head))

/**
 * list_for_each_entry	-	iterate over list of given type
 * @pos:	the type * to use as a loop cursor.
 * @head:	the head for your list.
 * @member:	the name of the list_head within the struct.
 */
#define list_for_each_entry(pos, head, member)				\
	for (pos = list_first_entry(head, typeof(*pos), member);	\
	     !list_entry_is_head(pos, head, member);			\
	     pos = list_next_entry(pos, member))

#endif

标签:head,struct,list,pos,next,源码,Linux,entry
From: https://www.cnblogs.com/sachi/p/16735392.html

相关文章

  • cpc 查修系统 ConditionList.vue 条件列表
    ConditionList.vue条件列表<template><divclass="w-fullpt-2pl-2"><el-formref="ruleFormRef":model="ruleForm":rules="rules"......
  • 11 | python脚本更改linux系统下的文件权限
    在文件上传至linux系统的过程中遇到了执行文件不可执行的问题。于是自己写了一个python脚本和文件夹放到一起,上传后运行即可!frompathlibimport*#目录文件名......
  • Linux命令查找和压缩 find which whereis 和tar
    1 find的命令1.1命令的特点:精确查找实时查找支持查找条件很多各表达式之间使用逻辑运算符,“-a”表示而且(and),“-o”表示或者(or)  查找路径:指定具体目标路......
  • RocketMQ源码下载使用
    RocketMQ源码下载使用RocketMQ[github]下载地址 我公司用的是4.5.1,所以我为了解决问题就下载了对应的版本RocketMQ控制台[git]源码地址NameServer要先启动【......
  • Linux回环地址网卡配置修改
    折腾了好久,试了各种方法,才发现直接修改配置文件不行,而且新建con的方法也试了后来发现需要新建一个连接文件修改,原来的那个文件不要动┌──[[email protected]......
  • 在linux上,关于 MySQL账号安全性问题
    安装MySQL之后,系统就会出现一个mysql账号。所有MySQL的行为都需要这个mysql账号来执行。1、默认情况下,mysql账号不能登录。只能启动mysql2、如果需要mysql读写文件时,需要......
  • jenkins配置Linux子节点常见问题
    操作系统:虚拟机安装CentOS-7-x86_64-DVD-1810.isoRemoterootdirectory:/home/admin/jenkinsLaunchmethod:Launchagentbyconnectingittothemaster1.离线安装G......
  • linux查看tcp连接的建立时间
    linux查看连接的建立时间1、netstat-ntp|grepport确定要找哪个连接,对应的哪个进程,哪个端口,上述是查找26901进程建立的连接37321端口2、lsof-ppid|grepport138就......
  • linux安装jdk1.8
    下载安装包https://www.oracle.com/java/technologies/downloads/在usr下新建java文件夹cd/usrmkdirjavacdjava下载好的安装包放到刚创建的java下jdk-8u341-li......
  • Linux下定时自动备份Docker中所有SqlServer数据库
    准备工作一台Linux(Centos7为例)服务器。安装Docker服务。安装并启动SqlServer容器服务。编写Shell文件给出一个备份的范例#!/bin/bash#设置mssql备份目录folder......