refactor(all): The previous writing is not good so all refactoring.

This commit is contained in:
MacRsh
2025-02-04 22:55:53 +08:00
parent 967b18db25
commit 76e7efce33
38 changed files with 1794 additions and 1315 deletions

View File

@@ -9,6 +9,8 @@
#ifndef __MR_HW_IRQ_H__
#define __MR_HW_IRQ_H__
#include <libc/mr_types.h>
#ifdef __cplusplus
"C" {
#endif /* __cplusplus */

View File

@@ -1,73 +0,0 @@
/**
* @copyright (c) 2024, MacRsh
*
* @license SPDX-License-Identifier: Apache-2.0
*
* @date 2024-09-06 MacRsh First version
*/
#ifndef __MR_CLOCK_H__
#define __MR_CLOCK_H__
#include <libc/mr_errno.h>
#include <libc/mr_types.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @addtogroup Clock
* @{
*/
/* Clock type */
typedef mr_uint32_t mr_clock_t;
typedef mr_clock_t mr_tick_t;
#define MR_CLOCK_MAX MR_UINT32_MAX
#define MR_TICK_MAX MR_CLOCK_MAX
/**
* @brief This function increases the kclock.
*
* @param clock The clock to increase.
*/
void mr_clock_increase(mr_clock_t clock);
/**
* @brief This function gets the kclock.
*
* @return The kclock.
*/
mr_clock_t mr_clock_get(void);
/**
* @brief This function sets the kclock.
*
* @param clock The kclock to clock.
*/
void mr_clock_set(mr_clock_t clock);
/**
* @brief This function adds a hooks to the kclock.
*
* @param index The index of the hooks(auto: '-1').
* @param hook The hooks to add.
* @return The index on success, or a negative error code on failure.
*/
int mr_clock_hook_add(int index, void (*hook)(void));
/**
* @brief This function deletes a hooks from the kclock.
*
* @param index The index of the hooks.
*/
void mr_clock_hook_del(int index);
/** @} */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __MR_CLOCK_H__ */

View File

@@ -1,86 +0,0 @@
/**
* @copyright (c) 2024, MacRsh
*
* @license SPDX-License-Identifier: Apache-2.0
*
* @date 2024-09-06 MacRsh First version
*/
#ifndef __MR_HOOKS_H__
#define __MR_HOOKS_H__
#include <kernel/mr_spinlock.h>
#include <libc/mr_errno.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @addtogroup Hook
* @{
*/
/* Hooks type */
typedef struct mr_hooks {
mr_spinlock_t lock;
mr_ptr_t *hook;
mr_size_t size;
} mr_hooks_t;
/**
* @brief This macro function initialize a hooks.
*
* @param _hooks The hooks.
* @param _size The size of the hook pointers.
*/
#define MR_HOOKS_INIT(_hooks, _size) \
{ MR_SPINLOCK_INIT(), (_hooks), (_size) }
/**
* @brief This function initialize a hooks.
*
* @param hooks The hooks.
* @param hook The hook pointers.
* @param size The size of the hook pointers.
*
* @note The size is the number of the hook pointers.
*/
void mr_hooks_init(mr_hooks_t *hooks, mr_ptr_t *hook, mr_size_t size);
/**
* @brief This function add a hook.
*
* @param hooks The hooks.
* @param index The index of the hook(auto: '-1').
* @param hook The hook.
* @return The index on success, or a negative error code on failure.
*/
int mr_hooks_add(mr_hooks_t *hooks, int index, mr_ptr_t hook);
/**
* @brief This function delete a hook.
*
* @param hooks The hooks.
* @param index The index of the hook.
*/
void mr_hooks_del(mr_hooks_t *hooks, int index);
/**
* @brief This macro function iterates through the hooks.
*
* @param _i The index.
* @param _hooks The hooks.
* @param _hook The hook.
*/
#define MR_HOOKS_EACH(_i, _hooks, _hook) \
for ((_i) = 0, (_hook) = (_hooks)->hook[(_i)]; (_i) < (_hooks)->size; \
(_i)++, (_hook) = (_hooks)->hook[(_i)])
/** @} */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __MR_HOOKS_H__ */

View File

@@ -9,7 +9,7 @@
#ifndef __MR_INITCALL_H__
#define __MR_INITCALL_H__
#include <kernel/mr_compiler.h>
#include <libc/mr_compiler.h>
#ifdef __cplusplus
extern "C" {
@@ -27,19 +27,19 @@ extern "C" {
/* Initcall type */
typedef struct mr_initcall {
const char *name;
void (*fn)(void);
void (*entry)(void);
} mr_initcall_t;
/**
* @brief This macro function defines an initcall.
*
* @param _fn The function of the initcall.
* @param _entry The function of the initcall.
* @param _level The level of the initcall.
*/
#define MR_INIT_EXPORT(_fn, _level) \
MR_USED const mr_initcall_t __mr_initcall_##_fn MR_SECTION( \
#define MR_INIT_EXPORT(_entry, _level) \
MR_USED const mr_initcall_t __mr_initcall_##_entry MR_SECTION( \
"mr_initcall." _level) \
= {#_fn, _fn}
= {.name = #_entry, .entry = (_entry)}
/**
* @brief This function does initcalls(kernel).

View File

@@ -0,0 +1,56 @@
/**
* @copyright (c) 2024, MacRsh
*
* @license SPDX-License-Identifier: Apache-2.0
*
* @date 2024-09-06 MacRsh First version
*/
#ifndef __MR_KCLOCK_H__
#define __MR_KCLOCK_H__
#include <libc/mr_errno.h>
#include <libc/mr_types.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @addtogroup Kclock
* @{
*/
/* Clock type */
typedef mr_uint32_t mr_tick_t;
#define MR_TICK_MAX MR_UINT32_MAX
/**
* @brief This function increases the clock tick.
*
* @param tick The tick to increase.
*/
void mr_kclock_increase(mr_tick_t tick);
/**
* @brief This function gets the clock tick.
*
* @return The tick.
*/
mr_tick_t mr_kclock_tick(void);
/**
* @brief This function adds a hook to the clock.
*
* @param entry The hook entry.
* @return 0 on success, or a negative error code on failure.
*/
mr_err_t mr_kclock_hook_add(void (*entry)(void));
/** @} */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __MR_KCLOCK_H__ */

160
include/kernel/mr_kfifo.h Normal file
View File

@@ -0,0 +1,160 @@
/**
* @copyright (c) 2024, MacRsh
*
* @license SPDX-License-Identifier: Apache-2.0
*
* @date 2024-09-06 MacRsh First version
*/
#ifndef __MR_KFIFO_H__
#define __MR_KFIFO_H__
#include <kernel/mr_kservice.h>
#include <libc/mr_compiler.h>
#include <libc/mr_types.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @addtogroup Kfifo
* @{
*/
/* Kfifo type */
typedef struct mr_kfifo {
mr_uint8_t *buf;
mr_uint32_t size;
mr_uint32_t in;
mr_uint32_t out;
} mr_kfifo_t;
/**
* @brief This function initializes a kfifo.
*
* @param kfifo The kfifo to initialize.
* @param buf The buffer of the kfifo.
* @param size The size of the kfifo.
*/
void mr_kfifo_init(mr_kfifo_t *kfifo, void *buf, mr_uint32_t size);
/**
* @brief This function puts data into a kfifo.
*
* @param kfifo The kfifo to put data into.
* @param buf The data to put into the kfifo.
* @param size The size of the data.
* @return The number of bytes put into the kfifo.
*/
mr_uint32_t mr_kfifo_in(mr_kfifo_t *kfifo, const void *buf, mr_uint32_t size);
/**
* @brief This function takes data out of a kfifo.
*
* @param kfifo The kfifo to take data out of.
* @param buf The data to take out of the kfifo.
* @param size The size of the data.
* @return The number of bytes taken out of the kfifo.
*/
mr_uint32_t mr_kfifo_out(mr_kfifo_t *kfifo, void *buf, mr_uint32_t size);
/**
* @brief This function puts data into a kfifo, overwriting old data.
*
* @param kfifo The kfifo to put data into.
* @param buf The data to put into the kfifo.
* @param size The size of the data.
* @return The number of bytes put into the kfifo.
*/
mr_uint32_t mr_kfifo_in_overwrite(mr_kfifo_t *kfifo, const void *buf,
mr_uint32_t size);
/**
* @brief This function peeks data out of a kfifo.
*
* @param kfifo The kfifo to peek data out of.
* @param buf The data to peek out of the kfifo.
* @param size The size of the data.
* @return The number of bytes peeked out of the kfifo.
*/
mr_uint32_t mr_kfifo_peek(mr_kfifo_t *kfifo, void *buf, mr_uint32_t size);
/**
* @brief This function gets the size of a kfifo.
*
* @param kfifo The kfifo to get the size of.
* @return The size of the kfifo.
*/
MR_INLINE mr_uint32_t mr_kfifo_size(mr_kfifo_t *kfifo) {
return kfifo->size;
}
/**
* @brief This function gets the number of available space bytes in a kfifo.
*
* @param kfifo The kfifo to get the number of available space bytes in.
* @return The number of available space bytes in the kfifo.
*/
MR_INLINE mr_uint32_t mr_kfifo_avail(mr_kfifo_t *kfifo) {
return kfifo->size - (kfifo->in - kfifo->out);
}
/**
* @brief This function gets the number of data bytes in a kfifo.
*
* @param kfifo The kfifo to get the number of data bytes in.
* @return The number of data bytes in the kfifo.
*/
MR_INLINE mr_uint32_t mr_kfifo_len(mr_kfifo_t *kfifo) {
return kfifo->in - kfifo->out;
}
/**
* @brief This function resets a kfifo.
*
* @param kfifo The kfifo to reset.
*/
MR_INLINE void mr_kfifo_reset(mr_kfifo_t *kfifo) {
kfifo->in = kfifo->out = 0;
}
/**
* @brief This function skips data in a kfifo.
*
* @param kfifo The kfifo to skip data in.
* @param size The size of the data to skip.
* @return The number of bytes skipped.
*/
MR_INLINE mr_uint32_t mr_kfifo_skip(mr_kfifo_t *kfifo, mr_uint32_t size) {
kfifo->out += MR_MIN(size, mr_kfifo_len(kfifo));
return size;
}
/**
* @brief This function checks if a kfifo is empty.
*
* @param kfifo The kfifo to check.
* @return MR_TRUE if the kfifo is empty, MR_FALSE otherwise.
*/
MR_INLINE mr_bool_t mr_kfifo_is_empty(mr_kfifo_t *kfifo) {
return (kfifo->in == kfifo->out) ? MR_TRUE : MR_FALSE;
}
/**
* @brief This function checks if a kfifo is full.
*
* @param kfifo The kfifo to check.
* @return MR_TRUE if the kfifo is full, MR_FALSE otherwise.
*/
MR_INLINE mr_bool_t mr_kfifo_is_full(mr_kfifo_t *kfifo) {
return (kfifo->in == (kfifo->out + kfifo->size)) ? MR_TRUE : MR_FALSE;
}
/** @} */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __MR_KFIFO_H__ */

81
include/kernel/mr_khook.h Normal file
View File

@@ -0,0 +1,81 @@
/**
* @copyright (c) 2024, MacRsh
*
* @license SPDX-License-Identifier: Apache-2.0
*
* @date 2024-09-06 MacRsh First version
*/
#ifndef __MR_KHOOK_H__
#define __MR_KHOOK_H__
#include "mr_spinlock.h"
#include <libc/mr_errno.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @addtogroup Khook
* @{
*/
/* Khook type */
typedef struct mr_khook {
mr_spinlock_t lock;
mr_ptr_t *entry;
mr_size_t size;
mr_size_t next;
} mr_khook_t;
/**
* @brief This macro function initialize a hook.
*
* @param _entry The hook entry.
* @param _size The size of the entry pointers.
*/
#define MR_KHOOK_INIT(_entry, _size) \
{ \
.lock = MR_SPINLOCK_INIT(), .entry = (_entry), .size = (_size), \
.next = 0 \
}
/**
* @brief This function initialize a khook.
*
* @param khook The khook.
* @param entry The entry pointers.
* @param size The size of the entry pointers.
*
* @note The size is the number of the entry pointers.
*/
void mr_khook_init(mr_khook_t *khook, mr_ptr_t *entry, mr_size_t size);
/**
* @brief This function add a entry to the khook.
*
* @param khook The khook.
* @param entry The entry.
* @returns 0 on success, or a negative error code on failure.
*/
mr_err_t mr_khook_add(mr_khook_t *khook, mr_ptr_t entry);
/**
* @brief This macro function iterates through the hook.
*
* @param _i The index.
* @param _entry The entry.
* @param _hook The hook.
*/
#define MR_KHOOK_EACH(_i, _entry, _hook) \
for ((_i) = 0, (_entry) = (_hook)->entry[(_i)]; (_i) < (_hook)->next; \
(_i)++, (_entry) = (_hook)->entry[(_i)])
/** @} */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __MR_KHOOK_H__ */

View File

@@ -6,10 +6,11 @@
* @date 2024-09-06 MacRsh First version
*/
#ifndef __MR_LIST_H__
#define __MR_LIST_H__
#ifndef __MR_KLIST_H__
#define __MR_KLIST_H__
#include <kernel/mr_service.h>
#include <kernel/mr_kservice.h>
#include <libc/mr_compiler.h>
#include <libc/mr_types.h>
#ifdef __cplusplus
@@ -17,30 +18,30 @@ extern "C" {
#endif /* __cplusplus */
/**
* @addtogroup List
* @addtogroup Klist
* @{
*/
/* Double list type */
typedef struct mr_list {
struct mr_list *next;
struct mr_list *prev;
} mr_list_t;
typedef struct mr_klist {
struct mr_klist *next;
struct mr_klist *prev;
} mr_klist_t;
/**
* @brief This macro function initializes a list.
*
* @param _list The list to initialize.
* @param _klist The list to initialize.
*/
#define MR_LIST_INIT(_list) \
{ &(_list), &(_list) }
#define MR_KLIST_INIT(_klist) \
{ .next = (_klist), .prev = (_klist) }
/**
* @brief This function initializes a list.
*
* @param entry The element to initialize.
*/
MR_INLINE void mr_list_init(mr_list_t *entry) {
MR_INLINE void mr_klist_init(mr_klist_t *entry) {
entry->next = entry->prev = entry;
}
@@ -49,8 +50,10 @@ MR_INLINE void mr_list_init(mr_list_t *entry) {
*
* @param head The list head.
* @param entry The element to add.
*
* @note Adds to the end of the list.
*/
MR_INLINE void mr_list_add(mr_list_t *head, mr_list_t *entry) {
MR_INLINE void mr_klist_add(mr_klist_t *head, mr_klist_t *entry) {
head->prev->next = entry;
entry->prev = head->prev;
head->prev = entry;
@@ -58,12 +61,14 @@ MR_INLINE void mr_list_add(mr_list_t *head, mr_list_t *entry) {
}
/**
* @brief This function adds an element to the head of the list.
* @brief This function inserts an element into the list.
*
* @param head The list head.
* @param entry The element to add.
* @param entry The element to insert.
*
* @note Inserts to the beginning of the list.
*/
MR_INLINE void mr_list_add_head(mr_list_t *head, mr_list_t *entry) {
MR_INLINE void mr_klist_insert(mr_klist_t *head, mr_klist_t *entry) {
head->next->prev = entry;
entry->next = head->next;
head->next = entry;
@@ -75,7 +80,7 @@ MR_INLINE void mr_list_add_head(mr_list_t *head, mr_list_t *entry) {
*
* @param entry The element to remove.
*/
MR_INLINE void mr_list_del(mr_list_t *entry) {
MR_INLINE void mr_klist_del(mr_klist_t *entry) {
entry->prev->next = entry->next;
entry->next->prev = entry->prev;
entry->next = entry->prev = entry;
@@ -87,7 +92,7 @@ MR_INLINE void mr_list_del(mr_list_t *entry) {
* @param new The new element.
* @param old The old element.
*/
MR_INLINE void mr_list_replace(mr_list_t *new, mr_list_t *old) {
MR_INLINE void mr_klist_replace(mr_klist_t *new, mr_klist_t *old) {
new->next = old->next;
new->next->prev = new;
new->prev = old->prev;
@@ -101,16 +106,16 @@ MR_INLINE void mr_list_replace(mr_list_t *new, mr_list_t *old) {
* @param entry1 The first element.
* @param entry2 The second element.
*/
MR_INLINE void mr_list_swap(mr_list_t *entry1, mr_list_t *entry2) {
mr_list_t *tmp;
MR_INLINE void mr_klist_swap(mr_klist_t *entry1, mr_klist_t *entry2) {
mr_klist_t *tmp;
tmp = entry2->prev;
mr_list_del(entry2);
mr_list_replace(entry1, entry2);
mr_klist_del(entry2);
mr_klist_replace(entry1, entry2);
if (tmp == entry1) {
tmp = entry2;
}
mr_list_add(tmp, entry1);
mr_klist_add(tmp, entry1);
}
/**
@@ -118,21 +123,12 @@ MR_INLINE void mr_list_swap(mr_list_t *entry1, mr_list_t *entry2) {
*
* @param entry The element to move.
* @param head The list head.
*/
MR_INLINE void mr_list_move(mr_list_t *entry, mr_list_t *head) {
mr_list_del(entry);
mr_list_add(head, entry);
}
/**
* @brief This function moves an element to the head of the list.
*
* @param entry The element to move.
* @param head The list head.
* @note Move to the end of the list.
*/
MR_INLINE void mr_list_move_head(mr_list_t *entry, mr_list_t *head) {
mr_list_del(entry);
mr_list_add_head(head, entry);
MR_INLINE void mr_klist_move(mr_klist_t *entry, mr_klist_t *head) {
mr_klist_del(entry);
mr_klist_add(head, entry);
}
/**
@@ -141,52 +137,8 @@ MR_INLINE void mr_list_move_head(mr_list_t *entry, mr_list_t *head) {
* @param head The list head.
* @return MR_TRUE on empty, MR_FALSE otherwise.
*/
MR_INLINE mr_bool_t mr_list_is_empty(mr_list_t *head) {
return head->next == head ? MR_TRUE : MR_FALSE;
}
/**
* @brief This function rotates the list to the left.
*
* @param head The list head.
*/
MR_INLINE void mr_list_rotate_left(mr_list_t *head) {
mr_list_t *tmp;
if (!mr_list_is_empty(head)) {
tmp = head->next;
mr_list_move_head(tmp, head);
}
}
/**
* @brief This function rotates the list to the right.
*
* @param head The list head.
*/
MR_INLINE void mr_list_rotate_right(mr_list_t *head) {
mr_list_t *tmp;
if (!mr_list_is_empty(head)) {
tmp = head->prev;
mr_list_move(tmp, head);
}
}
/**
* @brief This function splices a list into another list.
*
* @param list The list to splice.
* @param head The list head.
*/
MR_INLINE void mr_list_splice(mr_list_t *list, mr_list_t *head) {
mr_list_t *tmp;
tmp = head->prev;
head->prev->next = list;
head->prev = list->prev;
list->prev->next = head;
list->prev = tmp;
MR_INLINE mr_bool_t mr_klist_is_empty(mr_klist_t *head) {
return (head->next == head) ? MR_TRUE : MR_FALSE;
}
/**
@@ -197,7 +149,7 @@ MR_INLINE void mr_list_splice(mr_list_t *list, mr_list_t *head) {
* @param _member The member of the element.
* @return The container of the element.
*/
#define MR_LIST_ENTRY(_ptr, _type, _member) \
#define MR_KLIST_ENTRY(_ptr, _type, _member) \
MR_CONTAINER_OF(_ptr, _type, _member)
/**
@@ -206,7 +158,7 @@ MR_INLINE void mr_list_splice(mr_list_t *list, mr_list_t *head) {
* @param _pos The pointer to the element.
* @param _head The list head.
*/
#define MR_LIST_FOR_EACH(_pos, _head) \
#define MR_KLIST_FOR_EACH(_pos, _head) \
for ((_pos) = (_head)->next; (_pos) != (_head); (_pos) = (_pos)->next)
/**
@@ -216,7 +168,7 @@ MR_INLINE void mr_list_splice(mr_list_t *list, mr_list_t *head) {
* @param _n The pointer to the next element.
* @param _head The list head.
*/
#define MR_LIST_FOR_EACH_SAFE(_pos, _n, _head) \
#define MR_KLIST_FOR_EACH_SAFE(_pos, _n, _head) \
for ((_pos) = (_head)->next, (_n) = (_pos)->next; (_pos) != (_head); \
(_pos) = (_n), (_n) = (_pos)->next)
@@ -226,4 +178,4 @@ MR_INLINE void mr_list_splice(mr_list_t *list, mr_list_t *head) {
}
#endif /* __cplusplus */
#endif /* __MR_LIST_H__ */
#endif /* __MR_KLIST_H__ */

120
include/kernel/mr_kmap.h Normal file
View File

@@ -0,0 +1,120 @@
/**
* @copyright (c) 2024, MacRsh
*
* @license SPDX-License-Identifier: Apache-2.0
*
* @date 2024-09-06 MacRsh First version
*/
#ifndef __MR_KMAP_H__
#define __MR_KMAP_H__
#include <libc/mr_compiler.h>
#include <libc/mr_errno.h>
#include <libc/mr_types.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @addtogroup Kmap
* @{
*/
/* Knode type */
typedef struct mr_knode {
mr_uint32_t key;
void *value;
struct mr_knode *next;
} mr_knode_t;
/* Kmap type */
typedef struct mr_kmap {
mr_knode_t **b;
mr_size_t size;
mr_size_t count;
mr_f32_t load_factor;
} mr_kmap_t;
/**
* @brief This function initializes a kmap.
*
* @param kmap The kmap to initialize.
* @param size The size of the kmap.
* @param load_factor The load factor of the kmap.
* @return 0 on success, or a negative error code on failure.
*/
mr_err_t mr_kmap_init(mr_kmap_t *kmap, mr_size_t size, mr_f32_t load_factor);
/**
* @brief This function adds a key-value pair to the kmap.
*
* @param kmap The kmap to add the key-value pair to.
* @param key The key to add.
* @param value The value to add.
* @return 0 on success, or a negative error code on failure.
*/
mr_err_t mr_kmap_add(mr_kmap_t *kmap, mr_uint32_t key, void *value);
/**
* @brief This function deletes a key-value pair from the kmap.
*
* @param kmap The kmap to delete the key-value pair from.
* @param key The key to delete.
* @return The value of the deleted key-value pair, or MR_NULL if not found.
*/
void *mr_kmap_del(mr_kmap_t *kmap, mr_uint32_t key);
/**
* @brief This function gets the value of a key from the kmap.
*
* @param kmap The kmap to get the value from.
* @param key The key to get the value of.
* @return The value of the key, or MR_NULL if not found.
*/
void *mr_kmap_value(mr_kmap_t *kmap, mr_uint32_t key);
/**
* @brief This function clears the kmap.
*
* @param kmap The kmap to clear.
*/
void mr_kmap_clear(mr_kmap_t *kmap);
/**
* @brief This function shrinks the kmap.
*
* @param kmap The kmap to shrink.
* @param size The new size of the kmap.
* @return 0 on success, or a negative error code on failure.
*/
mr_err_t mr_kmap_shrink(mr_kmap_t *kmap, mr_size_t size);
/**
* @brief This function gets the size of the kmap.
*
* @param kmap The kmap to get the size of.
* @return The size of the kmap.
*/
MR_INLINE mr_size_t mr_kmap_count(mr_kmap_t *kmap) {
return kmap->count;
}
/**
* @brief This function checks if the kmap is empty.
*
* @param kmap The kmap to check.
* @return MR_TRUE if the kmap is empty, MR_FALSE otherwise.
*/
MR_INLINE mr_bool_t mr_kmap_is_empty(mr_kmap_t *kmap) {
return (kmap->count == 0) ? MR_TRUE : MR_FALSE;
}
/** @} */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __MR_KMAP_H__ */

View File

@@ -9,8 +9,8 @@
#ifndef __MR_KOBJECT_H__
#define __MR_KOBJECT_H__
#include <kernel/mr_list.h>
#include <kernel/mr_lockref.h>
#include <kernel/mr_klist.h>
#include <kernel/mr_kref.h>
#include <libc/mr_errno.h>
#ifdef __cplusplus
@@ -49,9 +49,9 @@ typedef struct mr_kobject {
char iname[MR_CFG_KOBJECT_INAME_SIZE];
struct mr_kobject *parent;
mr_ktype_t *type;
mr_lockref_t ref;
mr_list_t entry;
mr_list_t list;
mr_klist_t entry;
mr_klist_t list;
mr_kref_t ref;
} mr_kobject_t;
/* Kset type */
@@ -84,10 +84,10 @@ void mr_ktype_init(mr_ktype_t *type, void (*release)(mr_kobject_t *));
#define MR_KOBJECT_INIT(_kobj, _type) \
{ \
.magic = MR_KOBJECT_MAGIC, \
.name = {.str = (_kobj).iname, .len = 0, .hash = 0}, \
.parent = &(_kobj), .type = (_type), .ref = MR_LOCKREF_INIT(), \
.entry = MR_LIST_INIT((_kobj).entry), \
.list = MR_LIST_INIT((_kobj).list) \
.name = {.str = (_kobj)->iname, .len = 0, .hash = 0}, \
.parent = (_kobj), .type = (_type), \
.entry = MR_KLIST_INIT(&(_kobj)->entry), \
.list = MR_KLIST_INIT(&(_kobj)->list), .ref = MR_KREF_INIT() \
}
/**
@@ -127,6 +127,16 @@ mr_err_t mr_kobject_add(mr_kobject_t *kobj, mr_kobject_t *parent,
*/
void mr_kobject_del(mr_kobject_t *kobj);
/**
* @brief This function looks up a kobject.
*
* @param parent The parent kobject.
* @param fmt The format string(path).
* @param ... The format arguments.
* @return The kobject on success, or MR_NULL on failure.
*/
mr_kobject_t *mr_kobject_lookup(mr_kobject_t *parent, const char *fmt, ...);
/**
* @brief This function gets a kobject.
*
@@ -142,6 +152,22 @@ mr_kobject_t *mr_kobject_get(mr_kobject_t *kobj);
*/
void mr_kobject_put(mr_kobject_t *kobj);
/**
* @brief This macro function gets the name of a kobject.
*
* @param _kobj The kobject.
* @return The name of the kobject.
*/
#define MR_KOBJECT_NAME(_kobj) (((mr_kobject_t *)(_kobj))->name.str)
/**
* @brief This macro function gets the parent of a kobject.
*
* @param _kobj The kobject.
* @return The parent of the kobject.
*/
#define MR_KOBJECT_PARENT(_kobj) (((mr_kobject_t *)(_kobj))->parent)
/**
* @brief This macro function initializes a kset.
*
@@ -149,9 +175,7 @@ void mr_kobject_put(mr_kobject_t *kobj);
* @param _type The ktype.
*/
#define MR_KSET_INIT(_kset, _type) \
{ \
.parent = MR_KOBJECT_INIT((_kset).parent, (_type)) \
}
{ .parent = MR_KOBJECT_INIT(&(_kset)->parent, (_type)) }
/**
* @brief This function initializes a kset.
@@ -170,6 +194,14 @@ void mr_kset_init(mr_kset_t *kset, mr_ktype_t *type);
*/
mr_err_t mr_kset_register(mr_kset_t *kset, const char *name);
/**
* @brief This function finds a kset.
*
* @param name The name.
* @returns The kset on success, or MR_NULL on failure.
*/
mr_kset_t *mr_kset_find(const char *name);
/** @} */
#ifdef __cplusplus

View File

@@ -0,0 +1,38 @@
/**
* @copyright (c) 2024, MacRsh
*
* @license SPDX-License-Identifier: Apache-2.0
*
* @date 2024-09-06 MacRsh First version
*/
#ifndef __MR_KPRINTF_H__
#define __MR_KPRINTF_H__
#include <libc/mr_stdio.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @addtogroup Kprintf
* @{
*/
/**
* @brief This function prints a formatted string.
*
* @param fmt The format string.
* @param ... The arguments.
* @return The number of characters printed.
*/
int mr_kprintf(const char *fmt, ...);
/** @} */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __MR_KPRINTF_H__ */

73
include/kernel/mr_kref.h Normal file
View File

@@ -0,0 +1,73 @@
/**
* @copyright (c) 2024, MacRsh
*
* @license SPDX-License-Identifier: Apache-2.0
*
* @date 2024-09-06 MacRsh First version
*/
#ifndef __MR_KREF_H__
#define __MR_KREF_H__
#include <libc/mr_atomic.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @addtogroup Kref
* @{
*/
/* Lockref type */
typedef mr_atomic_t mr_kref_t;
/**
* @brief This macro function initializes a kref.
*/
#define MR_KREF_INIT() MR_ATOMIC_INIT(1)
/**
* @brief This function initializes a kref.
*
* @param kref The kref to initialize.
*/
MR_INLINE void mr_kref_init(mr_kref_t *kref) {
mr_atomic_init(kref, 1);
}
/**
* @brief This function gets a kref.
*
* @param kref The kref to get.
*/
MR_INLINE void mr_kref_get(mr_kref_t *kref) {
mr_atomic_fetch_add(kref, 1);
}
/**
* @brief This function puts a kref.
*
* @param kref The kref to put.
* @param release The release function to call.
* @return MR_TRUE on end of lifecycle, MR_FALSE otherwise.
*/
MR_INLINE mr_bool_t mr_kref_put(mr_kref_t *kref, void (*release)(mr_kref_t *)) {
mr_atomic_t ret;
ret = mr_atomic_fetch_sub(kref, 1);
if ((ret == 1) && (release != MR_NULL)) {
release(kref);
return MR_TRUE;
}
return MR_FALSE;
}
/** @} */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __MR_KREF_H__ */

View File

@@ -9,8 +9,6 @@
#ifndef __MR_SERVICE_H__
#define __MR_SERVICE_H__
#include <kernel/mr_compiler.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
@@ -90,6 +88,24 @@ extern "C" {
*/
#define MR_MAKE_LOCAL(_type, ...) (&((_type){__VA_ARGS__}))
/**
* @brief This macro function gets the minimum value.
*
* @param _a The first value.
* @param _b The second value.
* @return The minimum value.
*/
#define MR_MIN(_a, _b) (((_a) < (_b)) ? (_a) : (_b))
/**
* @brief This macro function gets the maximum value.
*
* @param _a The first value.
* @param _b The second value.
* @return The maximum value.
*/
#define MR_MAX(_a, _b) (((_a) > (_b)) ? (_a) : (_b))
/** @} */
#ifdef __cplusplus

105
include/kernel/mr_ktimer.h Normal file
View File

@@ -0,0 +1,105 @@
/**
* @copyright (c) 2024, MacRsh
*
* @license SPDX-License-Identifier: Apache-2.0
*
* @date 2024-09-06 MacRsh First version
*/
#ifndef __MR_KTIMER_H__
#define __MR_KTIMER_H__
#include <kernel/mr_kclock.h>
#include <kernel/mr_kobject.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @addtogroup Ktimer
* @{
*/
/* Periodic definition */
#define MR_KTIMER_PERIODIC (1U << 31)
/* Ktimer type */
typedef struct mr_ktimer {
mr_kobject_t parent;
mr_klist_t list;
mr_tick_t init_tick;
mr_tick_t timeout_tick;
mr_ptr_t entry;
mr_ptr_t args;
} mr_ktimer_t;
/**
* @brief This function initialize a ktimer.
*
* @param ktimer The ktimer.
* @param name The ktimer name.
* @param entry The ktimer entry.
* @param args The ktimer args.
* @param tick The ktimer tick(period: 'tick | MR_KTIMER_PERIODIC').
* @returns 0 on success, or a negative error code on failure.
*/
mr_err_t mr_ktimer_init(mr_ktimer_t *ktimer, const char *name,
void (*entry)(mr_ktimer_t *, void *), void *args,
mr_tick_t tick);
/**
* @brief This function create a timer.
*
* @param name The timer name.
* @param entry The timer entry.
* @param args The timer args.
* @param tick The timer tick.
* @return The timer on success, or MR_NULL on failure.
*/
mr_ktimer_t *mr_ktimer_create(const char *name,
void (*entry)(mr_ktimer_t *, void *), void *args,
mr_tick_t tick);
/**
* @brief This function delete a ktimer.
*
* @param ktimer The ktimer.
* @return 0 on success, or a negative error code on failure.
*/
mr_err_t mr_ktimer_del(mr_ktimer_t *ktimer);
/**
* @brief This function start a ktimer.
*
* @param ktimer The ktimer.
* @return 0 on success, or a negative error code on failure.
*/
mr_err_t mr_ktimer_start(mr_ktimer_t *ktimer);
/**
* @brief This function stop a ktimer.
*
* @param ktimer The ktimer.
* @return 0 on success, or a negative error code on failure.
*/
mr_err_t mr_ktimer_stop(mr_ktimer_t *ktimer);
/**
* @brief This function set a ktimer tick.
*
* @param ktimer The ktimer.
* @param tick The ktimer tick.
* @return 0 on success, or a negative error code on failure.
*
* @note If the ktimer is running, it will be stopped.
*/
mr_err_t mr_ktimer_tick_set(mr_ktimer_t *ktimer, mr_tick_t tick);
/** @} */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __MR_KTIMER_H__ */

View File

@@ -1,150 +0,0 @@
/**
* @copyright (c) 2024, MacRsh
*
* @license SPDX-License-Identifier: Apache-2.0
*
* @date 2024-09-06 MacRsh First version
*/
#ifndef __MR_LOCKREF_H__
#define __MR_LOCKREF_H__
#include <kernel/mr_spinlock.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @addtogroup Lockref
* @{
*/
/* Lockref type */
typedef struct mr_lockref {
mr_spinlock_t lock;
mr_atomic_t count;
} mr_lockref_t;
/**
* @brief This macro function initializes a lockref.
*/
#define MR_LOCKREF_INIT() \
{ MR_SPINLOCK_INIT(), 1 }
/**
* @brief This function initializes a lockref.
*
* @param lockref The lockref to initialize.
*/
MR_INLINE void mr_lockref_init(mr_lockref_t *lockref) {
mr_spinlock_init(&lockref->lock);
mr_atomic_init(&lockref->count, 1);
}
/**
* @brief This function tries to lock a lockref.
*
* @param lockref The lockref to lock.
* @return MR_TRUE on success, MR_FALSE on failure.
*/
MR_INLINE mr_bool_t mr_lockref_trylock(mr_lockref_t *lockref) {
return mr_spinlock_trylock(&lockref->lock);
}
/**
* @brief This function locks a lockref.
*
* @param lockref The lockref to lock.
*/
MR_INLINE void mr_lockref_lock(mr_lockref_t *lockref) {
mr_spinlock_lock(&lockref->lock);
}
/**
* @brief This function unlocks a lockref.
*
* @param lockref The lockref to unlock.
*/
MR_INLINE void mr_lockref_unlock(mr_lockref_t *lockref) {
mr_spinlock_unlock(&lockref->lock);
}
/**
* @brief This function gets a locked lockref.
*
* @param lockref The lockref to get.
*/
MR_INLINE void mr_lockref_get_locked(mr_lockref_t *lockref) {
mr_atomic_fetch_add(&lockref->count, 1);
}
/**
* @brief This function puts a locked lockref.
*
* @param lockref The lockref to put.
* @param release The release function to call.
* @return MR_TRUE on end of lifecycle, MR_FALSE otherwise.
*/
MR_INLINE mr_bool_t mr_lockref_put_locked(mr_lockref_t *lockref,
void (*release)(mr_lockref_t *)) {
if (mr_atomic_load(&lockref->count) > 1) {
mr_atomic_fetch_sub(&lockref->count, 1);
return MR_FALSE;
}
/* End of lifecycle */
if (release != MR_NULL) {
release(lockref);
}
return MR_TRUE;
}
/**
* @brief This function gets a lockref.
*
* @param lockref The lockref to get.
*/
MR_INLINE void mr_lockref_get(mr_lockref_t *lockref) {
mr_lockref_lock(lockref);
mr_lockref_get_locked(lockref);
mr_lockref_unlock(lockref);
}
/**
* @brief This function puts a lockref.
*
* @param lockref The lockref to put.
* @param release The release function to call.
* @return MR_TRUE on end of lifecycle, MR_FALSE otherwise.
*
* @note If the lockref will be zero, it will be not unlocked.
*/
MR_INLINE mr_bool_t mr_lockref_put(mr_lockref_t *lockref,
void (*release)(mr_lockref_t *)) {
int ret;
mr_lockref_lock(lockref);
ret = mr_lockref_put_locked(lockref, release);
if (!ret) {
mr_lockref_unlock(lockref);
}
return ret;
}
/**
* @brief This function gets the count of a lockref.
*
* @param lockref The lockref to get.
* @return The count of the lockref.
*/
MR_INLINE mr_atomic_t mr_lockref_count(mr_lockref_t *lockref) {
return mr_atomic_load(&lockref->count);
}
/** @} */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __MR_LOCKREF_H__ */

View File

@@ -1,112 +0,0 @@
/**
* @copyright (c) 2024, MacRsh
*
* @license SPDX-License-Identifier: Apache-2.0
*
* @date 2024-09-06 MacRsh First version
*/
#ifndef __MR_RWLOCK_H__
#define __MR_RWLOCK_H__
#include <kernel//mr_atomic.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @addtogroup Rwlock
* @{
*/
/* Rwlock type */
typedef mr_atomic_t mr_rwlock_t;
/**
* @brief This macro function initializes a rwlock.
*/
#define MR_RWLOCK_INIT() MR_ATOMIC_INIT(0)
/**
* @brief This function initializes a rwlock.
*
* @param lock The rwlock to initialize.
*/
MR_INLINE void mr_rwlock_init(mr_rwlock_t *lock) {
mr_atomic_init(lock, 0);
}
/**
* @brief This function locks a rwlock for reading.
*
* @param lock The rwlock to lock.
*/
MR_INLINE void mr_rwlock_read_lock(mr_rwlock_t *lock) {
while (mr_atomic_fetch_add(lock, 1) & (1U << 31)) {
mr_atomic_fetch_sub(lock, 1);
}
}
/**
* @brief This function unlocks a rwlock for reading.
*
* @param lock The rwlock to unlock.
*/
MR_INLINE void mr_rwlock_read_unlock(mr_rwlock_t *lock) {
mr_atomic_fetch_sub(lock, 1);
}
/**
* @brief This function unlocks a rwlock for reading.
*
* @param lock The rwlock to unlock.
* @return MR_TRUE on success, MR_FALSE on failure.
*/
MR_INLINE mr_bool_t mr_rwlock_read_trylock(mr_rwlock_t *lock) {
if (mr_atomic_fetch_add(lock, 1) & (1U << 31)) {
mr_atomic_fetch_sub(lock, 1);
return MR_FALSE;
}
return MR_TRUE;
}
/**
* @brief This function locks a rwlock for writing.
*
* @param lock The rwlock to lock.
*/
MR_INLINE void mr_rwlock_write_lock(mr_rwlock_t *lock) {
while (mr_atomic_fetch_or(lock, (mr_atomic_t)(1U << 31))) {
}
}
/**
* @brief This function unlocks a rwlock for writing.
*
* @param lock The rwlock to unlock.
*/
MR_INLINE void mr_rwlock_write_unlock(mr_rwlock_t *lock) {
mr_atomic_fetch_and(lock, (mr_atomic_t)(~(1U << 31)));
}
/**
* @brief This function unlocks a rwlock for writing.
*
* @param lock The rwlock to unlock.
* @return MR_TRUE on success, MR_FALSE on failure.
*/
MR_INLINE mr_bool_t mr_rwlock_write_trylock(mr_rwlock_t *lock) {
if (mr_atomic_fetch_or(lock, (mr_atomic_t)(1U << 31))) {
return MR_FALSE;
}
return MR_TRUE;
}
/** @} */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __MR_RWLOCK_H__ */

136
include/kernel/mr_slist.h Normal file
View File

@@ -0,0 +1,136 @@
/**
* @copyright (c) 2024, MacRsh
*
* @license SPDX-License-Identifier: Apache-2.0
*
* @date 2024-09-06 MacRsh First version
*/
#ifndef __MR_SLIST_H__
#define __MR_SLIST_H__
#include <kernel/mr_kservice.h>
#include <libc/mr_compiler.h>
#include <libc/mr_types.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @addtogroup Slist
* @{
*/
/* Single list type */
typedef struct mr_slist {
struct mr_slist *next;
} mr_slist_t;
/**
* @brief This macro function initializes a single list.
*
* @param _slist The list to initialize.
*/
#define MR_SLIST_INIT(_slist) \
{ .next = MR_NULL }
/**
* @brief This function initializes a single list.
*
* @param entry The element to initialize.
*/
MR_INLINE void mr_slist_init(mr_slist_t *entry) {
entry->next = MR_NULL;
}
/**
* @brief This function adds an element to the list.
*
* @param head The list head.
* @param entry The element to add.
*
* @note Adds to the end of the list.
*/
MR_INLINE void mr_slist_add(mr_slist_t *head, mr_slist_t *entry) {
mr_slist_t *p;
p = head;
while (!p->next) {
p = p->next;
}
p->next = entry;
}
/**
* @brief This function inserts an element into the list.
*
* @param head The list head.
* @param entry The element to insert.
*
* @note Inserts to the beginning of the list.
*/
MR_INLINE void mr_slist_insert(mr_slist_t *head, mr_slist_t *entry) {
entry->next = head->next;
head->next = entry;
}
/**
* @brief This function removes an element from the list.
*
* @param head The list head.
* @param entry The element to remove.
*/
MR_INLINE void mr_slist_del(mr_slist_t *head, mr_slist_t *entry) {
mr_slist_t *p;
p = head;
while (!p->next) {
if (p->next != entry) {
p = p->next;
continue;
}
p->next = entry->next;
entry->next = MR_NULL;
return;
}
}
/**
* @brief This function checks if the list is empty.
*
* @param head The list head.
* @return MR_TRUE on empty, MR_FALSE otherwise.
*/
MR_INLINE mr_bool_t mr_slist_is_empty(mr_slist_t *head) {
return (!head->next) ? MR_TRUE : MR_FALSE;
}
/**
* @brief This macro function iterates through the list.
*
* @param _pos The pointer to the element.
* @param _head The list head.
*/
#define MR_SLIST_FOR_EACH(_pos, _head) \
for ((_pos) = (_head)->next; (_pos) != MR_NULL; (_pos) = (_pos)->next)
/**
* @brief This macro function iterates through the list in safe order.
*
* @param _pos The pointer to the element.
* @param _n The pointer to the next element.
* @param _head The list head.
*/
#define MR_SLIST_FOR_EACH_SAFE(_pos, _n, _head) \
for ((_pos) = (_head)->next, (_n) = (_pos) ? (_pos)->next : MR_NULL; \
(_pos) != MR_NULL; \
(_pos) = (_n), (_n) = (_pos) ? (_pos)->next : MR_NULL)
/** @} */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __MR_SLIST_H__ */

View File

@@ -10,7 +10,7 @@
#define __MR_SPINLOCK_H__
#include <arch/mr_hw_irq.h>
#include <kernel/mr_atomic.h>
#include <libc/mr_atomic.h>
#ifdef __cplusplus
extern "C" {
@@ -38,30 +38,18 @@ MR_INLINE void mr_spinlock_init(mr_spinlock_t *lock) {
mr_atomic_init(lock, 0);
}
/**
* @brief This function tries to lock a spinlock.
*
* @param lock The spinlock to lock.
* @return MR_TRUE on success, MR_FALSE on failure.
*/
MR_INLINE mr_bool_t mr_spinlock_trylock(mr_spinlock_t *lock) {
mr_spinlock_t unlock;
mr_spinlock_init(&unlock);
if (!mr_atomic_compare_exchange(lock, &unlock, 1)) {
return MR_FALSE;
}
return MR_TRUE;
}
/**
* @brief This function locks a spinlock.
*
* @param lock The spinlock to lock.
*/
MR_INLINE void mr_spinlock_lock(mr_spinlock_t *lock) {
while (!mr_spinlock_trylock(lock)) {
}
mr_atomic_t unlock;
do {
mr_atomic_init(&unlock, 0);
unlock = mr_atomic_compare_exchange(lock, &unlock, 1);
} while (!unlock);
}
/**
@@ -74,11 +62,10 @@ MR_INLINE void mr_spinlock_unlock(mr_spinlock_t *lock) {
}
/**
* @brief This function locks a spinlock with IRQs disabled and returns the
* IRQ flags.
* @brief This function locks a spinlock with interrupts disabled.
*
* @param lock The spinlock to lock.
* @return The IRQ flags.
* @return The interrupt mask.
*/
MR_INLINE int mr_spinlock_lock_irqsave(mr_spinlock_t *lock) {
int mask;
@@ -89,13 +76,13 @@ MR_INLINE int mr_spinlock_lock_irqsave(mr_spinlock_t *lock) {
}
/**
* @brief This function unlocks a spinlock with IRQs disabled and restores the
* IRQ mask.
* @brief This function unlocks a spinlock with interrupts restored.
*
* @param lock The spinlock to unlock.
* @param mask The IRQ mask.
* @param mask The interrupt mask.
*/
MR_INLINE void mr_spinlock_unlock_irqrestore(mr_spinlock_t *lock, int mask) {
MR_INLINE void mr_spinlock_unlock_irqrestore(mr_spinlock_t *lock, int mask)
{
mr_spinlock_unlock(lock);
mr_hw_irq_restore(mask);
}

View File

@@ -1,105 +0,0 @@
/**
* @copyright (c) 2024, MacRsh
*
* @license SPDX-License-Identifier: Apache-2.0
*
* @date 2024-09-06 MacRsh First version
*/
#ifndef __MR_TIMER_H__
#define __MR_TIMER_H__
#include <kernel/mr_clock.h>
#include <kernel/mr_kobject.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @addtogroup Timer
* @{
*/
/* Periodic definition */
#define MR_TIMER_PERIODIC (1U << 31)
/* Timer type */
typedef struct mr_timer {
mr_kobject_t parent;
mr_list_t list;
mr_tick_t init_tick;
mr_tick_t timeout_tick;
mr_ptr_t entry;
mr_ptr_t args;
} mr_timer_t;
/**
* @brief This function initialize a timer.
*
* @param timer The timer.
* @param name The timer name.
* @param entry The timer entry.
* @param args The timer args.
* @param tick The timer tick(period: 'tick | MR_TIMER_PERIODIC').
* @returns 0 on success, or a negative error code on failure.
*/
mr_err_t mr_timer_init(mr_timer_t *timer, const char *name,
void (*entry)(mr_timer_t *, void *), void *args,
mr_tick_t tick);
/**
* @brief This function create a timer.
*
* @param name The timer name.
* @param entry The timer entry.
* @param args The timer args.
* @param tick The timer tick.
* @return The timer on success, or MR_NULL on failure.
*/
mr_timer_t *mr_timer_create(const char *name,
void (*entry)(mr_timer_t *, void *), void *args,
mr_tick_t tick);
/**
* @brief This function delete a timer.
*
* @param timer The timer.
* @return 0 on success, or a negative error code on failure.
*/
mr_err_t mr_timer_del(mr_timer_t *timer);
/**
* @brief This function start a timer.
*
* @param timer The timer.
* @return 0 on success, or a negative error code on failure.
*/
mr_err_t mr_timer_start(mr_timer_t *timer);
/**
* @brief This function stop a timer.
*
* @param timer The timer.
* @return 0 on success, or a negative error code on failure.
*/
mr_err_t mr_timer_stop(mr_timer_t *timer);
/**
* @brief This function set a timer tick.
*
* @param timer The timer.
* @param tick The timer tick.
* @return 0 on success, or a negative error code on failure.
*
* @note If the timer is running, it will be stopped.
*/
mr_err_t mr_timer_tick_set(mr_timer_t *timer, mr_tick_t tick);
/** @} */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __MR_TIMER_H__ */

View File

@@ -69,25 +69,25 @@ menu "Libc"
help
The size of the heap in bytes.
# PRINTFK
# STDIO
choice
prompt "Printfk"
prompt "Stdio"
default MR_USE_PRINTFK
config MR_USE_LIBC_PRINTFK
bool "Standard libc printfk"
config MR_USE_LIBC_STDIO
bool "Standard libc stdio"
help
Use the standard libc printfk for printing.
Use the standard libc stdio for I/O operations.
config MR_USE_3PARTY_PRINTFK
bool "3rd party printfk"
config MR_USE_3PARTY_STDIO
bool "3rd party stdio"
help
Use a third-party printfk library for printing.
Use a third-party stdio library for I/O operations.
config MR_USE_PRINTFK
bool "Custom printfk"
config MR_USE_STDIO
bool "Custom stdio"
help
Use a custom printfk implementation for printing.
Use a custom stdio implementation for I/O operations.
endchoice
# STRING

View File

@@ -15,7 +15,7 @@
#elif defined(MR_USE_3PARTY_ASSERT)
#include <3party/libc/mr_assert.h>
#elif defined(MR_USE_ASSERT)
#include <libc/mr_printfk.h>
#include <libc/mr_kprintf.h>
#endif /* defined(MR_USE_LIBC_ASSERT) */
#ifdef __cplusplus
@@ -36,7 +36,7 @@ extern "C" {
#define MR_ASSERT(_expr) \
do { \
if (!(_expr)) { \
mr_printfk("%s:%d: %s\n", __FILE__, __LINE__, #_expr); \
mr_kprintf("%s:%d: %s\n", __FILE__, __LINE__, #_expr); \
while (1) { \
} \
} \

View File

@@ -9,7 +9,7 @@
#ifndef __MR_ATOMIC_H__
#define __MR_ATOMIC_H__
#include <kernel/mr_compiler.h>
#include <libc/mr_compiler.h>
#include <libc/mr_types.h>
#if !defined(__CC_ARM) && !defined(__GNUC__) && !defined(__clang__)
#include <arch/mr_hw_irq.h>

View File

@@ -1,60 +0,0 @@
/**
* @copyright (c) 2024, MacRsh
*
* @license SPDX-License-Identifier: Apache-2.0
*
* @date 2024-09-06 MacRsh First version
*/
#ifndef __MR_PRINTFK_H__
#define __MR_PRINTFK_H__
#include <mr_config.h>
#if defined(MR_USE_LIBC_PRINTFK)
#include <stdio.h>
#else
#include <libc/mr_types.h>
#endif /* defined(MR_USE_LIBC_PRINTFK) */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @addtogroup Printf
* @{
*/
/* Printf definition */
#if defined(MR_USE_LIBC_PRINTFK)
#define mr_printfk(_fmt, ...) printf(_fmt, ##__VA_ARGS__)
#define mr_snprintfk(_b, _s, _f, ...) snprintf(_b, _s, _f, ##__VA_ARGS__)
#else
/**
* @brief This function prints a formatted string.
*
* @param fmt The format string.
* @param ... The arguments.
* @return The number of characters printed.
*/
int mr_printfk(const char *fmt, ...);
/**
* @brief This function prints a formatted string.
*
* @param buf The buffer.
* @param size The size of the buffer.
* @param fmt The format string.
* @param ... The arguments.
* @return The number of characters printed.
*/
int mr_snprintfk(char *buf, mr_size_t size, const char *fmt, ...);
#endif /* defined(MR_USE_LIBC_PRINTFK) */
/** @} */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __MR_PRINTFK_H__ */

42
include/libc/mr_stdio.h Normal file
View File

@@ -0,0 +1,42 @@
/**
* @copyright (c) 2024, MacRsh
*
* @license SPDX-License-Identifier: Apache-2.0
*
* @date 2024-09-06 MacRsh First version
*/
#ifndef __MR_STDIO_H__
#define __MR_STDIO_H__
#include <mr_config.h>
#if defined(MR_USE_LIBC_STDIO)
#include <stdio.h>
#else
#include <libc/mr_types.h>
#endif /* defined(MR_USE_LIBC_STDIO) */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @addtogroup Stdio
* @{
*/
/* Stdio definition */
#if defined(MR_USE_LIBC_STDIO)
#define mr_vprintf(_f, _a) vprintf(_f, _a)
#define mr_vsnprintf(_b, _s, _f, _a) vsnprintf(_b, _s, _f, _a)
#else
#endif /* defined(MR_USE_LIBC_STDIO) */
/** @} */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __MR_STDIO_H__ */

View File

@@ -5,6 +5,12 @@
extern "C" {
#endif /* __cplusplus */
//#define MR_USE_THREAD
#define MR_USE_LIBC_MALLOC
#define MR_USE_ASSERT
#define MR_USE_LIBC_ASSERT
#define MR_USE_LIBC_STDIO
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@@ -1,64 +0,0 @@
/**
* @copyright (c) 2024, MacRsh
*
* @license SPDX-License-Identifier: Apache-2.0
*
* @date 2024-09-06 MacRsh First version
*/
#include <kernel/mr_atomic.h>
#include <kernel/mr_clock.h>
#include <kernel/mr_hooks.h>
static mr_atomic_t kclock;
#if !defined(MR_CFG_CLOCK_HOOK_SIZE)
#define MR_CFG_CLOCK_HOOK_SIZE (4)
#endif /* !defined(MR_CFG_CLOCK_HOOK_SIZE) */
#if defined(MR_USE_THREAD) && (MR_CFG_CLOCK_HOOK_SIZE < 2)
#error "If use thread, clock hook size must >= 2"
#endif /* defined(MR_USE_THREAD) && (MR_CFG_CLOCK_HOOK_SIZE < 2) */
static mr_ptr_t khook[MR_CFG_CLOCK_HOOK_SIZE];
static mr_hooks_t khooks = MR_HOOKS_INIT(khook, MR_CFG_CLOCK_HOOK_SIZE);
MR_INLINE void clock_hooks_call(void) {
void (*hook)(void);
mr_size_t i;
/* Each hooks */
MR_HOOKS_EACH(i, &khooks, hook) {
if (!hook) {
continue;
}
/* Call hook */
hook();
}
}
void mr_clock_increase(mr_clock_t clock) {
/* Clock increase */
mr_atomic_fetch_add(&kclock, (mr_atomic_t)clock);
/* Call hooks */
clock_hooks_call();
}
mr_clock_t mr_clock_get(void) {
/* Get kclock */
return (mr_clock_t)mr_atomic_load(&kclock);
}
void mr_clock_set(mr_clock_t clock) {
/* Set kclock */
mr_atomic_store(&kclock, (mr_atomic_t)clock);
}
int mr_clock_hook_add(int index, void (*hook)(void)) {
/* Add hook */
return mr_hooks_add(&khooks, index, hook);
}
void mr_clock_hook_del(int index) {
/* Delete hook */
mr_hooks_del(&khooks, index);
}

View File

@@ -1,77 +0,0 @@
/**
* @copyright (c) 2024, MacRsh
*
* @license SPDX-License-Identifier: Apache-2.0
*
* @date 2024-09-06 MacRsh First version
*/
#include <kernel/mr_hooks.h>
void mr_hooks_init(mr_hooks_t *hooks, mr_ptr_t *hook, mr_size_t size) {
/* Check arguments */
if ((!hooks) || (!hook) || (!size)) {
return;
}
/* Initialize hooks */
mr_spinlock_init(&hooks->lock);
hooks->hook = hook;
hooks->size = size;
}
int mr_hooks_add(mr_hooks_t *hooks, int index, mr_ptr_t hook) {
mr_size_t i;
int ret;
/* Check arguments */
if ((!hooks) || (index < -1) || (index >= (int)hooks->size)) {
return -MR_EINVAL;
}
/* Lock hooks */
mr_spinlock_lock(&hooks->lock);
/* Add hooks */
if (index >= 0) {
hooks->hook[index] = hook;
ret = index;
goto _exit;
}
/* Allocate hooks */
for (i = 0; i < hooks->size; i++) {
if (hooks->hook[i]) {
continue;
}
/* Allocate success */
hooks->hook[i] = hook;
ret = (int)i;
goto _exit;
}
/* Allocate fail */
ret = -MR_ENOMEM;
_exit:
/* Unlock hooks */
mr_spinlock_unlock(&hooks->lock);
return ret;
}
void mr_hooks_del(mr_hooks_t *hooks, int index) {
/* Check arguments */
if ((!hooks) || (index < 0) || (index >= (int)hooks->size)) {
return;
}
/* Lock hooks */
mr_spinlock_lock(&hooks->lock);
/* Delete hooks */
hooks->hook[index] = MR_NULL;
/* Unlock hooks */
mr_spinlock_unlock(&hooks->lock);
}

View File

@@ -30,7 +30,7 @@ void mr_autoinit_kernel(void) {
/* Run initcalls(kernel) */
for (ic = &__mr_initcall_kernel_start; ic <= &__mr_initcall_kernel_end;
ic++) {
ic->fn();
ic->entry();
}
}
@@ -40,6 +40,6 @@ void mr_autoinit(void) {
/* Run initcalls(user) */
for (ic = &__mr_initcall_user_start; ic <= &__mr_initcall_user_end;
ic++) {
ic->fn();
ic->entry();
}
}

54
kernel/kclock.c Normal file
View File

@@ -0,0 +1,54 @@
/**
* @copyright (c) 2024, MacRsh
*
* @license SPDX-License-Identifier: Apache-2.0
*
* @date 2024-09-06 MacRsh First version
*/
#include <kernel/mr_kclock.h>
#include <kernel/mr_khook.h>
#include <libc/mr_atomic.h>
static mr_atomic_t kclock;
#if !defined(MR_CFG_KCLOCK_HOOK_SIZE)
#define MR_CFG_KCLOCK_HOOK_SIZE (4)
#endif /* !defined(MR_CFG_KCLOCK_HOOK_SIZE) */
#if defined(MR_USE_THREAD) && (MR_CFG_KCLOCK_HOOK_SIZE < 2)
#error "If use thread, clock hook size must >= 2"
#endif /* defined(MR_USE_THREAD) && (MR_CFG_KCLOCK_HOOK_SIZE < 2) */
static mr_ptr_t kentry[MR_CFG_KCLOCK_HOOK_SIZE];
static mr_khook_t khook = MR_KHOOK_INIT(kentry, MR_CFG_KCLOCK_HOOK_SIZE);
MR_INLINE void kclock_hook(void) {
void (*entry)(void);
mr_size_t i;
/* Each hooks */
MR_KHOOK_EACH(i, entry, &khook) {
if (!entry) {
continue;
}
/* Call entry */
entry();
}
}
void mr_kclock_increase(mr_tick_t tick) {
/* Clock increase */
mr_atomic_fetch_add(&kclock, (mr_atomic_t)tick);
/* Call hooks */
kclock_hook();
}
mr_tick_t mr_kclock_tick(void) {
/* Get kclock */
return (mr_tick_t)mr_atomic_load(&kclock);
}
mr_err_t mr_kclock_hook_add(void (*entry)(void)) {
/* Add entry to khook */
return mr_khook_add(&khook, entry);
}

100
kernel/kfifo.c Normal file
View File

@@ -0,0 +1,100 @@
/**
* @copyright (c) 2024, MacRsh
*
* @license SPDX-License-Identifier: Apache-2.0
*
* @date 2024-09-06 MacRsh First version
*/
#include <kernel/mr_kfifo.h>
#include <libc/mr_string.h>
MR_INLINE mr_uint32_t kfifo_align_down_pow2(mr_uint32_t val) {
if (val == 0) {
return 0;
}
val |= val >> 1;
val |= val >> 2;
val |= val >> 4;
val |= val >> 8;
val |= val >> 16;
return val - (val >> 1);
}
void mr_kfifo_init(mr_kfifo_t *kfifo, void *buf, mr_uint32_t size) {
kfifo->buf = buf;
kfifo->in = 0;
kfifo->out = 0;
/* Align 2^n(down) */
kfifo->size = kfifo_align_down_pow2(size);
}
mr_uint32_t mr_kfifo_in(mr_kfifo_t *kfifo, const void *buf, mr_uint32_t size) {
mr_uint32_t s;
/* Get available size */
size = MR_MIN(size, mr_kfifo_avail(kfifo));
if (size == 0) {
return 0;
}
/* In end of kfifo */
s = MR_MIN(size, kfifo->size - (kfifo->in & (kfifo->size - 1)));
mr_memcpy(kfifo->buf + (kfifo->in & (kfifo->size - 1)), buf, s);
/* In start of kfifo */
mr_memcpy(kfifo->buf, buf + s, size - s);
/* Update in index */
kfifo->in += size;
return size;
}
mr_uint32_t mr_kfifo_out(mr_kfifo_t *kfifo, void *buf, mr_uint32_t size) {
/* Peek kfifo */
size = mr_kfifo_peek(kfifo, buf, size);
/* Update out index */
kfifo->out += size;
return size;
}
mr_uint32_t mr_kfifo_in_overwrite(mr_kfifo_t *kfifo, const void *buf,
mr_uint32_t size) {
mr_uint32_t s;
/* Skip the useless data */
s = MR_MIN(size, mr_kfifo_size(kfifo));
if (s > size) {
buf = (mr_uint8_t *)buf + (size - s);
size = s;
}
/* Give space to kfifo */
s = mr_kfifo_avail(kfifo);
if (s < size) {
mr_kfifo_skip(kfifo, size - s);
}
/* In kfifo */
return mr_kfifo_in(kfifo, buf, size);
}
mr_uint32_t mr_kfifo_peek(mr_kfifo_t *kfifo, void *buf, mr_uint32_t size) {
mr_uint32_t s;
/* Get available size */
size = MR_MIN(size, mr_kfifo_len(kfifo));
if (size == 0) {
return 0;
}
/* Out end of kfifo */
s = MR_MIN(size, kfifo->size - (kfifo->out & (kfifo->size - 1)));
mr_memcpy(buf, kfifo->buf + (kfifo->out & (kfifo->size - 1)), s);
/* Out start of kfifo */
mr_memcpy(buf + s, kfifo->buf, size - s);
return size;
}

49
kernel/khook.c Normal file
View File

@@ -0,0 +1,49 @@
/**
* @copyright (c) 2024, MacRsh
*
* @license SPDX-License-Identifier: Apache-2.0
*
* @date 2024-09-06 MacRsh First version
*/
#include <kernel/mr_khook.h>
void mr_khook_init(mr_khook_t *khook, mr_ptr_t *entry, mr_size_t size) {
/* Check arguments */
if ((!khook) || ((!entry) && (size == 0))) {
return;
}
/* Initialize khook */
mr_spinlock_init(&khook->lock);
khook->entry = entry;
khook->size = size;
khook->next = 0;
}
mr_err_t mr_khook_add(mr_khook_t *khook, mr_ptr_t entry) {
mr_err_t ret;
mr_size_t i;
int mask;
/* Check arguments */
if (!khook) {
return -MR_EINVAL;
}
/* Lock khook */
mask = mr_spinlock_lock_irqsave(&khook->lock);
/* Add entry to khook */
if (khook->next < khook->size) {
khook->entry[khook->next++] = entry;
ret = 0;
} else {
/* Out of space */
ret = -MR_ENOMEM;
}
/* Unlock khook */
mr_spinlock_unlock_irqrestore(&khook->lock, mask);
return ret;
}

202
kernel/kmap.c Normal file
View File

@@ -0,0 +1,202 @@
/**
* @copyright (c) 2024, MacRsh
*
* @license SPDX-License-Identifier: Apache-2.0
*
* @date 2024-09-06 MacRsh First version
*/
#include <kernel/mr_kmap.h>
#include <libc/mr_compiler.h>
#include <libc/mr_malloc.h>
mr_err_t mr_kmap_init(mr_kmap_t *kmap, mr_size_t size, mr_f32_t load_factor) {
/* Check arguments */
if ((size == 0) || (load_factor <= 0.0f) || (load_factor > 1.0f)) {
return -MR_EINVAL;
}
/* Initialize kmap */
kmap->b = mr_calloc(size, sizeof(mr_knode_t));
if (!kmap->b) {
return -MR_ENOMEM;
}
kmap->size = size;
kmap->count = 0;
kmap->load_factor = load_factor;
return 0;
}
MR_INLINE mr_err_t kmap_resize(mr_kmap_t *kmap, mr_size_t new_size) {
mr_knode_t *node, *prev;
mr_knode_t **new_b;
mr_size_t index, i;
if (new_size == kmap->size) {
/* No need to resize */
return 0;
}
/* Allocate new bucket */
if (new_size > 0) {
new_b = mr_calloc(new_size, sizeof(mr_knode_t));
if (!new_b) {
return -MR_ENOMEM;
}
/* Rehash */
for (i = 0; i < kmap->size; i++) {
node = kmap->b[i];
while (node) {
prev = node;
node = node->next;
index = prev->key % new_size;
prev->next = new_b[index];
new_b[index] = prev;
}
}
} else {
new_b = MR_NULL;
}
/* Update kmap */
mr_free(kmap->b);
kmap->b = new_b;
kmap->size = new_size;
return 0;
}
mr_err_t mr_kmap_add(mr_kmap_t *kmap, mr_uint32_t key, void *value) {
mr_knode_t *node;
mr_size_t index;
mr_err_t ret;
/* Check arguments */
if ((kmap->size == 0) || (!value)) {
return -MR_EINVAL;
}
/* Check load factor */
if (((mr_f32_t)kmap->count / (mr_f32_t)kmap->size) >= kmap->load_factor) {
/* Resize kmap */
ret = kmap_resize(kmap, kmap->size * 2);
if (ret != 0) {
return ret;
}
}
/* Update existing node */
index = key % kmap->size;
node = kmap->b[index];
while (node) {
if (node->key != key) {
node = node->next;
continue;
}
/* Update value */
node->value = value;
return 0;
}
/* Insert new node */
node = mr_malloc(sizeof(mr_knode_t));
if (!node) {
return -MR_ENOMEM;
}
node->key = key;
node->value = value;
node->next = kmap->b[index];
kmap->b[index] = node;
kmap->count++;
return 0;
}
void *mr_kmap_del(mr_kmap_t *kmap, mr_uint32_t key) {
mr_knode_t *node, *prev;
mr_size_t index;
void *value;
/* Check arguments */
if (kmap->size == 0) {
return MR_NULL;
}
/* Remove node */
index = key % kmap->size;
node = kmap->b[index];
prev = MR_NULL;
while (node) {
if (node->key != key) {
prev = node;
node = node->next;
continue;
}
if (!prev) {
kmap->b[index] = node->next;
} else {
prev->next = node->next;
}
value = node->value;
mr_free(node);
kmap->count--;
/* Check shrink factor */
if (((((mr_f32_t)kmap->size * kmap->load_factor) / 4.0f)
> (mr_f32_t)kmap->count)) {
/* Resize kmap */
kmap_resize(kmap, kmap->size / 2);
}
return value;
}
return MR_NULL;
}
void *mr_kmap_value(mr_kmap_t *kmap, mr_uint32_t key) {
mr_knode_t *node;
mr_size_t index;
/* Check arguments */
if (kmap->size == 0) {
return MR_NULL;
}
/* Find node */
index = key % kmap->size;
node = kmap->b[index];
while (node) {
if (node->key != key) {
node = node->next;
continue;
}
return node->value;
}
return MR_NULL;
}
void mr_kmap_clear(mr_kmap_t *kmap) {
mr_knode_t *node, *prev;
mr_size_t i;
/* Clear kmap */
for (i = 0; i < kmap->size; i++) {
node = kmap->b[i];
while (node) {
prev = node;
node = node->next;
mr_free(prev);
}
kmap->b[i] = MR_NULL;
}
kmap->count = 0;
}
mr_err_t mr_kmap_shrink(mr_kmap_t *kmap, mr_size_t size) {
/* Check arguments */
if (size < kmap->count) {
return -MR_EINVAL;
}
/* Resize kmap */
return kmap_resize(kmap, size);
}

View File

@@ -7,8 +7,9 @@
*/
#include <kernel/mr_kobject.h>
#include <kernel/mr_spinlock.h>
#include <libc/mr_malloc.h>
#include <libc/mr_printfk.h>
#include <libc/mr_stdio.h>
#include <libc/mr_string.h>
/* Last-word definition */
@@ -16,7 +17,8 @@
#define LWORD_DOT2 (0x2e2e)
/* Root kset */
static mr_kset_t kroot = MR_KSET_INIT(kroot, MR_NULL);
static mr_spinlock_t klock = MR_SPINLOCK_INIT();
static mr_kset_t kroot = MR_KSET_INIT(&kroot, MR_NULL);
void mr_ktype_init(mr_ktype_t *type, void (*release)(mr_kobject_t *)) {
/* Check arguments */
@@ -44,22 +46,18 @@ void mr_kobject_init(mr_kobject_t *kobj, mr_ktype_t *type) {
kname_init(&kobj->name);
kobj->parent = kobj;
kobj->type = type;
mr_lockref_init(&kobj->ref);
mr_list_init(&kobj->entry);
mr_list_init(&kobj->list);
mr_klist_init(&kobj->entry);
mr_klist_init(&kobj->list);
mr_kref_init(&kobj->ref);
kobj->magic = MR_KOBJECT_MAGIC;
}
MR_INLINE mr_bool_t kobject_is_added(mr_kobject_t *kobj) {
return !mr_list_is_empty(&kobj->entry);
}
MR_INLINE mr_err_t path_alloc_varg(const char *fmt, mr_va_list args,
const char **path) {
int path_len;
/* Get path length */
path_len = mr_snprintfk(MR_NULL, 0, fmt, args);
path_len = mr_vsnprintf(MR_NULL, 0, fmt, args);
if (path_len < 0) {
return -MR_EINVAL;
}
@@ -71,7 +69,7 @@ MR_INLINE mr_err_t path_alloc_varg(const char *fmt, mr_va_list args,
}
/* Format path */
mr_snprintfk((char *)*path, path_len + 1, fmt, args);
mr_vsnprintf((char *)*path, path_len + 1, fmt, args);
return 0;
}
@@ -102,10 +100,11 @@ MR_INLINE mr_bool_t kname_match(mr_kname_t *kn1, mr_kname_t *kn2) {
MR_INLINE mr_kobject_t *kobject_lookup_kname(mr_kobject_t *last,
mr_kname_t *kname) {
mr_kobject_t *kobj;
mr_list_t *l;
mr_klist_t *l;
MR_LIST_FOR_EACH(l, &last->list) {
kobj = MR_LIST_ENTRY(l, mr_kobject_t, entry);
/* For each kobject */
MR_KLIST_FOR_EACH(l, &last->list) {
kobj = MR_KLIST_ENTRY(l, mr_kobject_t, entry);
/* Match object name */
if (!kname_match(&kobj->name, kname)) {
@@ -115,6 +114,8 @@ MR_INLINE mr_kobject_t *kobject_lookup_kname(mr_kobject_t *last,
/* Found */
return kobj;
}
/* Not found */
return MR_NULL;
}
@@ -154,19 +155,15 @@ MR_INLINE mr_kobject_t *kobject_lookup_path(mr_kobject_t **last,
default: {
/* Handle 'other' */
kobj = kobject_lookup_kname(*last, &kname);
if (!kobj) {
/* Not found */
return MR_NULL;
}
break;
}
}
/* Get found kobject */
kobj = mr_kobject_get(kobj);
if (!kobj) {
/* Not found */
return MR_NULL;
}
/* Update last */
mr_kobject_put(*last);
*last = kobj;
}
return *last;
@@ -207,56 +204,56 @@ MR_INLINE void path_free(const char *path) {
mr_free((char *)path);
}
MR_INLINE mr_err_t kobject_add_varg(mr_kobject_t *kobj, mr_kobject_t *parent,
const char *fmt, mr_va_list args) {
const char *path, *path2;
MR_INLINE mr_err_t kobject_add(mr_kobject_t *kobj, mr_kobject_t **parent,
const char *path) {
mr_err_t ret;
/* Already added */
if (kobject_is_added(kobj)) {
return 0;
}
/* Get parent */
parent = mr_kobject_get(parent);
if (!parent) {
ret = -MR_EINVAL;
goto _exit_nf;
}
/* Allocate path */
ret = path_alloc_varg(fmt, args, &path);
if (ret != 0) {
goto _exit_nf;
} else {
/* Save path for free */
path2 = path;
}
/* Lookup path in parent */
if (kobject_lookup_path(&parent, &path, parent)) {
ret = -MR_EEXIST;
goto _exit;
if (kobject_lookup_path(parent, &path, *parent)) {
return -MR_EEXIST;
}
/* Allocate name */
ret = kobject_name_alloc(kobj, path);
if (ret != 0) {
return ret;
}
/* Add kobject to parent */
kobj->parent = mr_kobject_get(*parent);
mr_klist_add(&(*parent)->list, &kobj->entry);
return 0;
}
MR_INLINE mr_err_t kobject_add_varg(mr_kobject_t *kobj, mr_kobject_t *parent,
const char *fmt, mr_va_list args) {
const char *path;
mr_err_t ret;
int mask;
/* Lock */
mask = mr_spinlock_lock_irqsave(&klock);
/* Already added */
if (!mr_klist_is_empty(&kobj->entry)) {
ret = -MR_EBUSY;
goto _exit;
}
/* Allocate path */
ret = path_alloc_varg(fmt, args, &path);
if (ret != 0) {
goto _exit;
}
/* Add kobject to parent */
kobj->parent = mr_kobject_get(parent);
mr_lockref_lock(&parent->ref);
mr_list_add(&parent->list, &kobj->entry);
mr_lockref_unlock(&parent->ref);
ret = kobject_add(kobj, &parent, path);
_exit:
/* Free path */
path_free(path2);
_exit_nf:
/* Put parent */
mr_kobject_put(parent);
path_free(path);
_exit:
/* Unlock */
mr_spinlock_unlock_irqrestore(&klock, mask);
return ret;
}
@@ -266,44 +263,34 @@ mr_err_t mr_kobject_add(mr_kobject_t *kobj, mr_kobject_t *parent,
mr_err_t ret;
/* Check arguments */
if ((!kobj) || (!MR_KOBJECT_IS_INITED(kobj)) || (!parent) || (!fmt)) {
if ((!kobj) || (!MR_KOBJECT_IS_INITED(kobj)) || (!parent)
|| (!MR_KOBJECT_IS_INITED(parent)) || (!fmt)) {
return -MR_EINVAL;
}
/* Add kobject to kroot */
/* Add kobject to parent */
mr_va_start(args, fmt);
mr_lockref_lock(&kobj->ref);
ret = kobject_add_varg(kobj, parent, fmt, args);
mr_lockref_unlock(&kobj->ref);
mr_va_end(args);
return ret;
}
MR_INLINE mr_bool_t kobject_is_deleted(mr_kobject_t *kobj) {
return kobj->parent == kobj;
}
MR_INLINE void kobject_del(mr_kobject_t *kobj) {
mr_kobject_t *parent;
int mask;
/* Lock */
mask = mr_spinlock_lock_irqsave(&klock);
/* Already deleted */
if (kobject_is_deleted(kobj)) {
return;
if (mr_klist_is_empty(&kobj->entry)) {
goto _exit;
}
/* Get parent */
parent = mr_kobject_get(kobj->parent);
if (!parent) {
return;
}
/* Remove from parent */
mr_lockref_lock(&parent->ref);
mr_list_del(&kobj->entry);
mr_lockref_unlock(&parent->ref);
/* Put parent */
mr_kobject_put(parent);
/* Remove kobject from parent */
mr_klist_del(&kobj->entry);
_exit:
/* Unlock */
mr_spinlock_unlock_irqrestore(&klock, mask);
}
void mr_kobject_del(mr_kobject_t *kobj) {
@@ -313,14 +300,59 @@ void mr_kobject_del(mr_kobject_t *kobj) {
}
/* Delete kobject */
mr_lockref_lock(&kobj->ref);
kobject_del(kobj);
mr_lockref_unlock(&kobj->ref);
/* Put kobject */
mr_kobject_put(kobj);
}
MR_INLINE mr_kobject_t *kobject_lookup_varg(mr_kobject_t *parent,
const char *fmt, mr_va_list args) {
const char *path, *path2;
mr_kobject_t *kobj;
mr_err_t ret;
int mask;
/* Lock */
mask = mr_spinlock_lock_irqsave(&klock);
/* Allocate path */
ret = path_alloc_varg(fmt, args, &path);
if (ret != 0) {
kobj = MR_NULL;
goto _exit;
} else {
/* Save path for free */
path2 = path;
}
/* Lookup kobject for path */
kobj = kobject_lookup_path(&parent, &path, parent);
/* Free path */
path_free(path2);
_exit:
/* Unlock */
mr_spinlock_unlock_irqrestore(&klock, mask);
return kobj;
}
mr_kobject_t *mr_kobject_lookup(mr_kobject_t *parent, const char *fmt, ...) {
mr_kobject_t *kobj;
mr_va_list args;
/* Check arguments */
if ((!parent) || (!MR_KOBJECT_IS_INITED(parent)) || (!fmt)) {
return MR_NULL;
}
/* Lookup kobject from parent */
mr_va_start(args, fmt);
kobj = kobject_lookup_varg(parent, fmt, args);
mr_va_end(args);
return kobj;
}
mr_kobject_t *mr_kobject_get(mr_kobject_t *kobj) {
/* Check arguments */
if ((!kobj) || (!MR_KOBJECT_IS_INITED(kobj))) {
@@ -328,7 +360,7 @@ mr_kobject_t *mr_kobject_get(mr_kobject_t *kobj) {
}
/* Get kobject */
mr_lockref_get(&kobj->ref);
mr_kref_get(&kobj->ref);
return kobj;
}
@@ -342,7 +374,7 @@ MR_INLINE void kobject_release(mr_kobject_t *kobj) {
}
}
MR_INLINE void kobject_release_ref(mr_lockref_t *ref) {
MR_INLINE void kobject_release_ref(mr_kref_t *ref) {
mr_kobject_t *kobj, *parent;
const char *name;
@@ -377,25 +409,20 @@ void mr_kobject_put(mr_kobject_t *kobj) {
}
/* Put kobject */
mr_lockref_put(&kobj->ref, kobject_release_ref);
mr_kref_put(&kobj->ref, kobject_release_ref);
}
void mr_kset_init(mr_kset_t *kset, mr_ktype_t *type) {
/* Check arguments */
if (!kset) {
return;
}
/* Init kset */
mr_kobject_init((mr_kobject_t *)kset, type);
}
mr_err_t mr_kset_register(mr_kset_t *kset, const char *name) {
/* Check arguments */
if ((!kset) || (!name)) {
return -MR_EINVAL;
}
/* Add kset to kroot */
return mr_kobject_add((mr_kobject_t *)kset, (mr_kobject_t *)&kroot, name);
}
mr_kset_t *mr_kset_find(const char *name) {
/* Lookup kset in kroot */
return (mr_kset_t *)mr_kobject_lookup((mr_kobject_t *)&kroot, name);
}

20
kernel/kprintf.c Normal file
View File

@@ -0,0 +1,20 @@
/**
* @copyright (c) 2024, MacRsh
*
* @license SPDX-License-Identifier: Apache-2.0
*
* @date 2024-09-06 MacRsh First version
*/
#include <kernel/mr_kprintf.h>
#include <libc/mr_types.h>
int mr_kprintf(const char *fmt, ...) {
mr_va_list args;
int ret;
mr_va_start(args, fmt);
ret = mr_vprintf(fmt, args);
mr_va_end(args);
return ret;
}

291
kernel/ktimer.c Normal file
View File

@@ -0,0 +1,291 @@
/**
* @copyright (c) 2024, MacRsh
*
* @license SPDX-License-Identifier: Apache-2.0
*
* @date 2024-09-06 MacRsh First version
*/
#include <kernel/mr_initcall.h>
#include <kernel/mr_ktimer.h>
#include <kernel/mr_spinlock.h>
#include <libc/mr_malloc.h>
static mr_ktype_t ktype1, ktype2;
static mr_kset_t kroot = MR_KSET_INIT(&kroot, MR_NULL);
static mr_klist_t klist = MR_KLIST_INIT(&klist);
static mr_spinlock_t klock = MR_SPINLOCK_INIT();
MR_INLINE void ktimer_init(mr_ktimer_t *ktimer, mr_ptr_t entry, void *args,
mr_tick_t tick) {
/* Init ktimer */
mr_klist_init(&ktimer->list);
ktimer->init_tick = tick;
ktimer->timeout_tick = 0;
ktimer->entry = entry;
ktimer->args = args;
}
MR_INLINE mr_err_t ktimer_init_add(mr_ktimer_t *ktimer, mr_ktype_t *ktype,
const char *name, mr_ptr_t entry, void *args,
mr_tick_t tick) {
/* Init ktimer */
ktimer_init(ktimer, entry, args, tick);
/* Init kobject */
mr_kobject_init((mr_kobject_t *)ktimer, ktype);
/* Add kobject to kroot */
return mr_kobject_add((mr_kobject_t *)ktimer, (mr_kobject_t *)&kroot, name);
}
mr_err_t mr_ktimer_init(mr_ktimer_t *ktimer, const char *name,
void (*entry)(mr_ktimer_t *, void *), void *args,
mr_tick_t tick) {
/* Check arguments */
if ((!ktimer) || (MR_KOBJECT_IS_INITED(ktimer)) || (!name) || (!entry)
|| (tick == 0)) {
return -MR_EINVAL;
}
/* Init and add ktimer */
return ktimer_init_add(ktimer, &ktype1, name, (mr_ptr_t)entry, args, tick);
}
mr_ktimer_t *mr_ktimer_create(const char *name,
void (*entry)(mr_ktimer_t *, void *), void *args,
mr_tick_t tick) {
mr_ktimer_t *ktimer;
mr_err_t ret;
/* Check arguments */
if ((!name) || (!entry) || (tick == 0)) {
return MR_NULL;
}
/* Create ktimer */
ktimer = mr_malloc(sizeof(mr_ktimer_t));
if (!ktimer) {
return MR_NULL;
}
/* Init and add ktimer */
ret = ktimer_init_add(ktimer, &ktype2, name, (mr_ptr_t)entry, args, tick);
if (ret != 0) {
/* Free ktimer */
mr_free(ktimer);
return MR_NULL;
}
return ktimer;
}
MR_INLINE void ktimer_del(mr_ktimer_t *ktimer) {
int mask;
/* Lock */
mask = mr_spinlock_lock_irqsave(&klock);
/* Already deleted */
if (mr_klist_is_empty(&ktimer->list)) {
goto _exit;
}
/* Remove ktimer from ktimer list */
mr_klist_del(&ktimer->list);
_exit:
/* Unlock */
mr_spinlock_unlock_irqrestore(&klock, mask);
}
mr_err_t mr_ktimer_del(mr_ktimer_t *ktimer) {
/* Check arguments */
if ((!ktimer) || (!MR_KOBJECT_IS_INITED(ktimer))) {
return -MR_EINVAL;
}
/* Delete ktimer */
ktimer_del(ktimer);
/* Delete kobject */
mr_kobject_del((mr_kobject_t *)ktimer);
return 0;
}
MR_INLINE void ktimer_insert(mr_ktimer_t *ktimer) {
mr_tick_t tick;
mr_ktimer_t *t;
mr_klist_t *l;
/* Set timeout tick */
tick = ktimer->init_tick & ~MR_KTIMER_PERIODIC;
ktimer->timeout_tick = mr_kclock_tick() + tick;
/* Insert ktimer into ktimer list */
MR_KLIST_FOR_EACH(l, &klist) {
t = MR_KLIST_ENTRY(l, mr_ktimer_t, list);
if ((ktimer->timeout_tick - t->timeout_tick) < (MR_TICK_MAX / 2)) {
continue;
}
/* Move ktimer into position */
mr_klist_move(&ktimer->list, &t->list);
return;
}
/* It is the last ktimer */
mr_klist_move(&ktimer->list, &klist);
}
MR_INLINE void ktimer_start(mr_ktimer_t *ktimer) {
int mask;
/* Lock */
mask = mr_spinlock_lock_irqsave(&klock);
/* Insert ktimer into ktimer list */
ktimer_insert(ktimer);
/* Unlock */
mr_spinlock_unlock_irqrestore(&klock, mask);
}
mr_err_t mr_ktimer_start(mr_ktimer_t *ktimer) {
/* Check arguments */
if ((!ktimer) || (!MR_KOBJECT_IS_INITED(ktimer))) {
return -MR_EINVAL;
}
/* Start ktimer */
ktimer_start(ktimer);
return 0;
}
mr_err_t mr_ktimer_stop(mr_ktimer_t *ktimer) {
/* Check arguments */
if ((!ktimer) || (!MR_KOBJECT_IS_INITED(ktimer))) {
return -MR_EINVAL;
}
/* Delete ktimer */
ktimer_del(ktimer);
return 0;
}
MR_INLINE void ktimer_tick_set(mr_ktimer_t *ktimer, mr_tick_t tick) {
int mask;
/* Lock */
mask = mr_spinlock_lock_irqsave(&klock);
/* Set init tick */
ktimer->init_tick = tick;
/* Unlock */
mr_spinlock_unlock_irqrestore(&klock, mask);
}
mr_err_t mr_ktimer_tick_set(mr_ktimer_t *ktimer, mr_tick_t tick) {
/* Check arguments */
if ((!ktimer) || (!MR_KOBJECT_IS_INITED(ktimer)) || (tick == 0)) {
return -MR_EINVAL;
}
/* Delete ktimer */
ktimer_del(ktimer);
/* Set ktimer tick */
ktimer_tick_set(ktimer, tick);
return 0;
}
MR_INLINE void ktimer_release1_kobj(mr_kobject_t *kobj) {
mr_ktimer_t *ktimer;
/* Get ktimer */
ktimer = MR_CONTAINER_OF(kobj, mr_ktimer_t, parent);
/* Delete ktimer */
ktimer_del(ktimer);
}
MR_INLINE void ktimer_release2_kobj(mr_kobject_t *kobj) {
mr_ktimer_t *ktimer;
/* Get ktimer */
ktimer = MR_CONTAINER_OF(kobj, mr_ktimer_t, parent);
/* Delete ktimer */
ktimer_del(ktimer);
/* Free ktimer */
mr_free(ktimer);
}
MR_INLINE void ktimer_timeout_check(void) {
mr_ktimer_t *ktimer;
mr_klist_t list;
mr_tick_t tick;
int mask;
/* Lock */
mask = mr_spinlock_lock_irqsave(&klock);
/* Check timeout ktimer */
while (!mr_klist_is_empty(&klist)) {
ktimer = MR_KLIST_ENTRY(klist.next, mr_ktimer_t, list);
/* Get current tick */
tick = mr_kclock_tick();
if ((tick - ktimer->timeout_tick) >= (MR_TICK_MAX / 2)) {
/* There will be no timeout ktimer after that */
break;
}
/* Move ktimer into operation list */
mr_klist_init(&list);
mr_klist_move(&ktimer->list, &list);
/* Unlock */
mr_spinlock_unlock(&klock);
/* Call ktimer entry */
((void (*)(mr_ktimer_t *, void *))ktimer->entry)(ktimer, ktimer->args);
/* Lock */
mr_spinlock_lock(&klock);
/* Check that the ktimer has not been moved */
if (mr_klist_is_empty(&list)) {
/* Timer is no longer yours to operate */
continue;
}
/* Tick is periodic */
if (ktimer->init_tick & MR_KTIMER_PERIODIC) {
/* Restart ktimer */
ktimer_insert(ktimer);
}
}
/* Unlock */
mr_spinlock_unlock_irqrestore(&klock, mask);
}
MR_INLINE void mr_ktimer_kset_init(void) {
mr_err_t ret;
/* Register kset */
ret = mr_kset_register(&kroot, "timer");
if (ret != 0) {
/* It won't entry the kclock, so it won't start */
return;
}
/* Init ktype */
mr_ktype_init(&ktype1, ktimer_release1_kobj);
mr_ktype_init(&ktype2, ktimer_release2_kobj);
/* Add kclock entry */
mr_kclock_hook_add(ktimer_timeout_check);
}
MR_INIT_EXPORT(mr_ktimer_kset_init, MR_INIT_LEVEL_KERNEL);

View File

@@ -1,311 +0,0 @@
/**
* @copyright (c) 2024, MacRsh
*
* @license SPDX-License-Identifier: Apache-2.0
*
* @date 2024-09-06 MacRsh First version
*/
#include <kernel/mr_initcall.h>
#include <kernel/mr_spinlock.h>
#include <kernel/mr_timer.h>
#include <libc/mr_malloc.h>
static mr_ktype_t ktype1, ktype2;
static mr_kset_t kroot = MR_KSET_INIT(kroot, MR_NULL);
static mr_list_t klist = MR_LIST_INIT(klist);
static mr_spinlock_t klock = MR_SPINLOCK_INIT();
MR_INLINE void timer_init(mr_timer_t *timer, mr_ptr_t entry, void *args,
mr_tick_t tick) {
/* Init timer */
mr_list_init(&timer->list);
timer->init_tick = tick;
timer->timeout_tick = 0;
timer->entry = entry;
timer->args = args;
}
MR_INLINE mr_err_t timer_init_add(mr_timer_t *timer, mr_ktype_t *ktype,
const char *name, mr_ptr_t entry, void *args,
mr_tick_t tick) {
/* Init timer */
timer_init(timer, entry, args, tick);
/* Init kobject */
mr_kobject_init((mr_kobject_t *)timer, ktype);
/* Add kobject to kroot */
return mr_kobject_add((mr_kobject_t *)timer, (mr_kobject_t *)&kroot, name);
}
mr_err_t mr_timer_init(mr_timer_t *timer, const char *name,
void (*entry)(mr_timer_t *, void *), void *args,
mr_tick_t tick) {
/* Check arguments */
if ((!timer) || (MR_KOBJECT_IS_INITED(timer)) || (!name) || (!entry)
|| (tick == 0)) {
return -MR_EINVAL;
}
/* Init and add timer */
return timer_init_add(timer, &ktype1, name, (mr_ptr_t)entry, args, tick);
}
mr_timer_t *mr_timer_create(const char *name,
void (*entry)(mr_timer_t *, void *), void *args,
mr_tick_t tick) {
mr_timer_t *timer;
mr_err_t ret;
/* Check arguments */
if ((!name) || (!entry) || (tick == 0)) {
return MR_NULL;
}
/* Create timer */
timer = mr_malloc(sizeof(mr_timer_t));
if (!timer) {
return MR_NULL;
}
/* Init and add timer */
ret = timer_init_add(timer, &ktype2, name, (mr_ptr_t)entry, args, tick);
if (ret != 0) {
/* Free timer */
mr_free(timer);
return MR_NULL;
}
return timer;
}
MR_INLINE void timer_remove(mr_timer_t *timer) {
/* Stop timer if not stopped */
if (!mr_list_is_empty(&timer->list)) {
mr_list_del(&timer->list);
}
}
MR_INLINE void timer_del(mr_timer_t *timer) {
int mask;
/* Lock timer list */
mask = mr_spinlock_lock_irqsave(&klock);
/* Remove timer from timer list */
timer_remove(timer);
/* Unlock timer list */
mr_spinlock_unlock_irqrestore(&klock, mask);
}
mr_err_t mr_timer_del(mr_timer_t *timer) {
/* Get timer */
timer = (mr_timer_t *)mr_kobject_get((mr_kobject_t *)timer);
if (!timer) {
return -MR_EINVAL;
}
/* Delete timer from timer list */
timer_del(timer);
/* Delete kobject */
mr_kobject_del((mr_kobject_t *)timer);
/* Put timer */
mr_kobject_put((mr_kobject_t *)timer);
return 0;
}
MR_INLINE void timer_insert(mr_timer_t *timer) {
mr_tick_t tick;
mr_timer_t *t;
mr_list_t *l;
/* Set timeout tick */
tick = timer->init_tick & ~MR_TIMER_PERIODIC;
timer->timeout_tick = (mr_tick_t)mr_clock_get() + tick;
/* Insert timer into timer list */
MR_LIST_FOR_EACH(l, &klist) {
t = MR_LIST_ENTRY(l, mr_timer_t, list);
if ((timer->timeout_tick - t->timeout_tick) < (MR_TICK_MAX / 2)) {
continue;
}
/* Move timer into position */
mr_list_move(&timer->list, &t->list);
return;
}
/* It is the last timer */
mr_list_move(&timer->list, &klist);
}
MR_INLINE void timer_start(mr_timer_t *timer) {
int mask;
/* Lock timer list */
mask = mr_spinlock_lock_irqsave(&klock);
/* Insert timer into timer list */
timer_insert(timer);
/* Unlock timer list */
mr_spinlock_unlock_irqrestore(&klock, mask);
}
mr_err_t mr_timer_start(mr_timer_t *timer) {
/* Get timer */
timer = (mr_timer_t *)mr_kobject_get((mr_kobject_t *)timer);
if (!timer) {
return -MR_EINVAL;
}
/* Start timer */
timer_start(timer);
/* Put timer */
mr_kobject_put((mr_kobject_t *)timer);
return 0;
}
mr_err_t mr_timer_stop(mr_timer_t *timer) {
/* Get timer */
timer = (mr_timer_t *)mr_kobject_get((mr_kobject_t *)timer);
if (!timer) {
return -MR_EINVAL;
}
/* Delete timer from timer list */
timer_del(timer);
/* Put timer */
mr_kobject_put((mr_kobject_t *)timer);
return 0;
}
MR_INLINE void timer_tick_set(mr_timer_t *timer, mr_tick_t tick) {
int mask;
/* Lock timer list */
mask = mr_spinlock_lock_irqsave(&klock);
/* Set init tick */
timer->init_tick = tick;
/* Unlock timer list */
mr_spinlock_unlock_irqrestore(&klock, mask);
}
mr_err_t mr_timer_tick_set(mr_timer_t *timer, mr_tick_t tick) {
/* Check arguments */
if (tick == 0) {
return -MR_EINVAL;
}
/* Get timer */
timer = (mr_timer_t *)mr_kobject_get((mr_kobject_t *)timer);
if (!timer) {
return -MR_EINVAL;
}
/* Delete timer from timer list */
timer_del(timer);
/* Set timer tick */
timer_tick_set(timer, tick);
/* Put timer */
mr_kobject_put((mr_kobject_t *)timer);
return 0;
}
MR_INLINE void timer_release1_kobj(mr_kobject_t *kobj) {
mr_timer_t *timer;
/* Get timer */
timer = MR_CONTAINER_OF(kobj, mr_timer_t, parent);
/* Delete timer from timer list */
timer_del(timer);
}
MR_INLINE void timer_release2_kobj(mr_kobject_t *kobj) {
mr_timer_t *timer;
/* Get timer */
timer = MR_CONTAINER_OF(kobj, mr_timer_t, parent);
/* Delete timer from timer list */
timer_del(timer);
/* Free timer */
mr_free(timer);
}
MR_INLINE void timer_timeout_check(void) {
mr_timer_t *timer;
mr_tick_t tick;
mr_list_t list;
int mask;
/* Lock timer list */
mask = mr_spinlock_lock_irqsave(&klock);
/* Check timeout timer */
while (!mr_list_is_empty(&klist)) {
timer = MR_LIST_ENTRY(klist.next, mr_timer_t, list);
/* Get current tick */
tick = (mr_tick_t)mr_clock_get();
if ((tick - timer->timeout_tick) >= (MR_TICK_MAX / 2)) {
break;
}
/* Move timer into operation list */
mr_list_init(&list);
mr_list_move(&timer->list, &list);
/* Unlock timer list */
mr_spinlock_unlock_irqrestore(&klock, mask);
/* Call timer entry */
((void (*)(mr_timer_t *, void *))timer->entry)(timer, timer->args);
/* Lock timer list */
mask = mr_spinlock_lock_irqsave(&klock);
/* Timer is no longer yours to operate */
if (mr_list_is_empty(&list)) {
continue;
}
/* Tick is periodic */
if (timer->init_tick & MR_TIMER_PERIODIC) {
timer_insert(timer);
}
}
/* Unlock timer list */
mr_spinlock_unlock_irqrestore(&klock, mask);
}
MR_INLINE void mr_timer_kset_init(void) {
mr_err_t ret;
/* Register kset */
ret = mr_kset_register(&kroot, "timer");
if (ret != 0) {
/* It won't hook the clock, so it won't start */
return;
}
/* Init ktype */
mr_ktype_init(&ktype1, timer_release1_kobj);
mr_ktype_init(&ktype2, timer_release2_kobj);
/* Register clock hook */
mr_clock_hook_add(-1, timer_timeout_check);
}
MR_INIT_EXPORT(mr_timer_kset_init, MR_INIT_LEVEL_KERNEL);

View File

@@ -1,32 +0,0 @@
/**
* @copyright (c) 2024, MacRsh
*
* @license SPDX-License-Identifier: Apache-2.0
*
* @date 2024-09-06 MacRsh First version
*/
#include <libc/mr_printfk.h>
#if (!defined(MR_USE_LIBC_PRINTFK)) && (!defined(MR_USE_3PARTY_PRINTFK))
#include <stdio.h>
int mr_printfk(const char *fmt, ...) {
mr_va_list args;
int ret;
mr_va_start(args, fmt);
ret = vprintf(fmt, args);
mr_va_end(args);
return ret;
}
int mr_snprintfk(char *buf, mr_size_t size, const char *fmt, ...) {
mr_va_list args;
int ret;
mr_va_start(args, fmt);
ret = vsnprintf(buf, size, fmt, args);
mr_va_end(args);
return ret;
}
#endif /* (!defined(MR_USE_LIBC_PRINTFK)) && (!defined(MR_USE_3PARTY_PRINTFK)) */