feat(ref,malloc): Optimize the magic number of memory.
1.Reference counting supports the selection of long count (short identifier) and short count (long identifier), and can be chosen between memory clarity and the upper limit of reference counting.
This commit is contained in:
@@ -35,8 +35,12 @@ extern "C" {
|
||||
#define mr_realloc(_m, _sz) realloc(_m, _sz)
|
||||
#else
|
||||
#if defined(MR_USE_MALLOC)
|
||||
/* Memory block magic definition */
|
||||
#define MR_MEMBLK_MAGIC (0x6d725800U)
|
||||
|
||||
/* Memory block type */
|
||||
typedef struct MR_ALIGN(MR_ALIGN_SIZE) mr_memblk {
|
||||
volatile mr_uint32_t magic;
|
||||
struct mr_memblk *next;
|
||||
mr_size_t size;
|
||||
} mr_memblk_t;
|
||||
|
||||
@@ -7,6 +7,13 @@ config MR_USE_ENTRY
|
||||
bool "Use entry"
|
||||
default n
|
||||
|
||||
# ==================================
|
||||
# REF
|
||||
# ==================================
|
||||
config MR_USE_REF_LONG_COUNT
|
||||
bool "Use ref long count"
|
||||
default n
|
||||
|
||||
# ==================================
|
||||
# CLOCK
|
||||
# ==================================
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#define __MR_INITCALL_H__
|
||||
|
||||
#include <libc/mr_compiler.h>
|
||||
#include <libc/mr_assert.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -30,8 +29,8 @@ typedef void(mr_initcall_entry_t)(void);
|
||||
|
||||
/* Initcall type */
|
||||
typedef struct MR_ALIGN(MR_ALIGN_SIZE) mr_initcall {
|
||||
mr_initcall_entry_t *entry;
|
||||
const char *name;
|
||||
mr_initcall_entry_t *entry;
|
||||
} mr_initcall_t;
|
||||
|
||||
/**
|
||||
|
||||
@@ -29,12 +29,12 @@ extern "C" {
|
||||
|
||||
#if defined(MR_USE_IRQ)
|
||||
/* Irq flag definition */
|
||||
#define MR_IRQ_EDGE_RISING (0x01)
|
||||
#define MR_IRQ_EDGE_FALLING (0x02)
|
||||
#define MR_IRQ_EDGE_BOTH (0x03)
|
||||
#define MR_IRQ_LEVEL_HIGH (0x04)
|
||||
#define MR_IRQ_LEVEL_LOW (0x08)
|
||||
#define MR_IRQ_SHARED (0x10)
|
||||
#define MR_IRQ_EDGE_RISING (0x01U)
|
||||
#define MR_IRQ_EDGE_FALLING (0x02U)
|
||||
#define MR_IRQ_EDGE_BOTH (0x03U)
|
||||
#define MR_IRQ_LEVEL_HIGH (0x04U)
|
||||
#define MR_IRQ_LEVEL_LOW (0x08U)
|
||||
#define MR_IRQ_SHARED (0x10U)
|
||||
|
||||
/* Irq return definition */
|
||||
typedef enum mr_irq_return {
|
||||
|
||||
@@ -35,8 +35,8 @@ typedef struct mr_clazz {
|
||||
|
||||
/* Object type */
|
||||
typedef struct mr_object {
|
||||
mr_ref_t magic_ref;
|
||||
const mr_clazz_t *clazz;
|
||||
mr_ref_t ref;
|
||||
} mr_object_t;
|
||||
|
||||
/**
|
||||
@@ -69,7 +69,7 @@ MR_INLINE void mr_clazz_init(mr_clazz_t *clazz, const char *name,
|
||||
* @param _clazz The clazz.
|
||||
*/
|
||||
#define MR_OBJECT_INIT(_obj, _clazz) \
|
||||
{ .clazz = (_clazz), .ref = MR_REF_INIT() }
|
||||
{ .magic_ref = MR_REF_INIT(), .clazz = (_clazz) }
|
||||
|
||||
/**
|
||||
* @brief This function initializes an object.
|
||||
@@ -87,7 +87,7 @@ mr_err_t mr_object_init(mr_object_t *obj, const mr_clazz_t *clazz);
|
||||
* @return MR_TRUE on initialized, MR_FALSE otherwise.
|
||||
*/
|
||||
#define MR_OBJECT_IS_INITED(_obj) \
|
||||
(MR_REF_IS_INITED(((mr_object_t *)(_obj))->ref))
|
||||
(MR_REF_IS_INITED(((mr_object_t *)(_obj))->magic_ref))
|
||||
|
||||
/**
|
||||
* @brief This macro function checks if an object is of a clazz.
|
||||
|
||||
@@ -21,9 +21,17 @@ extern "C" {
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Ref magic definition */
|
||||
#define MR_REF_MAGIC (0x6d720000)
|
||||
#define MR_REF_OVERFLOW (0x6d730000)
|
||||
#if defined(MR_USE_REF_LONG_COUNT)
|
||||
/* Ref magic definition(16bits ref-count) */
|
||||
#define MR_REF_MAGIC (0x6d720000U)
|
||||
#define MR_REF_MAGIC_MASK (0xffff0000U)
|
||||
#define MR_REF_OVERFLOW (0x6d730000U)
|
||||
#else
|
||||
/* Ref magic definition(8bits ref-count) */
|
||||
#define MR_REF_MAGIC (0x6d725800U)
|
||||
#define MR_REF_MAGIC_MASK (0xffffff00U)
|
||||
#define MR_REF_OVERFLOW (0x6d725900U)
|
||||
#endif /* defined(MR_USE_REF_LONG_COUNT) */
|
||||
|
||||
/* Ref type */
|
||||
typedef volatile mr_atomic_t mr_ref_t;
|
||||
@@ -34,7 +42,7 @@ typedef void(mr_ref_release_t)(mr_ref_t *ref);
|
||||
/**
|
||||
* @brief This macro function initializes a ref.
|
||||
*/
|
||||
#define MR_REF_INIT() MR_ATOMIC_INIT(MR_REF_MAGIC | 0x0001)
|
||||
#define MR_REF_INIT() MR_ATOMIC_INIT(MR_REF_MAGIC | 0x0001U)
|
||||
|
||||
/**
|
||||
* @brief This macro function checks if a ref is initialized.
|
||||
@@ -43,7 +51,7 @@ typedef void(mr_ref_release_t)(mr_ref_t *ref);
|
||||
* @return MR_TRUE on initialized, MR_FALSE otherwise.
|
||||
*/
|
||||
#define MR_REF_IS_INITED(_ref) \
|
||||
(((_ref) & 0xffff0000) == MR_REF_MAGIC)
|
||||
(((_ref) & MR_REF_MAGIC_MASK) == MR_REF_MAGIC)
|
||||
|
||||
/**
|
||||
* @brief This macro function gets the ref count.
|
||||
@@ -60,7 +68,7 @@ typedef void(mr_ref_release_t)(mr_ref_t *ref);
|
||||
*/
|
||||
MR_INLINE void mr_ref_init(mr_ref_t *ref) {
|
||||
/* Init ref(endow with an effective life cycle) */
|
||||
mr_atomic_init(ref, MR_REF_MAGIC | 0x0001);
|
||||
mr_atomic_init(ref, MR_REF_MAGIC | 0x0001U);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
#include <libc/mr_assert.h>
|
||||
#include <libc/mr_atomic.h>
|
||||
|
||||
/* Clock tick */
|
||||
static mr_atomic_t __tick;
|
||||
/* Clock hook entry */
|
||||
#if !defined(MR_CFG_CLOCK_HOOK_SIZE)
|
||||
#define MR_CFG_CLOCK_HOOK_SIZE (2)
|
||||
@@ -23,6 +21,8 @@ static mr_atomic_t __tick;
|
||||
static mr_ptr_t __entry[MR_CFG_CLOCK_HOOK_SIZE];
|
||||
/* Clock hook */
|
||||
static mr_hook_t __hook = MR_HOOK_INIT(__entry, MR_CFG_CLOCK_HOOK_SIZE);
|
||||
/* Clock tick */
|
||||
static mr_atomic_t __tick = MR_ATOMIC_INIT(0);
|
||||
|
||||
static mr_tick_t clock_hook(void) {
|
||||
mr_tick_t tickless, less;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
#include <mr-X/mr_initcall.h>
|
||||
#include <libc/mr_assert.h>
|
||||
#include <libc/mr_types.h>
|
||||
|
||||
/* Kernel and user init status */
|
||||
|
||||
12
kernel/irq.c
12
kernel/irq.c
@@ -34,12 +34,12 @@ static mr_irq_desc_t __table[MR_CFG_IRQ_TABLE_SIZE];
|
||||
static mr_irq_defer_hook_t __hook = {.wakeup = MR_NULL, .suspend = MR_NULL};
|
||||
#endif /* defined(MR_USE_IRQ_DEFER_HOOK) */
|
||||
|
||||
/* Irq priority default definition */
|
||||
#define IRQ_PRIORITY_DEFAULT (0)
|
||||
/* Irq flags definition */
|
||||
#define IRQ_FLAG_TYPE_MASK (0x0fU)
|
||||
/* Irq action pending definition */
|
||||
#define IRQ_ACTION_PENDING (1U << 31)
|
||||
/* Irq flags definition */
|
||||
#define IRQ_FLAG_TYPE_MASK (0x0fU)
|
||||
/* Irq priority default definition */
|
||||
#define IRQ_PRIORITY_DEFAULT (0)
|
||||
|
||||
static mr_err_t irq_table_insert(mr_irq_t *irq, mr_uint32_t irq_start,
|
||||
mr_uint32_t irq_end) {
|
||||
@@ -190,7 +190,7 @@ mr_err_t mr_irq_del(mr_irq_t *irq) {
|
||||
MR_ASSERT((irq != MR_NULL) && MR_OBJECT_IS_INITED(irq));
|
||||
MR_ASSERT(MR_OBJECT_CLAZZ_IS_OR(irq, &__clazz1, &__clazz2));
|
||||
|
||||
/* Mark as dying */
|
||||
/* Mark irq as dying */
|
||||
mr_atomic_store(&irq->dying, MR_TRUE);
|
||||
|
||||
/* Delete object */
|
||||
@@ -773,7 +773,7 @@ mr_err_t mr_irq_defer_hook_set(mr_irq_defer_hook_t *hook) {
|
||||
static void irq_del(mr_irq_t *irq) {
|
||||
int mask;
|
||||
|
||||
/* Mark as dying */
|
||||
/* Mark irq as dying */
|
||||
mr_atomic_store(&irq->dying, MR_TRUE);
|
||||
|
||||
/* Lock */
|
||||
|
||||
@@ -16,8 +16,8 @@ mr_err_t mr_object_init(mr_object_t *obj, const mr_clazz_t *clazz) {
|
||||
}
|
||||
|
||||
/* Init object */
|
||||
mr_ref_init(&obj->magic_ref);
|
||||
obj->clazz = clazz;
|
||||
mr_ref_init(&obj->ref);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ mr_object_t *mr_object_get(mr_object_t *obj) {
|
||||
}
|
||||
|
||||
/* Get object reference */
|
||||
return mr_ref_get(&obj->ref) ? obj : MR_NULL;
|
||||
return mr_ref_get(&obj->magic_ref) ? obj : MR_NULL;
|
||||
}
|
||||
|
||||
static void object_ref_release(mr_ref_t *ref) {
|
||||
@@ -46,7 +46,7 @@ static void object_ref_release(mr_ref_t *ref) {
|
||||
mr_object_t *obj;
|
||||
|
||||
/* Get object and clazz */
|
||||
obj = MR_CONTAINER_OF(ref, mr_object_t, ref);
|
||||
obj = MR_CONTAINER_OF(ref, mr_object_t, magic_ref);
|
||||
clazz = obj->clazz;
|
||||
|
||||
/* Call clazz release */
|
||||
@@ -62,5 +62,5 @@ mr_bool_t mr_object_put(mr_object_t *obj) {
|
||||
}
|
||||
|
||||
/* Put object reference */
|
||||
return mr_ref_put(&obj->ref, object_ref_release);
|
||||
return mr_ref_put(&obj->magic_ref, object_ref_release);
|
||||
}
|
||||
|
||||
@@ -40,9 +40,6 @@ static void queue_wakeup(mr_workqueue_t *queue) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get workqueue run-time(running) */
|
||||
mr_workqueue_get(queue);
|
||||
|
||||
/* Wakeup workqueue */
|
||||
#if defined(MR_USE_WORKQUEUE_HOOK)
|
||||
if (queue->hook.wakeup) {
|
||||
@@ -94,9 +91,6 @@ static void queue_timer_entry(mr_timer_t *timer, void *param) {
|
||||
} else if (mr_list_is_empty(&queue->tlist)) {
|
||||
/* Don't need timer */
|
||||
mr_timer_stop(&queue->timer);
|
||||
|
||||
/* Put workqueue run-time(timing) */
|
||||
mr_workqueue_put(queue);
|
||||
}
|
||||
|
||||
/* Unlock */
|
||||
@@ -170,7 +164,7 @@ mr_err_t mr_workqueue_del(mr_workqueue_t *queue) {
|
||||
MR_ASSERT((queue != MR_NULL) && MR_OBJECT_IS_INITED(queue));
|
||||
MR_ASSERT(MR_OBJECT_CLAZZ_IS_OR(queue, &__queue_clazz1, &__queue_clazz2));
|
||||
|
||||
/* Mark as dying */
|
||||
/* Mark workqueue as dying */
|
||||
mr_atomic_store(&queue->dying, MR_TRUE);
|
||||
|
||||
/* Delete object */
|
||||
@@ -179,17 +173,11 @@ mr_err_t mr_workqueue_del(mr_workqueue_t *queue) {
|
||||
}
|
||||
|
||||
static void queue_suspend(mr_workqueue_t *queue) {
|
||||
mr_atomic_t run;
|
||||
|
||||
/* Check if workqueue need suspend */
|
||||
mr_atomic_init(&run, MR_TRUE);
|
||||
if (!mr_atomic_compare_exchange(&queue->running, &run, MR_FALSE)) {
|
||||
if (mr_atomic_load(&queue->running)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Put workqueue run-time(running) */
|
||||
mr_workqueue_put(queue);
|
||||
|
||||
/* Suspend workqueue */
|
||||
#if defined(MR_USE_WORKQUEUE_HOOK)
|
||||
if (queue->hook.suspend) {
|
||||
@@ -241,6 +229,9 @@ mr_err_t mr_workqueue_execute(mr_workqueue_t *queue) {
|
||||
mask = mr_spinlock_lock_irqsave(&__lock);
|
||||
}
|
||||
|
||||
/* Mark workqueue as not running */
|
||||
mr_atomic_store(&queue->running, MR_FALSE);
|
||||
|
||||
/* Unlock */
|
||||
mr_spinlock_unlock_irqrestore(&__lock, mask);
|
||||
|
||||
@@ -323,12 +314,6 @@ mr_err_t mr_workqueue_delayed_work(mr_workqueue_t *queue, mr_work_t *work,
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
/* Check if workqueue is started for the first time */
|
||||
if (mr_list_is_empty(&queue->tlist)) {
|
||||
/* Get workqueue run-time(timing) */
|
||||
mr_workqueue_get(queue);
|
||||
}
|
||||
|
||||
/* Set timeout tick */
|
||||
tick = tick & ~MR_TIMER_PERIODIC;
|
||||
work->tick = mr_clock_tick() + tick;
|
||||
@@ -385,7 +370,7 @@ static void queue_del(mr_workqueue_t *queue) {
|
||||
mr_work_t *work;
|
||||
int mask;
|
||||
|
||||
/* Mark as dying */
|
||||
/* Mark workqueue as dying */
|
||||
mr_atomic_store(&queue->dying, MR_TRUE);
|
||||
|
||||
/* Delete workqueue timer */
|
||||
|
||||
@@ -106,6 +106,7 @@ void *mr_malloc(mr_size_t size) {
|
||||
prev->next = blk->next;
|
||||
blk->next = MR_NULL;
|
||||
blk->size = size;
|
||||
blk->magic = MR_MEMBLK_MAGIC;
|
||||
|
||||
/* Check if we need to allocate a new block */
|
||||
if (res > (sizeof(mr_memblk_t) << 2)) {
|
||||
@@ -114,6 +115,7 @@ void *mr_malloc(mr_size_t size) {
|
||||
/* Set the new block information */
|
||||
new->size = res - sizeof(mr_memblk_t);
|
||||
new->next = MR_NULL;
|
||||
new->magic = ~MR_MEMBLK_MAGIC;
|
||||
|
||||
/* Insert the new block */
|
||||
heap_insert_block(new);
|
||||
@@ -138,7 +140,7 @@ void mr_free(void *mem) {
|
||||
|
||||
/* Check the block */
|
||||
blk = (mr_memblk_t *)((mr_uint8_t *)mem - sizeof(mr_memblk_t));
|
||||
if (blk->size != 0) {
|
||||
if (blk->magic == MR_MEMBLK_MAGIC) {
|
||||
/* Insert the free block */
|
||||
heap_insert_block(blk);
|
||||
}
|
||||
@@ -157,6 +159,9 @@ mr_size_t mr_malloc_usable_size(void *mem) {
|
||||
|
||||
/* Get the block information */
|
||||
blk = (mr_memblk_t *)((mr_uint8_t *)mem - sizeof(mr_memblk_t));
|
||||
if (blk->magic != MR_MEMBLK_MAGIC) {
|
||||
return 0;
|
||||
}
|
||||
return blk->size;
|
||||
}
|
||||
|
||||
@@ -214,6 +219,7 @@ void mr_libc_malloc_init(void) {
|
||||
size = sizeof(__heap) - sizeof(mr_memblk_t);
|
||||
blk->size = size - offset;
|
||||
blk->next = MR_NULL;
|
||||
blk->magic = MR_MEMBLK_MAGIC;
|
||||
__blk_head.next = blk;
|
||||
__blk_head.size = 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user