style(all): Supports clipping components other than kernel objects

This commit is contained in:
MacRsh
2025-02-18 21:30:51 +08:00
parent 135d40a1ea
commit dcc5b8c4ee
22 changed files with 224 additions and 882 deletions

View File

@@ -24,6 +24,9 @@
* @brief This function saves the current interrupt mask.
*
* @return The current interrupt mask.
*
* @note User implementation.
* @note Need to clear the hardware interrupt mask.
*/
int mr_hw_irq_save(void);
@@ -31,6 +34,8 @@ int mr_hw_irq_save(void);
* @brief This function restores the interrupt mask.
*
* @param mask The interrupt mask to restore.
*
* @note User implementation.
*/
void mr_hw_irq_restore(int mask);

View File

@@ -9,8 +9,11 @@
#ifndef __MR_KOS_H__
#define __MR_KOS_H__
#include <mr_config.h>
#if defined(MR_USE_KOS)
#include <kernel/mr_kclock.h>
#include <kernel/mr_kobject.h>
#endif /* defined(MR_USE_KOS) */
#ifdef __cplusplus
extern "C" {
@@ -21,6 +24,7 @@ extern "C" {
* @{
*/
#if defined(MR_USE_KOS)
/* Kthread operations type */
typedef struct mr_kthread_ops {
mr_err_t (*init)(void *res, const char *name, void *kth, void *stack,
@@ -86,14 +90,7 @@ MR_INLINE void mr_kos_put(mr_kos_t *kos) {
* @return The kernel os.
*/
mr_kos_t *mr_kos_find(void);
/**
* @brief This macro function gets the kthread operations of a kernel os.
*
* @param _kos The kernel os.
* @return The kthread operations of the kernel os.
*/
#define MR_KOS_KTH_OPS(_kos) ((_kos)->type->kth_type->ops)
#endif /* defined(MR_USE_KOS) */
/** @} */

View File

@@ -9,7 +9,10 @@
#ifndef __MR_KTHREAD_H__
#define __MR_KTHREAD_H__
#include <mr_config.h>
#if defined(MR_USE_KOS)
#include <kernel/kos/mr_kos.h>
#endif /* defined(MR_USE_KOS) */
#ifdef __cplusplus
extern "C" {
@@ -20,6 +23,7 @@ extern "C" {
* @{
*/
#if defined(MR_USE_KOS)
/* Kthread type */
typedef struct mr_kthread {
mr_kobject_t parent;
@@ -144,6 +148,30 @@ mr_err_t mr_kthread_exit(mr_kthread_t *kth);
*/
mr_kthread_t *mr_kthread_self(void);
/**
* @brief This function cleanup a kthread.
*
* @param kth The kthread.
*/
void mr_kthread_cleanup(mr_kthread_t *kth);
/**
* @brief This function is the kthread entry.
*
* @param kth The kthread.
*
* @note User does not need to call this function.
*/
void mr_kthread_entry(mr_kthread_t *kth);
/**
* @brief This function find a kthread.
*
* @param name The kthread name.
* @return The kthread on success, or MR_NULL on failure.
*/
mr_kthread_t *mr_kthread_find(const char *name);
/**
* @brief This function get a kthread.
*
@@ -162,30 +190,7 @@ MR_INLINE mr_kthread_t *mr_kthread_get(mr_kthread_t *kth) {
MR_INLINE void mr_kthread_put(mr_kthread_t *kth) {
mr_kobject_put((mr_kobject_t *)kth);
}
/**
* @brief This function find a kthread.
*
* @param name The kthread name.
* @return The kthread on success, or MR_NULL on failure.
*/
mr_kthread_t *mr_kthread_find(const char *name);
/**
* @brief This function cleanup a kthread.
*
* @param kth The kthread.
*/
void mr_kthread_cleanup(mr_kthread_t *kth);
/**
* @brief This function is the kthread entry.
*
* @param kth The kthread.
*
* @note User does not need to call this function.
*/
void mr_kthread_entry(mr_kthread_t *kth);
#endif /* defined(MR_USE_KOS) */
/** @} */

View File

@@ -1,160 +0,0 @@
/**
* @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__ */

View File

@@ -1,120 +0,0 @@
/**
* @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 {
struct mr_knode *next;
mr_uint32_t key;
void *value;
} 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

@@ -44,7 +44,7 @@ typedef struct mr_kobject {
mr_uint32_t magic;
mr_kname_t name;
#if !defined(MR_CFG_KOBJECT_INAME_SIZE)
#define MR_CFG_KOBJECT_INAME_SIZE (16)
#define MR_CFG_KOBJECT_INAME_SIZE (8)
#endif /* !defined(MR_CFG_KOBJECT_INAME_SIZE) */
char iname[MR_CFG_KOBJECT_INAME_SIZE];
struct mr_kobject *parent;

View File

@@ -1,136 +0,0 @@
/**
* @copyright (c) 2024, MacRsh
*
* @license SPDX-License-Identifier: Apache-2.0
*
* @date 2024-09-06 MacRsh First version
*/
#ifndef __MR_KSLIST_H__
#define __MR_KSLIST_H__
#include <kernel/mr_kservice.h>
#include <libc/mr_compiler.h>
#include <libc/mr_types.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @addtogroup Kslist
* @{
*/
/* Single list type */
typedef struct mr_kslist {
struct mr_kslist *next;
} mr_kslist_t;
/**
* @brief This macro function initializes a single list.
*
* @param _kslist The list to initialize.
*/
#define MR_KSLIST_INIT(_kslist) \
{ .next = MR_NULL }
/**
* @brief This function initializes a single list.
*
* @param entry The element to initialize.
*/
MR_INLINE void mr_kslist_init(mr_kslist_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_kslist_add(mr_kslist_t *head, mr_kslist_t *entry) {
mr_kslist_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_kslist_insert(mr_kslist_t *head, mr_kslist_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_kslist_del(mr_kslist_t *head, mr_kslist_t *entry) {
mr_kslist_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_kslist_is_empty(mr_kslist_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_KSLIST_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_KSLIST_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_KSLIST_H__ */

View File

@@ -9,8 +9,11 @@
#ifndef __MR_KTIMER_H__
#define __MR_KTIMER_H__
#include <mr_config.h>
#if defined(MR_USE_KTIMER)
#include <kernel/mr_kclock.h>
#include <kernel/mr_kobject.h>
#endif /* defined(MR_USE_KTIMER) */
#ifdef __cplusplus
extern "C" {
@@ -21,8 +24,9 @@ extern "C" {
* @{
*/
#if defined(MR_USE_KTIMER)
/* Periodic definition */
#define MR_KTIMER_PERIODIC (1U << 31)
#define MR_KTIMER_PERIODIC (1U << 31)
/* Ktimer type */
typedef struct mr_ktimer {
@@ -96,6 +100,34 @@ mr_err_t mr_ktimer_stop(mr_ktimer_t *ktimer);
*/
mr_err_t mr_ktimer_tick_set(mr_ktimer_t *ktimer, mr_tick_t tick);
/**
* @brief This function find a ktimer.
*
* @param name The ktimer name.
* @return The ktimer on success, or MR_NULL on failure.
*/
mr_ktimer_t *mr_ktimer_find(const char *name);
/**
* @brief This function get a ktimer.
*
* @param ktimer The ktimer.
* @return The ktimer on success, or MR_NULL on failure.
*/
MR_INLINE mr_ktimer_t *mr_ktimer_get(mr_ktimer_t *ktimer) {
return (mr_ktimer_t *)mr_kobject_get((mr_kobject_t *)ktimer);
}
/**
* @brief This function put a ktimer.
*
* @param ktimer The ktimer.
*/
MR_INLINE void mr_ktimer_put(mr_ktimer_t *ktimer) {
mr_kobject_put((mr_kobject_t *)ktimer);
}
#endif /* defined(MR_USE_KTIMER) */
/** @} */
#ifdef __cplusplus

View File

@@ -13,7 +13,7 @@
#include <libc/mr_types.h>
#if !defined(__CC_ARM) && !defined(__GNUC__) && !defined(__clang__)
#include <arch/mr_hw_irq.h>
#endif /* defined(__CC_ARM) || defined(__GNUC__) || defined(__clang__) */
#endif /* !defined(__CC_ARM) && !defined(__GNUC__) && !defined(__clang__) */
#ifdef __cplusplus
extern "C" {

View File

@@ -1,42 +0,0 @@
/**
* @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

@@ -126,6 +126,15 @@ char *mr_strerror(int errnum);
*/
mr_size_t mr_strlen(const char *s);
/**
* @brief This function returns the length of the string.
*
* @param s The string.
* @param size The maximum length of the string.
* @return The length of the string.
*/
mr_size_t mr_strnlen(const char *s, mr_size_t size);
/**
* @brief This function compares the first size bytes of s1 and s2.
*

View File

@@ -10,12 +10,12 @@
#define __MR_TYPES_H__
#include <mr_config.h>
#ifdef MR_USE_LIBC_TYPES
#if defined(MR_USE_LIBC_TYPES)
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#endif /* MR_USE_LIBC_TYPES */
#endif /* defined(MR_USE_LIBC_TYPES) */
#ifdef __cplusplus
extern "C" {
@@ -27,7 +27,7 @@ extern "C" {
*/
/* Signed integer type */
#ifdef MR_USE_LIBC_TYPES
#if defined(MR_USE_LIBC_TYPES)
typedef int8_t mr_int8_t;
typedef int16_t mr_int16_t;
typedef int32_t mr_int32_t;
@@ -41,21 +41,18 @@ typedef signed char mr_int8_t;
typedef signed short mr_int16_t;
typedef signed int mr_int32_t;
typedef signed long long mr_int64_t;
typedef long long mr_ssize_t;
#define MR_INT8_MAX (127)
#define MR_INT16_MAX (32767)
#define MR_INT32_MAX (2147483647U)
#define MR_INT64_MAX (9223372036854775807LL)
#endif /* MR_USE_LIBC_TYPES */
#endif /* defined(MR_USE_LIBC_TYPES) */
/* Unsigned integer type */
#ifdef MR_USE_LIBC_TYPES
#if defined(MR_USE_LIBC_TYPES)
typedef uint8_t mr_uint8_t;
typedef uint16_t mr_uint16_t;
typedef uint32_t mr_uint32_t;
typedef uint64_t mr_uint64_t;
typedef size_t mr_size_t;
typedef long mr_ssize_t;
#define MR_UINT8_MAX UINT8_MAX
#define MR_UINT16_MAX UINT16_MAX
#define MR_UINT32_MAX UINT32_MAX
@@ -65,15 +62,28 @@ typedef unsigned char mr_uint8_t;
typedef unsigned short mr_uint16_t;
typedef unsigned int mr_uint32_t;
typedef unsigned long long mr_uint64_t;
typedef unsigned long long mr_size_t;
#define MR_UINT8_MAX (255)
#define MR_UINT16_MAX (65535)
#define MR_UINT32_MAX (4294967295)
#define MR_UINT64_MAX (18446744073709551615ULL)
#endif /* MR_USE_LIBC_TYPES */
#endif /* defined(MR_USE_LIBC_TYPES) */
/* Size type */
#if defined(MR_USE_LIBC_TYPES)
typedef size_t mr_size_t;
typedef ssize_t mr_ssize_t;
#else
#if defined(MR_USE_ARCH_64BIT)
typedef unsigned long long mr_size_t;
typedef long long mr_ssize_t;
#else
typedef unsigned int mr_size_t;
typedef int mr_ssize_t;
#endif /* defined(MR_USE_ARCH_64BIT) */
#endif /* defined(MR_USE_ARCH_64BIT) */
/* Boolean type */
#ifdef MR_USE_LIBC_TYPES
#if defined(MR_USE_LIBC_TYPES)
typedef bool mr_bool_t;
#define MR_FALSE false
#define MR_TRUE true
@@ -81,42 +91,40 @@ typedef bool mr_bool_t;
typedef int mr_bool_t;
#define MR_FALSE (0)
#define MR_TRUE (1)
#endif /* MR_USE_LIBC_TYPES */
#endif /* defined(MR_USE_LIBC_TYPES) */
/* Pointer type */
#ifdef MR_USE_LIBC_TYPES
#if defined(MR_USE_LIBC_TYPES)
typedef void * mr_ptr_t;
typedef intptr_t mr_intptr_t;
typedef uintptr_t mr_uintptr_t;
#define MR_NULL NULL
#else
typedef void * mr_ptr_t;
typedef long long mr_intptr_t;
typedef unsigned long long mr_uintptr_t;
typedef mr_ssize_t mr_intptr_t;
typedef mr_size_t mr_uintptr_t;
#define MR_NULL ((void *)0)
#endif /* MR_USE_LIBC_TYPES */
#endif /* defined(MR_USE_LIBC_TYPES) */
/* Floating point type */
typedef float mr_f32_t;
typedef double mr_f64_t;
/* Variable argument list type */
#ifdef MR_USE_LIBC_TYPES
#if defined(MR_USE_LIBC_TYPES)
typedef va_list mr_va_list;
#define mr_va_start(_ap, _n) va_start(_ap, _n)
#define mr_va_arg(_ap, _t) va_arg(_ap, _t)
#define mr_va_end(_ap) va_end(_ap)
#define mr_va_start(_a, _l) va_start(_a, _l)
#define mr_va_arg(_a, _t) va_arg(_a, _t)
#define mr_va_end(_a) va_end(_a)
#else
typedef char * mr_va_list;
#define __mr_va_rounded_size(_t) \
(((sizeof(_t) + sizeof(int) - 1) / sizeof(int)) * sizeof(int))
#define mr_va_start(_ap, _n) \
((_ap) = (char *)&(_n) + __mr_va_rounded_size(_n))
#define mr_va_arg(_ap, _type) \
((_ap) += __mr_va_rounded_size(_type), \
*((_type *)((_ap)-__mr_va_rounded_size(_type))))
#define mr_va_end(_ap) ((_ap) = (mr_va_list)0)
#endif /* MR_USE_LIBC_TYPES */
#define mr_va_start(_a, _l) ((_a) = (mr_va_list)&(_l) + sizeof(_l))
#define __mr_va_align(_p, _t) \
((mr_va_list)(((mr_size_t)(_p) + sizeof(_t) - 1) & ~(sizeof(_t) - 1)))
#define mr_va_arg(_a, _t) \
((_a) = __mr_va_align(_a, _t) + sizeof(_t), *(_t *)((_a) - sizeof(_t)))
#define mr_va_end(_a) ((_a) = (mr_va_list)0)
#endif /* defined(MR_USE_LIBC_TYPES) */
/** @} */

View File

@@ -5,9 +5,6 @@
extern "C" {
#endif /* __cplusplus */
#define MR_USE_LIBC_PRINTF
//#define MR_USE_LIBC_MALLOC
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@@ -17,7 +17,9 @@ static mr_atomic_t kclock;
#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) */
/* Clock hook entry */
static mr_ptr_t kentry[MR_CFG_KCLOCK_HOOK_SIZE];
/* Clock hook */
static mr_khook_t khook = MR_KHOOK_INIT(kentry, MR_CFG_KCLOCK_HOOK_SIZE);
MR_INLINE void kclock_hook(void) {

View File

@@ -1,100 +0,0 @@
/**
* @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, (mr_uint8_t *)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((mr_uint8_t *)buf + s, kfifo->buf, size - s);
return size;
}

View File

@@ -1,202 +0,0 @@
/**
* @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->next = kmap->b[index];
node->key = key;
node->value = value;
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

@@ -12,14 +12,15 @@
#include <libc/mr_printf.h>
#include <libc/mr_string.h>
/* Kobject lock */
static mr_kspinlock_t klock = MR_KSPINLOCK_INIT();
/* Kobject kset */
static mr_kset_t kroot = MR_KSET_INIT(&kroot, MR_NULL);
/* Last-word definition */
#define LWORD_DOT (0x2e)
#define LWORD_DOT2 (0x2e2e)
/* Root kset */
static mr_kspinlock_t klock = MR_KSPINLOCK_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 *kobj)) {
/* Check arguments */
if (!type) {

View File

@@ -7,7 +7,9 @@
*/
#include <kernel/kos/mr_kos.h>
#if defined(MR_USE_KOS)
/* Kos */
static mr_kos_t kroot;
MR_INLINE void kos_init(mr_kos_t *os, mr_kos_type_t *ktype) {
@@ -41,3 +43,4 @@ mr_kos_t *mr_kos_find(void) {
/* Find kos in kroot */
return &kroot;
}
#endif /* defined(MR_USE_KOS) */

View File

@@ -7,13 +7,19 @@
*/
#include <kernel/kos/mr_kthread.h>
#if defined(MR_USE_KOS)
#include <kernel/mr_initcall.h>
#include <libc/mr_malloc.h>
#include <libc/mr_string.h>
/* Kthread ktype */
static mr_ktype_t ktype1, ktype2;
/* Kthread kset */
static mr_kset_t kroot = MR_KSET_INIT(&kroot, MR_NULL);
/* Kthread ops macro */
#define KOS_KTHREAD_OPS(_kos) ((_kos)->type->kth_type->ops)
MR_INLINE mr_err_t kthread_res_alloc(mr_kthread_t *kth, mr_size_t size) {
void *res;
@@ -70,8 +76,8 @@ MR_INLINE mr_err_t kthread_init(mr_kthread_t *kth, const char *name,
}
/* Init kthread resource */
ret = MR_KOS_KTH_OPS(kos)->init((void *)kth->res, name, kth, stack,
stack_size, priority, tick);
ret = KOS_KTHREAD_OPS(kos)->init((void *)kth->res, name, kth, stack,
stack_size, priority, tick);
if (ret != 0) {
kthread_res_free(kth);
return ret;
@@ -94,7 +100,7 @@ MR_INLINE mr_err_t kthread_del(mr_kthread_t *kth) {
}
/* Delete kthread resource */
return MR_KOS_KTH_OPS(kth->os)->del((void *)kth->res);
return KOS_KTHREAD_OPS(kth->os)->del((void *)kth->res);
}
MR_INLINE mr_err_t kthread_init_add(mr_kthread_t *kth, mr_ktype_t *ktype,
@@ -237,7 +243,7 @@ MR_INLINE mr_err_t kthread_startup(mr_kthread_t *kth) {
mr_kthread_get(kth);
/* Startup kthread resource */
ret = MR_KOS_KTH_OPS(kth->os)->startup((void *)kth->res);
ret = KOS_KTHREAD_OPS(kth->os)->startup((void *)kth->res);
if (ret != 0) {
mr_kthread_put(kth);
return ret;
@@ -257,7 +263,7 @@ mr_err_t mr_kthread_startup(mr_kthread_t *kth) {
MR_INLINE mr_err_t kthread_resume(mr_kthread_t *kth) {
/* Resume kthread resource */
return MR_KOS_KTH_OPS(kth->os)->resume((void *)kth->res);
return KOS_KTHREAD_OPS(kth->os)->resume((void *)kth->res);
}
mr_err_t mr_kthread_resume(mr_kthread_t *kth) {
@@ -281,7 +287,7 @@ MR_INLINE mr_err_t kthread_yield(void) {
}
/* Yield kthread resource */
ret = MR_KOS_KTH_OPS(kos)->yield();
ret = KOS_KTHREAD_OPS(kos)->yield();
/* Put kos */
mr_kos_put(kos);
@@ -295,7 +301,7 @@ mr_err_t mr_kthread_yield(void) {
MR_INLINE mr_err_t kthread_suspend(mr_kthread_t *kth) {
/* Suspend kthread resource */
return MR_KOS_KTH_OPS(kth->os)->suspend((void *)kth->res);
return KOS_KTHREAD_OPS(kth->os)->suspend((void *)kth->res);
}
mr_err_t mr_kthread_suspend(mr_kthread_t *kth) {
@@ -319,7 +325,7 @@ MR_INLINE mr_err_t kthread_sleep(mr_tick_t tick) {
}
/* Sleep kthread resource */
ret = MR_KOS_KTH_OPS(kos)->sleep(tick);
ret = KOS_KTHREAD_OPS(kos)->sleep(tick);
/* Put kos */
mr_kos_put(kos);
@@ -333,7 +339,7 @@ mr_err_t mr_kthread_sleep(mr_tick_t tick) {
MR_INLINE mr_err_t kthread_exit(mr_kthread_t *kth) {
/* Exit kthread resource */
return MR_KOS_KTH_OPS(kth->os)->exit((void *)kth->res);
return KOS_KTHREAD_OPS(kth->os)->exit((void *)kth->res);
}
mr_err_t mr_kthread_exit(mr_kthread_t *kth) {
@@ -357,7 +363,7 @@ MR_INLINE mr_kthread_t *kthread_self(void) {
}
/* Get kthread self */
ret = MR_KOS_KTH_OPS(kos)->self();
ret = KOS_KTHREAD_OPS(kos)->self();
/* Put kos */
mr_kos_put(kos);
@@ -369,11 +375,6 @@ mr_kthread_t *mr_kthread_self(void) {
return kthread_self();
}
mr_kthread_t *mr_kthread_find(const char *name) {
/* Lookup kthread in kroot */
return (mr_kthread_t *)mr_kobject_lookup((mr_kobject_t *)&kroot, name);
}
void mr_kthread_cleanup(mr_kthread_t *kth) {
/* Check arguments */
if ((!kth) || (!MR_KOBJECT_IS_INITED(kth))) {
@@ -385,8 +386,8 @@ void mr_kthread_cleanup(mr_kthread_t *kth) {
}
void mr_kthread_entry(mr_kthread_t *kth) {
/* Check entry */
if (!kth->entry) {
/* Check arguments */
if ((!kth) || (!MR_KOBJECT_IS_INITED(kth)) || (!kth->entry)) {
return;
}
@@ -394,6 +395,11 @@ void mr_kthread_entry(mr_kthread_t *kth) {
((void (*)(mr_kthread_t *, void *))kth->entry)(kth, kth->args);
}
mr_kthread_t *mr_kthread_find(const char *name) {
/* Lookup kthread in kroot */
return (mr_kthread_t *)mr_kobject_lookup((mr_kobject_t *)&kroot, name);
}
MR_INLINE mr_kthread_t *kthread_release_kobj(mr_kobject_t *kobj) {
mr_kthread_t *kth;
@@ -416,7 +422,7 @@ MR_INLINE void kthread_release1_kobj(mr_kobject_t *kobj) {
MR_INLINE void kthread_release2_kobj(mr_kobject_t *kobj) {
mr_kthread_t *kth;
/* Release kobject */
/* Release kthread */
kth = kthread_release_kobj(kobj);
/* Free kthread */
@@ -432,3 +438,4 @@ MR_INLINE void mr_kthread_kset_init(void) {
mr_ktype_init(&ktype2, kthread_release2_kobj);
}
MR_INIT_EXPORT(mr_kthread_kset_init, MR_INIT_LEVEL_KERNEL);
#endif /* defined(MR_USE_KOS) */

View File

@@ -6,15 +6,20 @@
* @date 2024-09-06 MacRsh First version
*/
#include <kernel/mr_ktimer.h>
#if defined(MR_USE_KTIMER)
#include <kernel/mr_initcall.h>
#include <kernel/mr_kspinlock.h>
#include <kernel/mr_ktimer.h>
#include <libc/mr_malloc.h>
/* Ktimer ktype */
static mr_ktype_t ktype1, ktype2;
static mr_kset_t kroot = MR_KSET_INIT(&kroot, MR_NULL);
/* Ktimer list */
static mr_klist_t klist = MR_KLIST_INIT(&klist);
/* Ktimer lock */
static mr_kspinlock_t klock = MR_KSPINLOCK_INIT();
/* Ktimer kset */
static mr_kset_t kroot = MR_KSET_INIT(&kroot, MR_NULL);
MR_INLINE void ktimer_init(mr_ktimer_t *ktimer, mr_ptr_t entry, void *args,
mr_tick_t tick) {
@@ -84,14 +89,11 @@ MR_INLINE void ktimer_del(mr_ktimer_t *ktimer) {
/* Lock */
mask = mr_kspinlock_lock_irqsave(&klock);
/* Already deleted */
if (mr_klist_is_empty(&ktimer->list)) {
goto _exit;
/* Remove ktimer from ktimer list */
if (!mr_klist_is_empty(&ktimer->list)) {
mr_klist_del(&ktimer->list);
}
/* Remove ktimer from ktimer list */
mr_klist_del(&ktimer->list);
_exit:
/* Unlock */
mr_kspinlock_unlock_irqrestore(&klock, mask);
}
@@ -176,6 +178,11 @@ MR_INLINE void ktimer_tick_set(mr_ktimer_t *ktimer, mr_tick_t tick) {
/* Lock */
mask = mr_kspinlock_lock_irqsave(&klock);
/* Remove ktimer from ktimer list */
if (!mr_klist_is_empty(&ktimer->list)) {
mr_klist_del(&ktimer->list);
}
/* Set init tick */
ktimer->init_tick = tick;
@@ -189,15 +196,17 @@ mr_err_t mr_ktimer_tick_set(mr_ktimer_t *ktimer, mr_tick_t tick) {
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 *mr_ktimer_find(const char *name) {
/* Lookup ktimer in kroot */
return (mr_ktimer_t *)mr_kobject_lookup((mr_kobject_t *)&kroot, name);
}
MR_INLINE mr_ktimer_t *ktimer_release_kobj(mr_kobject_t *kobj) {
mr_ktimer_t *ktimer;
/* Get ktimer */
@@ -205,16 +214,19 @@ MR_INLINE void ktimer_release1_kobj(mr_kobject_t *kobj) {
/* Delete ktimer */
ktimer_del(ktimer);
return ktimer;
}
MR_INLINE void ktimer_release1_kobj(mr_kobject_t *kobj) {
/* Release ktimer */
ktimer_release_kobj(kobj);
}
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);
/* Release ktimer */
ktimer = ktimer_release_kobj(kobj);
/* Free ktimer */
mr_free(ktimer);
@@ -223,9 +235,11 @@ MR_INLINE void ktimer_release2_kobj(mr_kobject_t *kobj) {
MR_INLINE void ktimer_timeout_check(void) {
mr_ktimer_t *ktimer;
mr_klist_t list;
mr_tick_t tick;
int mask;
/* Operation list */
mr_klist_init(&list);
/* Lock */
mask = mr_kspinlock_lock_irqsave(&klock);
@@ -233,15 +247,13 @@ MR_INLINE void ktimer_timeout_check(void) {
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)) {
/* Check timeout tick */
if ((mr_kclock_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 */
@@ -288,3 +300,4 @@ MR_INLINE void mr_ktimer_kset_init(void) {
mr_kclock_hook_add(ktimer_timeout_check);
}
MR_INIT_EXPORT(mr_ktimer_kset_init, MR_INIT_LEVEL_KERNEL);
#endif /* defined(MR_USE_KTIMER) */

View File

@@ -9,15 +9,16 @@
#include <libc/mr_malloc.h>
#if (!defined(MR_USE_LIBC_MALLOC)) && (!defined(MR_USE_3PARTY_MALLOC))
#include <arch/mr_hw_irq.h>
#include <libc/mr_string.h>
#if !defined(MR_CFG_HEAP_SIZE)
#define MR_CFG_HEAP_SIZE (4 * 1024)
#endif /* !defined(MR_CFG_HEAP_SIZE) */
#if (MR_CFG_HEAP_SIZE < 16)
#if (MR_CFG_HEAP_SIZE < 24)
#error "Heap size is too small(must >= 16)"
#endif /* MR_CFG_HEAP_SIZE */
/* Heap memory */
static mr_uint8_t heap[MR_CFG_HEAP_SIZE];
/* Heap block head */
static mr_memblk_t blk_head = {.size = 1};
/* Heap magic number */
@@ -170,7 +171,8 @@ mr_size_t mr_malloc_usable_size(void *mem) {
void *mr_calloc(mr_size_t num, mr_size_t size) {
mr_size_t total;
void *memory;
mr_size_t i;
void *mem;
/* Calculate the total size */
total = num * size;
@@ -178,20 +180,23 @@ void *mr_calloc(mr_size_t num, mr_size_t size) {
return MR_NULL;
}
/* Allocate memory */
memory = mr_malloc(total);
if (memory == MR_NULL) {
/* Not enough memory */
/* Allocate mem */
mem = mr_malloc(total);
if (mem == MR_NULL) {
/* Not enough mem */
return MR_NULL;
}
/* Initialize the memory to 0 */
mr_memset(memory, 0, total);
return memory;
/* Initialize the mem to 0 */
for (i = 0; i < total; i++) {
((mr_uint8_t *)mem)[i] = 0;
}
return mem;
}
void *mr_realloc(void *mem, mr_size_t size) {
mr_size_t old_size;
mr_size_t i;
void *new;
/* Get the old size */
@@ -205,7 +210,9 @@ void *mr_realloc(void *mem, mr_size_t size) {
}
/* Copy the memory data to the new memory */
mr_memcpy(new, mem, old_size);
for (i = 0; i < old_size; i++) {
((mr_uint8_t *)new)[i] = ((mr_uint8_t *)mem)[i];
}
mr_free(mem);
return new;
}

View File

@@ -126,6 +126,10 @@ char *mr_strerror(int errnum) {
error = "Invalid argument";
break;
}
case MR_ENOSYS: {
error = "Function not implemented";
break;
}
case MR_ETIMEDOUT: {
error = "Connection timed out";
break;
@@ -149,6 +153,18 @@ mr_size_t mr_strlen(const char *s) {
return len;
}
mr_size_t mr_strnlen(const char *s, mr_size_t size) {
mr_size_t len;
if (!s) {
return 0;
}
for (len = 0; (len < size) && (*s != '\0'); s++) {
len++;
}
return len;
}
int mr_strncmp(const char *s1, const char *s2, mr_size_t size) {
return mr_memcmp(s1, s2, size);
}