mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-18 08:06:32 +00:00
doc: Add ai doc translate tool and add English doc. (#1168)
- add tools/doc_translator.py - translated docs into English Signed-off-by: longjin <longjin@DragonOS.org>
This commit is contained in:
112
docs/locales/en/kernel/core_api/atomic.md
Normal file
112
docs/locales/en/kernel/core_api/atomic.md
Normal file
@ -0,0 +1,112 @@
|
||||
:::{note}
|
||||
**AI Translation Notice**
|
||||
|
||||
This document was automatically translated by `Qwen/Qwen3-8B` model, for reference only.
|
||||
|
||||
- Source document: kernel/core_api/atomic.md
|
||||
|
||||
- Translation time: 2025-05-19 01:41:25
|
||||
|
||||
- Translation model: `Qwen/Qwen3-8B`
|
||||
|
||||
Please report issues via [Community Channel](https://github.com/DragonOS-Community/DragonOS/issues)
|
||||
|
||||
:::
|
||||
|
||||
# Atomic Variables
|
||||
|
||||
## Introduction
|
||||
|
||||
  DragonOS implements atomic variables of type `atomic_t`. Atomic variables are implemented using architecture-specific atomic operation instructions. The specific implementation is located in `kernel/common/atomic.h`.
|
||||
|
||||
## API
|
||||
|
||||
   Note that all the following APIs are atomic operations.
|
||||
|
||||
### `inline void atomic_add(atomic_t *ato, long val)`
|
||||
|
||||
#### Description
|
||||
|
||||
   Atomically adds a specified value to the atomic variable.
|
||||
|
||||
#### Parameters
|
||||
|
||||
**ato**
|
||||
|
||||
   The atomic variable object.
|
||||
|
||||
**val**
|
||||
|
||||
   The value to be added to the variable.
|
||||
|
||||
### `inline void atomic_sub(atomic_t *ato, long val)`
|
||||
|
||||
#### Description
|
||||
|
||||
   Atomically subtracts a specified value from the atomic variable.
|
||||
|
||||
#### Parameters
|
||||
|
||||
**ato**
|
||||
|
||||
   The atomic variable object.
|
||||
|
||||
**val**
|
||||
|
||||
   The value to be subtracted from the variable.
|
||||
|
||||
### `void atomic_inc(atomic_t *ato)`
|
||||
|
||||
#### Description
|
||||
|
||||
   Atomically increments the atomic variable by 1.
|
||||
|
||||
#### Parameters
|
||||
|
||||
**ato**
|
||||
|
||||
   The atomic variable object.
|
||||
|
||||
### `void atomic_dec(atomic_t *ato)`
|
||||
|
||||
#### Description
|
||||
|
||||
   Atomically decrements the atomic variable by 1.
|
||||
|
||||
#### Parameters
|
||||
|
||||
**ato**
|
||||
|
||||
   The atomic variable object.
|
||||
|
||||
### `inline void atomic_set_mask(atomic_t *ato, long mask)`
|
||||
|
||||
#### Description
|
||||
|
||||
   Performs a bitwise OR operation between the atomic variable and the mask variable.
|
||||
|
||||
#### Parameters
|
||||
|
||||
**ato**
|
||||
|
||||
   The atomic variable object.
|
||||
|
||||
**mask**
|
||||
|
||||
   The variable used for the OR operation with the atomic variable.
|
||||
|
||||
### `inline void atomic_clear_mask(atomic_t *ato, long mask)`
|
||||
|
||||
#### Description
|
||||
|
||||
   Performs a bitwise AND operation between the atomic variable and the mask variable.
|
||||
|
||||
#### Parameters
|
||||
|
||||
**ato**
|
||||
|
||||
   The atomic variable object.
|
||||
|
||||
**mask**
|
||||
|
||||
   The variable used for the AND operation with the atomic variable.
|
77
docs/locales/en/kernel/core_api/casting.md
Normal file
77
docs/locales/en/kernel/core_api/casting.md
Normal file
@ -0,0 +1,77 @@
|
||||
:::{note}
|
||||
**AI Translation Notice**
|
||||
|
||||
This document was automatically translated by `Qwen/Qwen3-8B` model, for reference only.
|
||||
|
||||
- Source document: kernel/core_api/casting.md
|
||||
|
||||
- Translation time: 2025-05-19 01:41:11
|
||||
|
||||
- Translation model: `Qwen/Qwen3-8B`
|
||||
|
||||
Please report issues via [Community Channel](https://github.com/DragonOS-Community/DragonOS/issues)
|
||||
|
||||
:::
|
||||
|
||||
# Type Conversion Library API
|
||||
|
||||
  The kernel provides some functions to help you convert between different types. These include the following types:
|
||||
|
||||
- Numeric type conversion (using the `num-traits` library)
|
||||
- Arc type conversion
|
||||
|
||||
  All functions not specially marked are implemented in `kernel/src/libs/casting.rs`.
|
||||
|
||||
## 1. Numeric Type Conversion
|
||||
|
||||
### 1.1 Conversion Between Integer Types and Enum Types
|
||||
|
||||
  You can use macros provided by the `num-traits` library to convert between enum types and integer types.
|
||||
The SystemError enum type uses this approach, and you can find its usage in `kernel/src/syscall/mod.rs`.
|
||||
|
||||
  It first inherits the `FromPrimitive, ToPrimitive` two traits, and then performs the conversion like this:
|
||||
|
||||
```rust
|
||||
impl SystemError {
|
||||
/// @brief 把posix错误码转换为系统错误枚举类型。
|
||||
pub fn from_posix_errno(errno: i32) -> Option<SystemError> {
|
||||
// posix 错误码是小于0的
|
||||
if errno >= 0 {
|
||||
return None;
|
||||
}
|
||||
return <Self as FromPrimitive>::from_i32(-errno);
|
||||
}
|
||||
|
||||
/// @brief 把系统错误枚举类型转换为负数posix错误码。
|
||||
pub fn to_posix_errno(&self) -> i32 {
|
||||
return -<Self as ToPrimitive>::to_i32(self).unwrap();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
  These two functions well illustrate how to use these two traits.
|
||||
|
||||
## 2. Arc Type Conversion
|
||||
|
||||
### 2.1 Conversion from Arc<dyn U> to Arc<T>
|
||||
|
||||
  When we need to convert an `Arc<dyn U>` to a specific type pointer of `Arc<T>`, we need to implement the `DowncastArc` trait for `U`. This trait is defined in `kernel/src/libs/casting.rs`. It requires `trait U` to implement the `Any + Sync + Send` trait.
|
||||
|
||||
  To implement the `DowncastArc` trait for `trait U: Any + Send + Sync`, you need to do the following:
|
||||
|
||||
```rust
|
||||
impl DowncastArc for dyn U {
|
||||
fn as_any_arc(self: Arc<Self>) -> Arc<dyn Any> {
|
||||
return self;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
  Using the `DowncastArc` trait, we can convert like this:
|
||||
|
||||
```rust
|
||||
let arc: Arc<dyn U> = ...;
|
||||
let arc_t: Arc<T> = arc.downcast_arc::<T>().unwrap();
|
||||
```
|
||||
|
||||
  If the specific type of `arc` is not `Arc<T>`, then `downcast_arc::<T>()` will return `None`.
|
28
docs/locales/en/kernel/core_api/index.rst
Normal file
28
docs/locales/en/kernel/core_api/index.rst
Normal file
@ -0,0 +1,28 @@
|
||||
.. note:: AI Translation Notice
|
||||
|
||||
This document was automatically translated by `Qwen/Qwen3-8B` model, for reference only.
|
||||
|
||||
- Source document: kernel/core_api/index.rst
|
||||
|
||||
- Translation time: 2025-05-19 01:41:08
|
||||
|
||||
- Translation model: `Qwen/Qwen3-8B`
|
||||
|
||||
|
||||
Please report issues via `Community Channel <https://github.com/DragonOS-Community/DragonOS/issues>`_
|
||||
|
||||
====================================
|
||||
Core API Documentation
|
||||
====================================
|
||||
|
||||
This is the core API documentation for DragonOS.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:caption: Kernel Utility Library
|
||||
|
||||
kernel_api
|
||||
atomic
|
||||
casting
|
||||
notifier_chain
|
||||
softirq
|
630
docs/locales/en/kernel/core_api/kernel_api.md
Normal file
630
docs/locales/en/kernel/core_api/kernel_api.md
Normal file
@ -0,0 +1,630 @@
|
||||
:::{note}
|
||||
**AI Translation Notice**
|
||||
|
||||
This document was automatically translated by `Qwen/Qwen3-8B` model, for reference only.
|
||||
|
||||
- Source document: kernel/core_api/kernel_api.md
|
||||
|
||||
- Translation time: 2025-05-19 01:43:39
|
||||
|
||||
- Translation model: `Qwen/Qwen3-8B`
|
||||
|
||||
Please report issues via [Community Channel](https://github.com/DragonOS-Community/DragonOS/issues)
|
||||
|
||||
:::
|
||||
|
||||
# DragonOS Kernel Core API
|
||||
|
||||
## Circular Linked List Management Functions
|
||||
|
||||
  Circular linked list is one of the important data structures in the kernel. It is included in `kernel/common/list.h`.
|
||||
|
||||
### `void list_init(struct List *list)`
|
||||
|
||||
#### Description
|
||||
|
||||
  Initialize a List structure so that its prev and next pointers point to itself.
|
||||
|
||||
#### Parameters
|
||||
|
||||
**list**
|
||||
|
||||
  The List structure to be initialized.
|
||||
|
||||
### `void list_add(struct List *entry, struct List *node)`
|
||||
|
||||
#### Description
|
||||
|
||||
  Insert the node after the entry.
|
||||
|
||||
#### Parameters
|
||||
|
||||
**entry**
|
||||
|
||||
  An existing node in the circular linked list.
|
||||
|
||||
**node**
|
||||
|
||||
  The node to be inserted.
|
||||
|
||||
### `void list_append(struct List *entry, struct List *node)`
|
||||
|
||||
#### Description
|
||||
|
||||
  Insert the node before the entry.
|
||||
|
||||
#### Parameters
|
||||
|
||||
**entry**
|
||||
|
||||
  An existing node in the circular linked list.
|
||||
|
||||
**node**
|
||||
|
||||
  The node to be inserted.
|
||||
|
||||
### `void list_del(struct List *entry)`
|
||||
|
||||
#### Description
|
||||
|
||||
  Remove the node from the list.
|
||||
|
||||
#### Parameters
|
||||
|
||||
**entry**
|
||||
|
||||
  The node to be removed.
|
||||
|
||||
### `list_del_init(struct List *entry)`
|
||||
|
||||
#### Description
|
||||
|
||||
  Remove the node from the list and re-initialize the entry using list_init().
|
||||
|
||||
#### Parameters
|
||||
|
||||
**entry**
|
||||
|
||||
  The node to be removed.
|
||||
|
||||
### `bool list_empty(struct List *entry)`
|
||||
|
||||
#### Description
|
||||
|
||||
  Check if the list is empty.
|
||||
|
||||
#### Parameters
|
||||
|
||||
**entry**
|
||||
|
||||
  A node in the list.
|
||||
|
||||
### `struct List *list_prev(struct List *entry)`
|
||||
|
||||
#### Description
|
||||
|
||||
  Get the previous node of the entry.
|
||||
|
||||
#### Parameters
|
||||
|
||||
**entry**
|
||||
|
||||
  A node in the list.
|
||||
|
||||
### `struct List *list_next(struct List *entry)`
|
||||
|
||||
#### Description
|
||||
|
||||
  Get the next node of the entry.
|
||||
|
||||
#### Parameters
|
||||
|
||||
**entry**
|
||||
|
||||
  A node in the list.
|
||||
|
||||
### `void list_replace(struct List *old, struct List *new)`
|
||||
|
||||
#### Description
|
||||
|
||||
  Replace the old node in the list with the new node.
|
||||
|
||||
#### Parameters
|
||||
|
||||
**old**
|
||||
|
||||
  The node to be removed.
|
||||
|
||||
**new**
|
||||
|
||||
  The new node to be inserted into the list.
|
||||
|
||||
(_translated_label___list_entry_en)=
|
||||
|
||||
### `list_entry(ptr, type, member)`
|
||||
|
||||
#### Description
|
||||
|
||||
  This macro can get the address of the structure that contains the List pointed to by ptr.
|
||||
|
||||
#### Parameters
|
||||
|
||||
**ptr**
|
||||
|
||||
  Pointer to the List structure.
|
||||
|
||||
**type**
|
||||
|
||||
  The type of the structure that contains the List.
|
||||
|
||||
**member**
|
||||
|
||||
  The name of the List structure member in the structure that contains the List.
|
||||
|
||||
### `list_first_entry(ptr, type, member)`
|
||||
|
||||
#### Description
|
||||
|
||||
  Get the first element in the list. Please note that this macro requires the list to be non-empty, otherwise it will cause an error.
|
||||
|
||||
#### Parameters
|
||||
|
||||
  Same as {ref}`list_entry() <_list_entry>`
|
||||
|
||||
### `list_first_entry_or_null(ptr, type, member)`
|
||||
|
||||
#### Description
|
||||
|
||||
  Get the first element in the list. If the list is empty, return NULL.
|
||||
|
||||
#### Parameters
|
||||
|
||||
  Same as {ref}`list_entry() <_list_entry>`
|
||||
|
||||
### `list_last_entry(ptr, type, member)`
|
||||
|
||||
#### Description
|
||||
|
||||
  Get the last element in the list. Please note that this macro requires the list to be non-empty, otherwise it will cause an error.
|
||||
|
||||
#### Parameters
|
||||
|
||||
  Same as {ref}`list_entry() <_list_entry>`
|
||||
|
||||
### `list_last_entry_or_full(ptr, type, member)`
|
||||
|
||||
#### Description
|
||||
|
||||
  Get the last element in the list. If the list is empty, return NULL.
|
||||
|
||||
#### Parameters
|
||||
|
||||
  Same as {ref}`list_entry() <_list_entry>`
|
||||
|
||||
(_translated_label___list_next_entry_en)=
|
||||
### `list_next_entry(pos, member)`
|
||||
|
||||
#### Description
|
||||
|
||||
  Get the next element in the list.
|
||||
|
||||
#### Parameters
|
||||
|
||||
**pos**
|
||||
|
||||
  Pointer to the outer structure.
|
||||
|
||||
**member**
|
||||
|
||||
  The name of the List structure member in the outer structure.
|
||||
|
||||
### `list_prev_entry(pos, member)`
|
||||
|
||||
#### Description
|
||||
|
||||
  Get the previous element in the list.
|
||||
|
||||
#### Parameters
|
||||
|
||||
  Same as {ref}`list_next_entry() <_list_next_entry>`
|
||||
|
||||
(_translated_label___list_for_each_en)=
|
||||
### `list_for_each(ptr, head)`
|
||||
|
||||
#### Description
|
||||
|
||||
  Traverse the entire list (from front to back).
|
||||
|
||||
#### Parameters
|
||||
|
||||
**ptr**
|
||||
|
||||
  Pointer to the List structure.
|
||||
|
||||
**head**
|
||||
|
||||
  Pointer to the head node of the list (struct List*).
|
||||
|
||||
### `list_for_each_prev(ptr, head)`
|
||||
|
||||
#### Description
|
||||
|
||||
  Traverse the entire list (from back to front).
|
||||
|
||||
#### Parameters
|
||||
|
||||
  Same as {ref}`list_for_each() <_list_for_each>`
|
||||
|
||||
(_translated_label___list_for_each_safe_en)=
|
||||
### `list_for_each_safe(ptr, n, head)`
|
||||
|
||||
#### Description
|
||||
|
||||
  Traverse the entire list from front to back (supports deletion of the current list node).
|
||||
|
||||
  This macro uses a temporary variable to prevent errors that may occur during iteration if the current ptr node is deleted.
|
||||
|
||||
#### Parameters
|
||||
|
||||
**ptr**
|
||||
|
||||
  Pointer to the List structure.
|
||||
|
||||
**n**
|
||||
|
||||
  Pointer to store the temporary value (List type).
|
||||
|
||||
**head**
|
||||
|
||||
  Pointer to the head node of the list (struct List*).
|
||||
|
||||
### `list_for_each_prev_safe(ptr, n, head)`
|
||||
|
||||
#### Description
|
||||
|
||||
  Traverse the entire list from back to front (supports deletion of the current list node).
|
||||
|
||||
  This macro uses a temporary variable to prevent errors that may occur during iteration if the current ptr node is deleted.
|
||||
|
||||
#### Parameters
|
||||
|
||||
  Same as {ref}`list_for_each_safe() <_list_for_each_safe>`
|
||||
|
||||
(_translated_label___list_for_each_entry_en)=
|
||||
### `list_for_each_entry(pos, head, member)`
|
||||
|
||||
#### Description
|
||||
|
||||
  Iterate through the list of a given type from the beginning.
|
||||
|
||||
#### Parameters
|
||||
|
||||
**pos**
|
||||
|
||||
  Pointer to a structure of the specific type.
|
||||
|
||||
**head**
|
||||
|
||||
  Pointer to the head node of the list (struct List*).
|
||||
|
||||
**member**
|
||||
|
||||
  The name of the List member in the structure pointed to by pos.
|
||||
|
||||
### `list_for_each_entry_reverse(pos, head, member)`
|
||||
|
||||
#### Description
|
||||
|
||||
  Iterate through the list of a given type in reverse order.
|
||||
|
||||
#### Parameters
|
||||
|
||||
  Same as {ref}`list_for_each_entry() <_list_for_each_entry>`
|
||||
|
||||
### `list_for_each_entry_safe(pos, n, head, member)`
|
||||
|
||||
#### Description
|
||||
|
||||
  Iterate through the list of a given type from the beginning (supports deletion of the current list node).
|
||||
|
||||
#### Parameters
|
||||
|
||||
**pos**
|
||||
|
||||
  Pointer to a structure of the specific type.
|
||||
|
||||
**n**
|
||||
|
||||
  Pointer to store the temporary value (same type as pos).
|
||||
|
||||
**head**
|
||||
|
||||
  Pointer to the head node of the list (struct List*).
|
||||
|
||||
**member**
|
||||
|
||||
  The name of the List member in the structure pointed to by pos.
|
||||
|
||||
### `list_prepare_entry(pos, head, member)`
|
||||
|
||||
#### Description
|
||||
|
||||
  Prepare a 'pos' structure for {ref}`list_for_each_entry_continue() <_list_for_each_entry_continue>`.
|
||||
|
||||
#### Parameters
|
||||
|
||||
**pos**
|
||||
|
||||
  Pointer to a structure of the specific type, used as the starting point for iteration.
|
||||
|
||||
**head**
|
||||
|
||||
  Pointer to the struct List structure to start iteration from.
|
||||
|
||||
**member**
|
||||
|
||||
  The name of the List member in the structure pointed to by pos.
|
||||
|
||||
(_translated_label___list_for_each_entry_continue_en)=
|
||||
### `list_for_each_entry_continue(pos, head, member)`
|
||||
|
||||
#### Description
|
||||
|
||||
  Continue iterating through the list from the next element of the specified position.
|
||||
|
||||
#### Parameters
|
||||
|
||||
**pos**
|
||||
|
||||
  Pointer to a structure of the specific type. This pointer is used as the iteration pointer.
|
||||
|
||||
**head**
|
||||
|
||||
  Pointer to the struct List structure to start iteration from.
|
||||
|
||||
**member**
|
||||
|
||||
  The name of the List member in the structure pointed to by pos.
|
||||
|
||||
### `list_for_each_entry_continue_reverse(pos, head, member)`
|
||||
|
||||
#### Description
|
||||
|
||||
  Iterate through the list in reverse order, starting from the previous element of the specified position.
|
||||
|
||||
#### Parameters
|
||||
|
||||
  Same as {ref}`list_for_each_entry_continue() <_list_for_each_entry_continue>`
|
||||
|
||||
### `list_for_each_entry_from(pos, head, member)`
|
||||
|
||||
#### Description
|
||||
|
||||
  Continue iterating through the list from the specified position.
|
||||
|
||||
#### Parameters
|
||||
|
||||
  Same as {ref}`list_for_each_entry_continue() <_list_for_each_entry_continue>`
|
||||
|
||||
(_translated_label___list_for_each_entry_safe_continue_en)=
|
||||
### `list_for_each_entry_safe_continue(pos, n, head, member)`
|
||||
|
||||
#### Description
|
||||
|
||||
  Continue iterating through the list from the next element of the specified position (supports deletion of the current list node).
|
||||
|
||||
#### Parameters
|
||||
|
||||
**pos**
|
||||
|
||||
  Pointer to a structure of the specific type. This pointer is used as the iteration pointer.
|
||||
|
||||
**n**
|
||||
|
||||
  Pointer to store the temporary value (same type as pos).
|
||||
|
||||
**head**
|
||||
|
||||
  Pointer to the struct List structure to start iteration from.
|
||||
|
||||
**member**
|
||||
|
||||
  The name of the List member in the structure pointed to by pos.
|
||||
|
||||
### `list_for_each_entry_safe_continue_reverse(pos, n, head, member)`
|
||||
|
||||
#### Description
|
||||
|
||||
  Iterate through the list in reverse order, starting from the previous element of the specified position (supports deletion of the current list node).
|
||||
|
||||
#### Parameters
|
||||
|
||||
  Same as {ref}`list_for_each_entry_safe_continue() <_list_for_each_entry_safe_continue>`
|
||||
|
||||
### `list_for_each_entry_safe_from(pos, n, head, member)`
|
||||
|
||||
#### Description
|
||||
|
||||
  Continue iterating through the list from the specified position (supports deletion of the current list node).
|
||||
|
||||
#### Parameters
|
||||
|
||||
  Same as {ref}`list_for_each_entry_safe_continue() <_list_for_each_entry_safe_continue>`
|
||||
|
||||
---
|
||||
|
||||
## Basic C Function Library
|
||||
|
||||
  Kernel programming differs from application layer programming; you will not be able to use functions from LibC. To address this, the kernel implements some commonly used C language functions, trying to make their behavior as close as possible to standard C library functions. It is important to note that the behavior of these functions may differ from standard C library functions, so it is recommended to carefully read the following documentation, which will be helpful to you.
|
||||
|
||||
### String Operations
|
||||
|
||||
#### `int strlen(const char *s)`
|
||||
|
||||
##### Description
|
||||
|
||||
  Measure and return the length of the string.
|
||||
|
||||
##### Parameters
|
||||
|
||||
**src**
|
||||
|
||||
  Source string.
|
||||
|
||||
#### `long strnlen(const char *src, unsigned long maxlen)`
|
||||
|
||||
##### Description
|
||||
|
||||
  Measure and return the length of the string. If the string length is greater than maxlen, return maxlen.
|
||||
|
||||
##### Parameters
|
||||
|
||||
**src**
|
||||
|
||||
  Source string.
|
||||
|
||||
**maxlen**
|
||||
|
||||
  Maximum length.
|
||||
|
||||
#### `long strnlen_user(const char *src, unsigned long maxlen)`
|
||||
|
||||
##### Description
|
||||
|
||||
  Measure and return the length of the string. If the string length is greater than maxlen, return maxlen.
|
||||
|
||||
  This function performs address space validation, requiring the src string to be from user space. If the source string is from kernel space, it will return 0.
|
||||
|
||||
##### Parameters
|
||||
|
||||
**src**
|
||||
|
||||
  Source string, located in user space.
|
||||
|
||||
**maxlen**
|
||||
|
||||
  Maximum length.
|
||||
|
||||
#### `char *strncpy(char *dst, const char *src, long count)`
|
||||
|
||||
##### Description
|
||||
|
||||
  Copy a string of count bytes and return the dst string.
|
||||
|
||||
##### Parameters
|
||||
|
||||
**src**
|
||||
|
||||
  Source string.
|
||||
|
||||
**dst**
|
||||
|
||||
  Destination string.
|
||||
|
||||
**count**
|
||||
|
||||
  Length of the source string to copy.
|
||||
|
||||
#### `char *strcpy(char *dst, const char *src)`
|
||||
|
||||
##### Description
|
||||
|
||||
  Copy the source string and return the dst string.
|
||||
|
||||
##### Parameters
|
||||
|
||||
**src**
|
||||
|
||||
  Source string.
|
||||
|
||||
**dst**
|
||||
|
||||
  Destination string.
|
||||
|
||||
#### `long strncpy_from_user(char *dst, const char *src, unsigned long size)`
|
||||
|
||||
##### Description
|
||||
|
||||
  Copy a string of count bytes from user space to kernel space, and return the size of the copied string.
|
||||
|
||||
  This function performs address space validation to prevent address space overflow issues.
|
||||
|
||||
##### Parameters
|
||||
|
||||
**src**
|
||||
|
||||
  Source string.
|
||||
|
||||
**dst**
|
||||
|
||||
  Destination string.
|
||||
|
||||
**size**
|
||||
|
||||
  Length of the source string to copy.
|
||||
|
||||
#### `int strcmp(char *FirstPart, char *SecondPart)`
|
||||
|
||||
##### Description
|
||||
|
||||
Compare the sizes of two strings.
|
||||
|
||||
***Return Value***
|
||||
|
||||
| Situation | Return Value |
|
||||
| ----------------------- | --- |
|
||||
| FirstPart == SecondPart | 0 |
|
||||
| FirstPart > SecondPart | 1 |
|
||||
| FirstPart < SecondPart | -1 |
|
||||
|
||||
##### Parameters
|
||||
|
||||
**FirstPart**
|
||||
|
||||
  First string.
|
||||
|
||||
**SecondPart**
|
||||
|
||||
  Second string.
|
||||
|
||||
### Memory Operations
|
||||
|
||||
#### `void *memcpy(void *dst, const void *src, uint64_t size)`
|
||||
|
||||
##### Description
|
||||
|
||||
  Copy memory from src to dst.
|
||||
|
||||
##### Parameters
|
||||
|
||||
**dst**
|
||||
|
||||
  Pointer to the destination address.
|
||||
|
||||
**src**
|
||||
|
||||
  Pointer to the source address.
|
||||
|
||||
**size**
|
||||
|
||||
  Size of data to be copied.
|
||||
|
||||
#### `void *memmove(void *dst, const void *src, uint64_t size)`
|
||||
|
||||
##### Description
|
||||
|
||||
  Similar to `memcpy()`, but this function prevents data from being incorrectly overwritten when the source and destination memory regions overlap.
|
||||
|
||||
##### Parameters
|
||||
|
||||
**dst**
|
||||
|
||||
  Pointer to the destination address.
|
||||
|
||||
**src**
|
||||
|
||||
  Pointer to the source address.
|
||||
|
||||
**size**
|
||||
|
||||
  Size of data to be copied.
|
48
docs/locales/en/kernel/core_api/notifier_chain.md
Normal file
48
docs/locales/en/kernel/core_api/notifier_chain.md
Normal file
@ -0,0 +1,48 @@
|
||||
:::{note}
|
||||
**AI Translation Notice**
|
||||
|
||||
This document was automatically translated by `Qwen/Qwen3-8B` model, for reference only.
|
||||
|
||||
- Source document: kernel/core_api/notifier_chain.md
|
||||
|
||||
- Translation time: 2025-05-19 01:41:30
|
||||
|
||||
- Translation model: `Qwen/Qwen3-8B`
|
||||
|
||||
Please report issues via [Community Channel](https://github.com/DragonOS-Community/DragonOS/issues)
|
||||
|
||||
:::
|
||||
|
||||
# Notifier Chain Notification Chain
|
||||
|
||||
## 1. Overview of Principles
|
||||
|
||||
  The notification chain is an event notification mechanism between subsystems within the kernel or between modules within a subsystem. Essentially, a notification chain is a list of event handling functions. Each notification chain is associated with a specific type of event (e.g., reboot event). When a specific event occurs, the corresponding callback functions in the event's notification chain are called, allowing the subsystem/module to respond to the event and perform the appropriate processing.
|
||||
|
||||
  The notification chain is somewhat similar to the subscription mechanism. It can be understood as: there is a "notifier" that maintains a list, and the "subscriber" registers its callback function into this list ("subscriber" can also unregister its callback function). When an event occurs that needs to be notified, the "notifier" traverses all the callback functions in the list and calls them, allowing all registered "subscribers" to respond and handle the event accordingly.
|
||||
|
||||
## 2. Core Features
|
||||
|
||||
### 2.1 Registering Callback Functions
|
||||
|
||||
  The callback function is encapsulated into a specific structure and registered into the designated notification chain. The related method is `register`, which is used by the "subscriber".
|
||||
|
||||
### 2.2 Unregistering Callback Functions
|
||||
|
||||
  The callback function is removed from the designated notification chain, i.e., it is deleted from the notification chain. The related method is `unregister`, which is used by the "subscriber".
|
||||
|
||||
### 2.3 Event Notification
|
||||
|
||||
  When an event occurs, the notification chain related to that event performs the event notification through this method. `call_chain` This method traverses all elements in the notification chain and calls the registered callback functions in sequence. This method is used by the "notifier".
|
||||
|
||||
## 3. Types of Notification Chains
|
||||
|
||||
  Each type of notification chain has corresponding `register`, `unregister`, and `call_chain` interfaces, with functions as described in the core features above.
|
||||
|
||||
- `AtomicNotifierChain`: Atomic notification chain, cannot sleep, recommended for use in interrupt context.
|
||||
- `BlockingNotifierChain`: Blocking notification chain, can sleep, recommended for use in process context.
|
||||
- `RawNotifierChain`: Raw notification chain, the caller is responsible for thread safety.
|
||||
|
||||
## 4. Other Issues
|
||||
|
||||
  `BlockingNotifierChain` does not currently support the sleeping functionality.
|
178
docs/locales/en/kernel/core_api/softirq.md
Normal file
178
docs/locales/en/kernel/core_api/softirq.md
Normal file
@ -0,0 +1,178 @@
|
||||
:::{note}
|
||||
**AI Translation Notice**
|
||||
|
||||
This document was automatically translated by `Qwen/Qwen3-8B` model, for reference only.
|
||||
|
||||
- Source document: kernel/core_api/softirq.md
|
||||
|
||||
- Translation time: 2025-05-19 01:41:38
|
||||
|
||||
- Translation model: `Qwen/Qwen3-8B`
|
||||
|
||||
Please report issues via [Community Channel](https://github.com/DragonOS-Community/DragonOS/issues)
|
||||
|
||||
:::
|
||||
|
||||
# Soft Interrupt
|
||||
|
||||
  Software interrupt, also known as the bottom half of an interrupt, is used to delay the processing of work that was not completed by the hard interrupt (the top half of the interrupt). Dividing the interrupt into two stages can effectively solve the problems of long interrupt handling time and interrupt loss.
|
||||
|
||||
## 1. Design Philosophy
|
||||
|
||||
  Each CPU has its own pending status. Soft interrupts are "initiated by which CPU, executed by which CPU", and the pending status of each CPU is not shared. The same soft interrupt vector can run concurrently on multiple cores.
|
||||
|
||||
  When we need to register a new soft interrupt, we need to implement the `SoftirqVec` feature for the soft interrupt handler, and then call the `register_softirq` function to register the soft interrupt handler within the soft interrupt mechanism.
|
||||
|
||||
  Please note that due to the reentrancy and concurrency of soft interrupts, the soft interrupt handler must ensure thread safety itself.
|
||||
|
||||
## 2. Soft Interrupt Vector Number
|
||||
|
||||
```rust
|
||||
pub enum SoftirqNumber {
|
||||
/// 时钟软中断信号
|
||||
TIMER = 0,
|
||||
/// 帧缓冲区刷新软中断
|
||||
VideoRefresh = 1,
|
||||
}
|
||||
```
|
||||
|
||||
## 3. Soft Interrupt API
|
||||
|
||||
### 3.1. SoftirqVec Feature
|
||||
|
||||
```rust
|
||||
pub trait SoftirqVec: Send + Sync + Debug {
|
||||
fn run(&self);
|
||||
}
|
||||
```
|
||||
|
||||
  The feature that the soft interrupt handler needs to implement. It needs to implement the `run` function to handle the soft interrupt. When the soft interrupt is executed, the `run` function will be called.
|
||||
|
||||
### 3.2. Softirq API
|
||||
|
||||
#### 3.2.1. Register Soft Interrupt Vector
|
||||
|
||||
```rust
|
||||
pub fn register_softirq(&self,
|
||||
softirq_num: SoftirqNumber,
|
||||
handler: Arc<dyn SoftirqVec>,
|
||||
) -> Result<i32, SystemError>
|
||||
```
|
||||
|
||||
- Parameters:
|
||||
|
||||
- softirq_num: Interrupt vector number
|
||||
|
||||
- handler: The structure corresponding to the interrupt function, which needs to point to a structure variable that implements the `SoftirqVec` feature
|
||||
|
||||
- Return:
|
||||
|
||||
- Ok(i32): 0
|
||||
|
||||
- Err(SystemError): Error code
|
||||
|
||||
#### 3.2.2. Unregister Soft Interrupt Vector
|
||||
|
||||
```rust
|
||||
pub fn unregister_softirq(&self, softirq_num: SoftirqNumber)
|
||||
```
|
||||
|
||||
- Parameters:
|
||||
|
||||
- softirq_num: Interrupt vector number
|
||||
|
||||
#### 3.2.3. Execute Soft Interrupt
|
||||
|
||||
```rust
|
||||
pub fn do_softirq(&self)
|
||||
```
|
||||
|
||||
- Purpose: Execute the soft interrupt function (**only called after hard interrupt execution**)
|
||||
|
||||
#### 3.2.4. Clear the Pending Flag of Soft Interrupt
|
||||
|
||||
```rust
|
||||
pub unsafe fn clear_softirq_pending(&self, softirq_num: SoftirqNumber)
|
||||
```
|
||||
|
||||
- Purpose: Clear the pending flag of the specified soft interrupt on the current CPU. Please note that this function is unsafe because it directly modifies the pending flag without locking.
|
||||
|
||||
- Parameters:
|
||||
|
||||
- softirq_num: Interrupt vector number
|
||||
|
||||
#### 3.2.5. Mark Soft Interrupt as to be Executed
|
||||
|
||||
```rust
|
||||
pub fn raise_softirq(&self, softirq_num: SoftirqNumber)
|
||||
```
|
||||
|
||||
- Purpose: Mark the specified soft interrupt as to be executed on the current CPU
|
||||
|
||||
- Parameters:
|
||||
|
||||
- softirq_num: Interrupt vector number
|
||||
|
||||
### 3.3. Usage Example
|
||||
|
||||
```rust
|
||||
#[derive(Debug)]
|
||||
/// SoftirqExample中断结构体
|
||||
pub struct SoftirqExample {
|
||||
running: AtomicBool,
|
||||
}
|
||||
/// SoftirqExample中断需要处理的逻辑
|
||||
fn softirq_example_func() {
|
||||
println!("addressed SoftirqExample");
|
||||
}
|
||||
impl SoftirqVec for SoftirqExample {
|
||||
fn run(&self) {
|
||||
if self.set_run() == false {
|
||||
return;
|
||||
}
|
||||
|
||||
softirq_example_func();
|
||||
|
||||
self.clear_run();
|
||||
}
|
||||
}
|
||||
impl SoftirqExample {
|
||||
pub fn new() -> SoftirqExample {
|
||||
SoftirqExample {
|
||||
running: AtomicBool::new(false),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_run(&self) -> bool {
|
||||
let x = self
|
||||
.running
|
||||
.compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed);
|
||||
if x.is_ok() {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
fn clear_run(&self) {
|
||||
self.running.store(false, Ordering::Release);
|
||||
}
|
||||
}
|
||||
fn main() {
|
||||
let softirq_example = Arc::new(SoftirqExample::new());
|
||||
let softirq_num = 2;
|
||||
// 注册SoftirqExample中断
|
||||
softirq_vectors()
|
||||
.register_softirq(SoftirqNumber::from(softirq_num as u64), softirq_example)
|
||||
.expect("failed to register SoftirqExample");
|
||||
|
||||
// 标志SoftirqExample中断需要执行
|
||||
softirq_vectors().raise_softirq(SoftirqNumber::from(softirq_num as u64));
|
||||
|
||||
// 标志SoftirqExample中断不需要执行
|
||||
softirq_vectors().clear_softirq_pending(SoftirqNumber::from(softirq_num as u64));
|
||||
|
||||
// 解注册SoftirqExample中断
|
||||
softirq_vectors().unregister_softirq(SoftirqNumber::from(softirq_num as u64));
|
||||
}
|
||||
```
|
Reference in New Issue
Block a user