mirror of
https://github.com/Ai-Thinker-Open/Ai-Thinker-Open_RTL8710BX_ALIOS_SDK.git
synced 2026-07-13 21:45:38 +00:00
rel_1.6.0 init
This commit is contained in:
commit
27b3e2883d
19359 changed files with 8093121 additions and 0 deletions
1
Living_SDK/kernel/rhino/.gitignore
vendored
Normal file
1
Living_SDK/kernel/rhino/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
out/
|
||||
4
Living_SDK/kernel/rhino/OWNER
Normal file
4
Living_SDK/kernel/rhino/OWNER
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
project : "AliOS",
|
||||
component : "rhino",
|
||||
}
|
||||
337
Living_SDK/kernel/rhino/common/k_atomic.c
Normal file
337
Living_SDK/kernel/rhino/common/k_atomic.c
Normal file
|
|
@ -0,0 +1,337 @@
|
|||
/*
|
||||
* Copyright (C) 2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
/*
|
||||
modification history
|
||||
--------------------
|
||||
2017_12_27,WangMin(Rocky) created.
|
||||
*/
|
||||
|
||||
/*
|
||||
* DESCRIPTION
|
||||
* This library is used to provide the atomic operators for CPU
|
||||
* which do not support native atomic operations.
|
||||
*
|
||||
* The design principle is disable the interrupt when execute the
|
||||
* atomic operations and enable the interrupt after finish the
|
||||
* operation.
|
||||
*
|
||||
* This library can be added into system by defining
|
||||
* RHINO_CONFIG_ATOMIC_GENERIC.
|
||||
*/
|
||||
|
||||
#include "k_api.h"
|
||||
#include "k_atomic.h"
|
||||
|
||||
/**
|
||||
* This routine atomically adds <*target> and <value>, placing the result in
|
||||
* <*target>. The operation is done using unsigned integer arithmetic.
|
||||
*
|
||||
* This routine can be used from both task and interrupt context.
|
||||
*
|
||||
* @param target memory location to add to
|
||||
* @param value the value to add
|
||||
*
|
||||
* @return The previous value from <target>
|
||||
*/
|
||||
|
||||
atomic_val_t rhino_atomic_add(atomic_t *target, atomic_val_t value)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
atomic_val_t old_value;
|
||||
|
||||
RHINO_CPU_INTRPT_DISABLE();
|
||||
|
||||
old_value = *target;
|
||||
*target += value;
|
||||
|
||||
RHINO_CPU_INTRPT_ENABLE();
|
||||
|
||||
return old_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine atomically subtracts <value> from <*target>, result is placed
|
||||
* in <*target>. The operation is done using unsigned integer arithmetic.
|
||||
*
|
||||
* This routine can be used from both task and interrupt context.
|
||||
*
|
||||
* @param target the memory location to subtract from
|
||||
* @param value the value to subtract
|
||||
*
|
||||
* @return The previous value from <target>
|
||||
*/
|
||||
|
||||
atomic_val_t rhino_atomic_sub(atomic_t *target, atomic_val_t value)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
atomic_val_t old_value;
|
||||
|
||||
RHINO_CPU_INTRPT_DISABLE();
|
||||
|
||||
old_value = *target;
|
||||
*target -= value;
|
||||
|
||||
RHINO_CPU_INTRPT_ENABLE();
|
||||
|
||||
return old_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine atomically increments the value in <*target>. The operation is
|
||||
* done using unsigned integer arithmetic.
|
||||
*
|
||||
* This routine can be used from both task and interrupt context.
|
||||
*
|
||||
* @return The value from <target> before the increment
|
||||
*/
|
||||
|
||||
atomic_val_t rhino_atomic_inc(atomic_t *target)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
atomic_val_t old_value;
|
||||
|
||||
RHINO_CPU_INTRPT_DISABLE();
|
||||
|
||||
old_value = *target;
|
||||
(*target)++;
|
||||
|
||||
RHINO_CPU_INTRPT_ENABLE();
|
||||
|
||||
return old_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine atomically decrement the value in <*target>. The operation is
|
||||
* done using unsigned integer arithmetic.
|
||||
*
|
||||
* This routine can be used from both task and interrupt context.
|
||||
*
|
||||
* @return The value from <target> before the increment
|
||||
*/
|
||||
|
||||
atomic_val_t rhino_atomic_dec(atomic_t *target)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
atomic_val_t old_value;
|
||||
|
||||
RHINO_CPU_INTRPT_DISABLE();
|
||||
|
||||
old_value = *target;
|
||||
(*target)--;
|
||||
|
||||
RHINO_CPU_INTRPT_ENABLE();
|
||||
|
||||
return old_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine atomically sets <*target> to <value> and returns the old value
|
||||
* that was in <*target>. Normally all CPU architectures can atomically write
|
||||
* to a variable of size atomic_t without the help of this routine.
|
||||
* This routine is intended for software that needs to atomically fetch and
|
||||
* replace the value of a memory location.
|
||||
*
|
||||
* This routine can be used from both task and interrupt context.
|
||||
*
|
||||
* @param target the memory location to write to
|
||||
* @param value the value to write
|
||||
*
|
||||
* @return The previous value from <target>
|
||||
*/
|
||||
|
||||
atomic_val_t rhino_atomic_set(atomic_t *target, atomic_val_t value)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
atomic_val_t old_value;
|
||||
|
||||
RHINO_CPU_INTRPT_DISABLE();
|
||||
|
||||
old_value = *target;
|
||||
*target = value;
|
||||
|
||||
RHINO_CPU_INTRPT_ENABLE();
|
||||
|
||||
return old_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine atomically read a value from <target>.
|
||||
* This routine can be used from both task and interrupt context.
|
||||
*
|
||||
* @return The value read from <target>
|
||||
*/
|
||||
|
||||
atomic_val_t rhino_atomic_get(const atomic_t *target)
|
||||
{
|
||||
return *target;
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine atomically performs a bitwise OR operation of <*target>
|
||||
* and <value>, placing the result in <*target>.
|
||||
*
|
||||
* This routine can be used from both task and interrupt context.
|
||||
*
|
||||
* @param target the memory location to be modified
|
||||
* @param value the value to OR
|
||||
*
|
||||
* @return The previous value from <target>
|
||||
*/
|
||||
|
||||
atomic_val_t rhino_atomic_or(atomic_t *target, atomic_val_t value)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
atomic_val_t old_value;
|
||||
|
||||
RHINO_CPU_INTRPT_DISABLE();
|
||||
|
||||
old_value = *target;
|
||||
*target |= value;
|
||||
|
||||
RHINO_CPU_INTRPT_ENABLE();
|
||||
|
||||
return old_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine atomically performs a bitwise XOR operation of <*target> and
|
||||
* <value>, placing the result in <*target>.
|
||||
*
|
||||
* This routine can be used from both task and interrupt context.
|
||||
*
|
||||
* @param target the memory location to be modified
|
||||
* @param value the value to XOR
|
||||
*
|
||||
* @return The previous value from <target>
|
||||
*/
|
||||
|
||||
atomic_val_t rhino_atomic_xor(atomic_t *target, atomic_val_t value)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
atomic_val_t old_value;
|
||||
|
||||
RHINO_CPU_INTRPT_DISABLE();
|
||||
|
||||
old_value = *target;
|
||||
*target ^= value;
|
||||
|
||||
RHINO_CPU_INTRPT_ENABLE();
|
||||
|
||||
return old_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine atomically performs a bitwise AND operation of <*target> and
|
||||
* <value>, placing the result in <*target>.
|
||||
*
|
||||
* This routine can be used from both task and interrupt context.
|
||||
*
|
||||
* @param target the memory location to be modified
|
||||
* @param value the value to AND
|
||||
*
|
||||
* @return The previous value from <target>
|
||||
*/
|
||||
|
||||
atomic_val_t rhino_atomic_and(atomic_t *target, atomic_val_t value)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
atomic_val_t old_value;
|
||||
|
||||
RHINO_CPU_INTRPT_DISABLE();
|
||||
|
||||
old_value = *target;
|
||||
*target &= value;
|
||||
|
||||
RHINO_CPU_INTRPT_ENABLE();
|
||||
|
||||
return old_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine atomically performs a bitwise NAND operation of <*target> and
|
||||
* <value>, placing the result in <*target>.
|
||||
*
|
||||
* This routine can be used from both task and interrupt context.
|
||||
*
|
||||
* @param target the memory location to be modified
|
||||
* @param value the value to NAND
|
||||
*
|
||||
* @return The previous value from <target>
|
||||
*/
|
||||
|
||||
atomic_val_t rhino_atomic_nand(atomic_t *target, atomic_val_t value)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
atomic_val_t old_value;
|
||||
|
||||
RHINO_CPU_INTRPT_DISABLE();
|
||||
|
||||
old_value = *target;
|
||||
*target = ~(*target & value);
|
||||
|
||||
RHINO_CPU_INTRPT_ENABLE();
|
||||
|
||||
return old_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine provides the atomic clear operator. The value of 0 is atomically
|
||||
* written at <target> and the previous value at <target> is returned.
|
||||
*
|
||||
* This routine can be used from both task and interrupt context.
|
||||
*
|
||||
* @param target the memory location to write
|
||||
*
|
||||
* @return The previous value from <target>
|
||||
*/
|
||||
|
||||
atomic_val_t rhino_atomic_clear(atomic_t *target)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
atomic_val_t old_value;
|
||||
|
||||
RHINO_CPU_INTRPT_DISABLE();
|
||||
|
||||
old_value = *target;
|
||||
*target = 0;
|
||||
|
||||
RHINO_CPU_INTRPT_ENABLE();
|
||||
|
||||
return old_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine performs an atomic compare-and-swap, it test that whether
|
||||
* <*target> equal to <oldValue>, and if TRUE, setting the value of <*target>
|
||||
* to <newValue> and return 1.
|
||||
*
|
||||
* If the original value at <target> does not equal <oldValue>, then the target
|
||||
* will not be updated and return 0.
|
||||
*
|
||||
* @param target address to be tested
|
||||
* @param old_value value to compare against
|
||||
* @param new_value value to compare against
|
||||
* @return Returns 1 if <new_value> is written, 0 otherwise.
|
||||
*/
|
||||
|
||||
int rhino_atomic_cas(atomic_t *target, atomic_val_t old_value,
|
||||
atomic_val_t new_value)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
int ret = 0;
|
||||
|
||||
RHINO_CPU_INTRPT_DISABLE();
|
||||
|
||||
if (*target == old_value)
|
||||
{
|
||||
*target = new_value;
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
RHINO_CPU_INTRPT_ENABLE();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
40
Living_SDK/kernel/rhino/common/k_atomic.h
Normal file
40
Living_SDK/kernel/rhino/common/k_atomic.h
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (C) 2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
/*
|
||||
modification history
|
||||
--------------------
|
||||
2017_12_27,WangMin(Rocky) created.
|
||||
*/
|
||||
|
||||
#ifndef K_ATOMIC_H
|
||||
#define K_ATOMIC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef unsigned int atomic_t;
|
||||
typedef atomic_t atomic_val_t;
|
||||
|
||||
extern atomic_val_t rhino_atomic_add(atomic_t *target, atomic_val_t value);
|
||||
extern atomic_val_t rhino_atomic_sub(atomic_t *target, atomic_val_t value);
|
||||
extern atomic_val_t rhino_atomic_inc(atomic_t *target);
|
||||
extern atomic_val_t rhino_atomic_dec(atomic_t *target);
|
||||
extern atomic_val_t rhino_atomic_set(atomic_t *target, atomic_val_t value);
|
||||
extern atomic_val_t rhino_atomic_get(const atomic_t *target);
|
||||
extern atomic_val_t rhino_atomic_or(atomic_t *target, atomic_val_t value);
|
||||
extern atomic_val_t rhino_atomic_xor(atomic_t *target, atomic_val_t value);
|
||||
extern atomic_val_t rhino_atomic_and(atomic_t *target, atomic_val_t value);
|
||||
extern atomic_val_t rhino_atomic_nand(atomic_t *target, atomic_val_t value);
|
||||
extern atomic_val_t rhino_atomic_clear(atomic_t *target);
|
||||
extern int rhino_atomic_cas(atomic_t *target, atomic_val_t old_value,
|
||||
atomic_val_t new_value);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* K_ATOMIC_H */
|
||||
|
||||
177
Living_SDK/kernel/rhino/common/k_fifo.c
Executable file
177
Living_SDK/kernel/rhino/common/k_fifo.c
Executable file
|
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
#include "k_fifo.h"
|
||||
|
||||
/*
|
||||
* internal helper to calculate the unused elements in a fifo
|
||||
*/
|
||||
static uint32_t fifo_unused(struct k_fifo *fifo)
|
||||
{
|
||||
return (fifo->mask + 1) - (fifo->in - fifo->out);
|
||||
}
|
||||
|
||||
static int8_t is_power_of_2(uint32_t n)
|
||||
{
|
||||
return (n != 0 && ((n & (n - 1)) == 0));
|
||||
}
|
||||
|
||||
int8_t fifo_init(struct k_fifo *fifo, void *buffer, uint32_t size)
|
||||
{
|
||||
/*
|
||||
* round down to the next power of 2, since our 'let the indices
|
||||
* wrap' technique works only in this case.
|
||||
*/
|
||||
if (!is_power_of_2(size)) {
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
fifo->in = 0;
|
||||
fifo->out = 0;
|
||||
fifo->data = buffer;
|
||||
|
||||
if (size < 2) {
|
||||
fifo->mask = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
fifo->mask = size - 1;
|
||||
fifo->free_bytes = size;
|
||||
fifo->size = size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void fifo_copy_in(struct k_fifo *fifo, const void *src,
|
||||
uint32_t len, uint32_t off)
|
||||
{
|
||||
uint32_t l;
|
||||
|
||||
uint32_t size = fifo->mask + 1;
|
||||
|
||||
off &= fifo->mask;
|
||||
|
||||
l = fifo_min(len, size - off);
|
||||
|
||||
memcpy((unsigned char *)fifo->data + off, src, l);
|
||||
memcpy(fifo->data, (unsigned char *)src + l, len - l);
|
||||
|
||||
|
||||
}
|
||||
|
||||
uint32_t fifo_in(struct k_fifo *fifo, const void *buf, uint32_t len)
|
||||
{
|
||||
uint32_t l;
|
||||
|
||||
CPSR_ALLOC();
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
|
||||
l = fifo_unused(fifo);
|
||||
|
||||
if (len > l) {
|
||||
len = l;
|
||||
}
|
||||
|
||||
fifo_copy_in(fifo, buf, len, fifo->in);
|
||||
fifo->in += len;
|
||||
|
||||
fifo->free_bytes -= len;
|
||||
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return len;
|
||||
}
|
||||
|
||||
static void kfifo_copy_out(struct k_fifo *fifo, void *dst,
|
||||
uint32_t len, uint32_t off)
|
||||
{
|
||||
uint32_t l;
|
||||
uint32_t size = fifo->mask + 1;
|
||||
|
||||
off &= fifo->mask;
|
||||
|
||||
l = fifo_min(len, size - off);
|
||||
|
||||
memcpy(dst, (unsigned char *)fifo->data + off, l);
|
||||
memcpy((unsigned char *)dst + l, fifo->data, len - l);
|
||||
|
||||
}
|
||||
|
||||
static uint32_t internal_fifo_out_peek(struct k_fifo *fifo,
|
||||
void *buf, uint32_t len)
|
||||
{
|
||||
uint32_t l;
|
||||
|
||||
l = fifo->in - fifo->out;
|
||||
|
||||
if (len > l) {
|
||||
len = l;
|
||||
}
|
||||
|
||||
kfifo_copy_out(fifo, buf, len, fifo->out);
|
||||
return len;
|
||||
}
|
||||
|
||||
uint32_t fifo_out_peek(struct k_fifo *fifo,
|
||||
void *buf, uint32_t len)
|
||||
{
|
||||
|
||||
uint32_t ret_len;
|
||||
|
||||
CPSR_ALLOC();
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
|
||||
ret_len = internal_fifo_out_peek(fifo, buf, len);
|
||||
|
||||
RHINO_CRITICAL_EXIT();
|
||||
|
||||
return ret_len;
|
||||
|
||||
}
|
||||
|
||||
uint32_t fifo_out(struct k_fifo *fifo, void *buf, uint32_t len)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
|
||||
len = internal_fifo_out_peek(fifo, buf, len);
|
||||
fifo->out += len;
|
||||
|
||||
fifo->free_bytes += len;
|
||||
|
||||
RHINO_CRITICAL_EXIT();
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
uint32_t fifo_out_all(struct k_fifo *fifo, void *buf)
|
||||
{
|
||||
uint32_t len;
|
||||
|
||||
CPSR_ALLOC();
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
|
||||
len = fifo->size - fifo->free_bytes;
|
||||
|
||||
if (len == 0) {
|
||||
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return 0;
|
||||
}
|
||||
|
||||
len = internal_fifo_out_peek(fifo, buf, len);
|
||||
fifo->out += len;
|
||||
|
||||
fifo->free_bytes += len;
|
||||
|
||||
RHINO_CRITICAL_EXIT();
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
76
Living_SDK/kernel/rhino/common/k_fifo.h
Normal file
76
Living_SDK/kernel/rhino/common/k_fifo.h
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef FIFO_H
|
||||
#define FIFO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct k_fifo {
|
||||
|
||||
uint32_t in;
|
||||
uint32_t out;
|
||||
uint32_t mask;
|
||||
void *data;
|
||||
uint32_t free_bytes;
|
||||
uint32_t size;
|
||||
|
||||
};
|
||||
|
||||
#define fifo_min(x, y) ((x) > (y)?(y):(x))
|
||||
#define fifo_max(x, y) ((x) > (y)?(x):(y))
|
||||
|
||||
/**
|
||||
* This function will init the fifo.
|
||||
* @param[in] fifo pointer to fifo
|
||||
* @param[in] buffer pointer to fifo buffer
|
||||
* @param[in] size size of fifo buffer
|
||||
* @return the operation status, 0 is OK, others is error
|
||||
*/
|
||||
int8_t fifo_init(struct k_fifo *fifo, void *buffer, uint32_t size);
|
||||
|
||||
/**
|
||||
* This function will write buf to fifo.
|
||||
* @param[in] fifo pointer to fifo
|
||||
* @param[in] buf pointer to buffer write
|
||||
* @param[in] size size of buffer
|
||||
* @return the size has been written to the fifo
|
||||
*/
|
||||
uint32_t fifo_in(struct k_fifo *fifo, const void *buf, uint32_t len);
|
||||
|
||||
/**
|
||||
* This function will read fifo data to buf
|
||||
* @param[in] fifo pointer to fifo
|
||||
* @param[in] buf pointer to buffer read
|
||||
* @param[in] len len of buffer
|
||||
* @return the size has read
|
||||
*/
|
||||
uint32_t fifo_out(struct k_fifo *fifo, void *buf, uint32_t len);
|
||||
|
||||
/**
|
||||
* This function will read fifo data to buf,but data remain in fifo
|
||||
* @param[in] fifo pointer to fifo
|
||||
* @param[in] buf pointer to buffer read
|
||||
* @param[in] len len of buffer
|
||||
* @return the size has read
|
||||
*/
|
||||
uint32_t fifo_out_peek(struct k_fifo *fifo,
|
||||
void *buf, uint32_t len);
|
||||
|
||||
/**
|
||||
* This function will read fifo all data
|
||||
* @param[in] fifo pointer to fifo
|
||||
* @param[in] buf pointer to buffer read
|
||||
* @return the size has read
|
||||
*/
|
||||
uint32_t fifo_out_all(struct k_fifo *fifo, void *buf);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
1541
Living_SDK/kernel/rhino/common/k_trace.c
Executable file
1541
Living_SDK/kernel/rhino/common/k_trace.c
Executable file
File diff suppressed because it is too large
Load diff
54
Living_SDK/kernel/rhino/core/include/k_api.h
Normal file
54
Living_SDK/kernel/rhino/core/include/k_api.h
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef K_API_H
|
||||
#define K_API_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <k_config.h>
|
||||
#include <k_default_config.h>
|
||||
#include <k_types.h>
|
||||
#include <k_err.h>
|
||||
#include <k_critical.h>
|
||||
#include <k_spin_lock.h>
|
||||
#include <k_sys.h>
|
||||
#include <k_bitmap.h>
|
||||
#include <k_list.h>
|
||||
#include <k_obj.h>
|
||||
#include <k_sched.h>
|
||||
#include <k_task.h>
|
||||
#include <k_ringbuf.h>
|
||||
#include <k_queue.h>
|
||||
#include <k_buf_queue.h>
|
||||
#include <k_sem.h>
|
||||
#include <k_task_sem.h>
|
||||
#include <k_mutex.h>
|
||||
#include <k_timer.h>
|
||||
#include <k_time.h>
|
||||
#include <k_event.h>
|
||||
#include <k_stats.h>
|
||||
#include <k_mm_debug.h>
|
||||
#include <k_mm_blk.h>
|
||||
#include <k_mm_region.h>
|
||||
#include <k_mm.h>
|
||||
#include <k_workqueue.h>
|
||||
#include <k_internal.h>
|
||||
#include <k_trace.h>
|
||||
#include <k_soc.h>
|
||||
#include <k_hook.h>
|
||||
#include <port.h>
|
||||
#include <k_endian.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* K_API_H */
|
||||
|
||||
165
Living_SDK/kernel/rhino/core/include/k_bitmap.h
Executable file
165
Living_SDK/kernel/rhino/core/include/k_bitmap.h
Executable file
|
|
@ -0,0 +1,165 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef K_BITMAP_H
|
||||
#define K_BITMAP_H
|
||||
|
||||
#define BITMAP_UNIT_SIZE 32U
|
||||
#define BITMAP_UNIT_MASK 0X0000001F
|
||||
#define BITMAP_UNIT_BITS 5U
|
||||
|
||||
#define BITMAP_MASK(nr) (1UL << (BITMAP_UNIT_SIZE - 1U - ((nr) & BITMAP_UNIT_MASK)))
|
||||
#define BITMAP_WORD(nr) ((nr) >> BITMAP_UNIT_BITS)
|
||||
|
||||
/**
|
||||
** This MACRO will declare a bitmap
|
||||
** @param[in] name the name of the bitmap to declare
|
||||
** @param[in] bits the bits of the bitmap
|
||||
** @return no return
|
||||
**/
|
||||
#define BITMAP_DECLARE(name, bits) uint32_t name[((bits) + (BITMAP_UNIT_SIZE - 1U)) >> BITMAP_UNIT_BITS]
|
||||
|
||||
#if (RHINO_CONFIG_BITMAP_HW != 0)
|
||||
extern int32_t cpu_bitmap_clz(uint32_t val);
|
||||
#endif
|
||||
|
||||
/**
|
||||
** This function will set a bit of the bitmap
|
||||
** @param[in] bitmap pointer to the bitmap
|
||||
** @param[in] nr position of the bitmap to set
|
||||
** @return no return
|
||||
**/
|
||||
RHINO_INLINE void krhino_bitmap_set(uint32_t *bitmap, int32_t nr)
|
||||
{
|
||||
bitmap[BITMAP_WORD(nr)] |= BITMAP_MASK(nr);
|
||||
}
|
||||
|
||||
/**
|
||||
** This function will clear a bit of the bitmap
|
||||
** @param[in] bitmap pointer to the bitmap
|
||||
** @param[in] nr position of the bitmap to clear
|
||||
** @return no return
|
||||
**/
|
||||
RHINO_INLINE void krhino_bitmap_clear(uint32_t *bitmap, int32_t nr)
|
||||
{
|
||||
bitmap[BITMAP_WORD(nr)] &= ~BITMAP_MASK(nr);
|
||||
}
|
||||
|
||||
/* Count Leading Zeros (clz)
|
||||
counts the number of zero bits preceding the most significant one bit. */
|
||||
RHINO_INLINE uint8_t krhino_clz32(uint32_t x)
|
||||
{
|
||||
uint8_t n = 0;
|
||||
|
||||
if (x == 0) {
|
||||
return 32;
|
||||
}
|
||||
|
||||
if ((x & 0XFFFF0000) == 0) {
|
||||
x <<= 16;
|
||||
n += 16;
|
||||
}
|
||||
if ((x & 0XFF000000) == 0) {
|
||||
x <<= 8;
|
||||
n += 8;
|
||||
}
|
||||
if ((x & 0XF0000000) == 0) {
|
||||
x <<= 4;
|
||||
n += 4;
|
||||
}
|
||||
if ((x & 0XC0000000) == 0) {
|
||||
x <<= 2;
|
||||
n += 2;
|
||||
}
|
||||
if ((x & 0X80000000) == 0) {
|
||||
n += 1;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
/* Count Trailing Zeros (ctz)
|
||||
counts the number of zero bits succeeding the least significant one bit. */
|
||||
RHINO_INLINE uint8_t krhino_ctz32(uint32_t x)
|
||||
{
|
||||
uint8_t n = 0;
|
||||
|
||||
if (x == 0) {
|
||||
return 32;
|
||||
}
|
||||
|
||||
if ((x & 0X0000FFFF) == 0) {
|
||||
x >>= 16;
|
||||
n += 16;
|
||||
}
|
||||
if ((x & 0X000000FF) == 0) {
|
||||
x >>= 8;
|
||||
n += 8;
|
||||
}
|
||||
if ((x & 0X0000000F) == 0) {
|
||||
x >>= 4;
|
||||
n += 4;
|
||||
}
|
||||
if ((x & 0X00000003) == 0) {
|
||||
x >>= 2;
|
||||
n += 2;
|
||||
}
|
||||
if ((x & 0X00000001) == 0) {
|
||||
n += 1;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
** This function will find the first bit(1) of the bitmap
|
||||
** @param[in] bitmap pointer to the bitmap
|
||||
** @return the first bit position
|
||||
**/
|
||||
RHINO_INLINE int32_t krhino_find_first_bit(uint32_t *bitmap)
|
||||
{
|
||||
int32_t nr = 0;
|
||||
uint32_t tmp = 0;
|
||||
|
||||
while (*bitmap == 0UL) {
|
||||
nr += BITMAP_UNIT_SIZE;
|
||||
bitmap++;
|
||||
}
|
||||
|
||||
tmp = *bitmap;
|
||||
|
||||
#if (RHINO_CONFIG_BITMAP_HW == 0)
|
||||
if (!(tmp & 0XFFFF0000)) {
|
||||
tmp <<= 16;
|
||||
nr += 16;
|
||||
}
|
||||
|
||||
if (!(tmp & 0XFF000000)) {
|
||||
tmp <<= 8;
|
||||
nr += 8;
|
||||
}
|
||||
|
||||
if (!(tmp & 0XF0000000)) {
|
||||
tmp <<= 4;
|
||||
nr += 4;
|
||||
}
|
||||
|
||||
if (!(tmp & 0XC0000000)) {
|
||||
tmp <<= 2;
|
||||
nr += 2;
|
||||
}
|
||||
|
||||
if (!(tmp & 0X80000000)) {
|
||||
nr += 1;
|
||||
}
|
||||
#else
|
||||
nr += cpu_bitmap_clz(tmp);
|
||||
#endif
|
||||
|
||||
return nr;
|
||||
}
|
||||
|
||||
#endif /* K_BITMAP_H */
|
||||
|
||||
121
Living_SDK/kernel/rhino/core/include/k_buf_queue.h
Normal file
121
Living_SDK/kernel/rhino/core/include/k_buf_queue.h
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef K_BUF_QUEUE_H
|
||||
#define K_BUF_QUEUE_H
|
||||
|
||||
typedef struct {
|
||||
blk_obj_t blk_obj;
|
||||
void *buf;
|
||||
k_ringbuf_t ringbuf;
|
||||
size_t max_msg_size;
|
||||
size_t cur_num;
|
||||
size_t peak_num;
|
||||
size_t min_free_buf_size;
|
||||
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
|
||||
klist_t buf_queue_item;
|
||||
#endif
|
||||
uint8_t mm_alloc_flag;
|
||||
} kbuf_queue_t;
|
||||
|
||||
typedef struct {
|
||||
size_t buf_size;
|
||||
size_t max_msg_size;
|
||||
size_t cur_num;
|
||||
size_t peak_num;
|
||||
size_t free_buf_size;
|
||||
size_t min_free_buf_size;
|
||||
} kbuf_queue_info_t;
|
||||
|
||||
/**
|
||||
* This function will create a buf-queue
|
||||
* @param[in] queue pointer to the queue(the space is provided by user)
|
||||
* @param[in] name name of the queue
|
||||
* @param[in] buf pointer to the buf
|
||||
* @param[in] size size of the buf
|
||||
* @param[in] max_msg max size of one msg
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_buf_queue_create(kbuf_queue_t *queue, const name_t *name,
|
||||
void *buf,
|
||||
size_t size, size_t max_msg);
|
||||
|
||||
/**
|
||||
* This function will create a fix buf-queue
|
||||
* @param[in] queue pointer to the queue(the space is provided by user)
|
||||
* @param[in] name name of the queue
|
||||
* @param[in] buf pointer to the buf
|
||||
* @param[in] msg_size size of the msg
|
||||
* @param[in] msg_num number of msg
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_fix_buf_queue_create(kbuf_queue_t *queue, const name_t *name,
|
||||
void *buf, size_t msg_size, size_t msg_num);
|
||||
|
||||
/**
|
||||
* This function will delete a queue
|
||||
* @param[in] queue pointer to the queue
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_buf_queue_del(kbuf_queue_t *queue);
|
||||
|
||||
#if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0)
|
||||
/**
|
||||
* This function will create a dyn-queue
|
||||
* @param[out] queue pointer to the queue(The space is provided by kernel)
|
||||
* @param[in] name pointer to the nam
|
||||
* @param[in] size size of the buf
|
||||
* @param[in] max_msg max size of one msg
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_buf_queue_dyn_create(kbuf_queue_t **queue, const name_t *name,
|
||||
size_t size, size_t max_msg);
|
||||
|
||||
/**
|
||||
* This function will delete a dyn-queue
|
||||
* @param[in] queue pointer to the queue
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_buf_queue_dyn_del(kbuf_queue_t *queue);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This function will send a msg at the end of queue
|
||||
* @param[in] queue pointer to the queue
|
||||
* @param[in] msg pointer to msg to be send
|
||||
* @param[in] size size of the msg
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_buf_queue_send(kbuf_queue_t *queue, void *msg, size_t size);
|
||||
|
||||
|
||||
/**
|
||||
* This function will receive msg form aqueue
|
||||
* @param[in] queue pointer to the queue
|
||||
* @param[in] ticks ticks to wait before receiving msg
|
||||
* @param[out] msg pointer to the buf to save msg
|
||||
* @param[out] size size of received msg
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_buf_queue_recv(kbuf_queue_t *queue, tick_t ticks, void *msg,
|
||||
size_t *size);
|
||||
|
||||
/**
|
||||
* This function will reset queue
|
||||
* @param[in] queue pointer to the queue
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_buf_queue_flush(kbuf_queue_t *queue);
|
||||
|
||||
/**
|
||||
* This function will get information of a queue
|
||||
* @param[in] queue pointer to the queue
|
||||
* @param[out] free free size of the queue buf
|
||||
* @param[out] total total size of the queue buf
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_buf_queue_info_get(kbuf_queue_t *queue, kbuf_queue_info_t *info);
|
||||
|
||||
#endif /* K_BUF_QUEUE_H */
|
||||
|
||||
65
Living_SDK/kernel/rhino/core/include/k_critical.h
Executable file
65
Living_SDK/kernel/rhino/core/include/k_critical.h
Executable file
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef K_CRITICAL_H
|
||||
#define K_CRITICAL_H
|
||||
|
||||
#if (RHINO_CONFIG_DISABLE_INTRPT_STATS > 0)
|
||||
#define RHINO_CRITICAL_ENTER() \
|
||||
do { \
|
||||
RHINO_CPU_INTRPT_DISABLE(); \
|
||||
intrpt_disable_measure_start(); \
|
||||
} while (0)
|
||||
|
||||
#define RHINO_CRITICAL_EXIT() \
|
||||
do { \
|
||||
intrpt_disable_measure_stop(); \
|
||||
RHINO_CPU_INTRPT_ENABLE(); \
|
||||
} while (0)
|
||||
|
||||
#if (RHINO_CONFIG_CPU_NUM > 1)
|
||||
#define RHINO_CRITICAL_EXIT_SCHED() \
|
||||
do { \
|
||||
intrpt_disable_measure_stop(); \
|
||||
core_sched(); \
|
||||
RHINO_CPU_INTRPT_ENABLE(); \
|
||||
} while (0)
|
||||
#else
|
||||
#define RHINO_CRITICAL_EXIT_SCHED() \
|
||||
do { \
|
||||
intrpt_disable_measure_stop(); \
|
||||
RHINO_CPU_INTRPT_ENABLE(); \
|
||||
core_sched(); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#else /* RHINO_CONFIG_DISABLE_INTRPT_STATS */
|
||||
#define RHINO_CRITICAL_ENTER() \
|
||||
do { \
|
||||
RHINO_CPU_INTRPT_DISABLE(); \
|
||||
} while (0)
|
||||
|
||||
#define RHINO_CRITICAL_EXIT() \
|
||||
do { \
|
||||
RHINO_CPU_INTRPT_ENABLE(); \
|
||||
} while (0)
|
||||
|
||||
#if (RHINO_CONFIG_CPU_NUM > 1)
|
||||
#define RHINO_CRITICAL_EXIT_SCHED() \
|
||||
do { \
|
||||
core_sched(); \
|
||||
RHINO_CPU_INTRPT_ENABLE(); \
|
||||
} while (0)
|
||||
#else
|
||||
#define RHINO_CRITICAL_EXIT_SCHED() \
|
||||
do { \
|
||||
RHINO_CPU_INTRPT_ENABLE(); \
|
||||
core_sched(); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#endif /* RHINO_CONFIG_DISABLE_INTRPT_STATS */
|
||||
|
||||
#endif /* K_CRITICAL_H */
|
||||
|
||||
309
Living_SDK/kernel/rhino/core/include/k_default_config.h
Normal file
309
Living_SDK/kernel/rhino/core/include/k_default_config.h
Normal file
|
|
@ -0,0 +1,309 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef K_DEFAULT_CONFIG_H
|
||||
#define K_DEFAULT_CONFIG_H
|
||||
|
||||
#ifndef RHINO_CONFIG_CPU_PWR_MGMT
|
||||
#define RHINO_CONFIG_CPU_PWR_MGMT 0
|
||||
#endif
|
||||
|
||||
/* chip level conf */
|
||||
#ifndef RHINO_CONFIG_LITTLE_ENDIAN
|
||||
#define RHINO_CONFIG_LITTLE_ENDIAN 1
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_CPU_STACK_DOWN
|
||||
#define RHINO_CONFIG_CPU_STACK_DOWN 1
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_BITMAP_HW
|
||||
#define RHINO_CONFIG_BITMAP_HW 0
|
||||
#endif
|
||||
|
||||
/* kernel feature conf */
|
||||
#ifndef RHINO_CONFIG_SEM
|
||||
#define RHINO_CONFIG_SEM 0
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_QUEUE
|
||||
#define RHINO_CONFIG_QUEUE 0
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_TASK_SEM
|
||||
#define RHINO_CONFIG_TASK_SEM 0
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_WORKQUEUE
|
||||
#define RHINO_CONFIG_WORKQUEUE 0
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_WORKQUEUE_STACK_SIZE
|
||||
#define RHINO_CONFIG_WORKQUEUE_STACK_SIZE 512
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_WORKQUEUE_TASK_PRIO
|
||||
#define RHINO_CONFIG_WORKQUEUE_TASK_PRIO 20
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_EVENT_FLAG
|
||||
#define RHINO_CONFIG_EVENT_FLAG 0
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_TIMER
|
||||
#define RHINO_CONFIG_TIMER 0
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_BUF_QUEUE
|
||||
#define RHINO_CONFIG_BUF_QUEUE 0
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_MM_BLK
|
||||
#define RHINO_CONFIG_MM_BLK 1
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_MM_BLK_SIZE
|
||||
#define RHINO_CONFIG_MM_BLK_SIZE 32
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_MM_TLF
|
||||
#define RHINO_CONFIG_MM_TLF 1
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_MM_MINISIZEBIT
|
||||
#define RHINO_CONFIG_MM_MINISIZEBIT 6
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_MM_MAXMSIZEBIT
|
||||
#define RHINO_CONFIG_MM_MAXMSIZEBIT 20
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_MM_QUICK
|
||||
#define RHINO_CONFIG_MM_QUICK 0
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_MM_TLF_BLK_SIZE
|
||||
#define RHINO_CONFIG_MM_TLF_BLK_SIZE 8192
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_MM_DEBUG
|
||||
#define RHINO_CONFIG_MM_DEBUG 0
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_GCC_RETADDR
|
||||
#define RHINO_CONFIG_GCC_RETADDR 0
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_MM_LEAKCHECK
|
||||
#define RHINO_CONFIG_MM_LEAKCHECK 0
|
||||
#endif
|
||||
|
||||
#ifndef K_MM_STATISTIC
|
||||
#define K_MM_STATISTIC 1
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_TASK_SEM
|
||||
#define RHINO_CONFIG_TASK_SEM 0
|
||||
#endif
|
||||
|
||||
/* kernel task conf */
|
||||
#ifndef RHINO_CONFIG_TASK_PRI_CHG
|
||||
#define RHINO_CONFIG_TASK_PRI_CHG 1
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_TASK_INFO
|
||||
#define RHINO_CONFIG_TASK_INFO 0
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_TASK_INFO_NUM
|
||||
#define RHINO_CONFIG_TASK_INFO_NUM 2
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_TASK_DEL
|
||||
#define RHINO_CONFIG_TASK_DEL 0
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_TASK_STACK_CUR_CHECK
|
||||
#define RHINO_CONFIG_TASK_STACK_CUR_CHECK 0
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_TASK_WAIT_ABORT
|
||||
#define RHINO_CONFIG_TASK_WAIT_ABORT 0
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_SCHED_RR
|
||||
#define RHINO_CONFIG_SCHED_RR 0
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_TIME_SLICE_DEFAULT
|
||||
#define RHINO_CONFIG_TIME_SLICE_DEFAULT 50
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_PRI_MAX
|
||||
#define RHINO_CONFIG_PRI_MAX 62
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_USER_PRI_MAX
|
||||
#define RHINO_CONFIG_USER_PRI_MAX (RHINO_CONFIG_PRI_MAX - 2)
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_RINGBUF_VENDOR
|
||||
#define RHINO_CONFIG_RINGBUF_VENDOR 0
|
||||
#endif
|
||||
|
||||
/* kernel mm_region conf */
|
||||
#ifndef RHINO_CONFIG_MM_REGION_MUTEX
|
||||
#define RHINO_CONFIG_MM_REGION_MUTEX 1
|
||||
#endif
|
||||
|
||||
/* kernel timer&tick conf */
|
||||
#ifndef RHINO_CONFIG_HW_COUNT
|
||||
#define RHINO_CONFIG_HW_COUNT 0
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_TICKS_PER_SECOND
|
||||
#define RHINO_CONFIG_TICKS_PER_SECOND 100
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_TIMER_TASK_STACK_SIZE
|
||||
#define RHINO_CONFIG_TIMER_TASK_STACK_SIZE 200
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_TIMER_RATE
|
||||
#define RHINO_CONFIG_TIMER_RATE 1
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_TIMER_TASK_PRI
|
||||
#define RHINO_CONFIG_TIMER_TASK_PRI 5
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_TIMER_MSG_NUM
|
||||
#define RHINO_CONFIG_TIMER_MSG_NUM 20
|
||||
#endif
|
||||
|
||||
/* kernel intrpt conf */
|
||||
#ifndef RHINO_CONFIG_INTRPT_STACK_REMAIN_GET
|
||||
#define RHINO_CONFIG_INTRPT_STACK_REMAIN_GET 0
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_INTRPT_MAX_NESTED_LEVEL
|
||||
#define RHINO_CONFIG_INTRPT_MAX_NESTED_LEVEL 188u
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_INTRPT_GUARD
|
||||
#define RHINO_CONFIG_INTRPT_GUARD 0
|
||||
#endif
|
||||
|
||||
/* kernel stack ovf check */
|
||||
#ifndef RHINO_CONFIG_INTRPT_STACK_OVF_CHECK
|
||||
#define RHINO_CONFIG_INTRPT_STACK_OVF_CHECK 0
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_TASK_STACK_OVF_CHECK
|
||||
#define RHINO_CONFIG_TASK_STACK_OVF_CHECK 0
|
||||
#endif
|
||||
|
||||
/* kernel dyn alloc conf */
|
||||
#ifndef RHINO_CONFIG_KOBJ_DYN_ALLOC
|
||||
#define RHINO_CONFIG_KOBJ_DYN_ALLOC 0
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0)
|
||||
|
||||
#ifndef RHINO_CONFIG_K_DYN_QUEUE_MSG
|
||||
#define RHINO_CONFIG_K_DYN_QUEUE_MSG 30
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_K_DYN_TASK_STACK
|
||||
#define RHINO_CONFIG_K_DYN_TASK_STACK 256
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_K_DYN_MEM_TASK_PRI
|
||||
#define RHINO_CONFIG_K_DYN_MEM_TASK_PRI RHINO_CONFIG_USER_PRI_MAX
|
||||
#endif
|
||||
|
||||
#endif /* RHINO_CONFIG_KOBJ_DYN_ALLOC */
|
||||
|
||||
/* kernel idle conf */
|
||||
#ifndef RHINO_CONFIG_IDLE_TASK_STACK_SIZE
|
||||
#define RHINO_CONFIG_IDLE_TASK_STACK_SIZE 100
|
||||
#endif
|
||||
|
||||
/* kernel hook conf */
|
||||
#ifndef RHINO_CONFIG_USER_HOOK
|
||||
#define RHINO_CONFIG_USER_HOOK 1
|
||||
#endif
|
||||
|
||||
/* kernel stats conf */
|
||||
#ifndef RHINO_CONFIG_SYSTEM_STATS
|
||||
#define RHINO_CONFIG_SYSTEM_STATS 0
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_DISABLE_SCHED_STATS
|
||||
#define RHINO_CONFIG_DISABLE_SCHED_STATS 0
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_DISABLE_INTRPT_STATS
|
||||
#define RHINO_CONFIG_DISABLE_INTRPT_STATS 0
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_CPU_USAGE_STATS
|
||||
#define RHINO_CONFIG_CPU_USAGE_STATS 0
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_CPU_USAGE_TASK_PRI
|
||||
#define RHINO_CONFIG_CPU_USAGE_TASK_PRI (RHINO_CONFIG_PRI_MAX - 2)
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_TASK_SCHED_STATS
|
||||
#define RHINO_CONFIG_TASK_SCHED_STATS 0
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_CPU_USAGE_TASK_STACK
|
||||
#define RHINO_CONFIG_CPU_USAGE_TASK_STACK 256
|
||||
#endif
|
||||
|
||||
/* kernel trace conf */
|
||||
#ifndef RHINO_CONFIG_TRACE
|
||||
#define RHINO_CONFIG_TRACE 0
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_CPU_NUM
|
||||
#define RHINO_CONFIG_CPU_NUM 1
|
||||
#endif
|
||||
|
||||
#if ((RHINO_CONFIG_TIMER >= 1) && (RHINO_CONFIG_BUF_QUEUE == 0))
|
||||
#error "RHINO_CONFIG_BUF_QUEUE should be 1 when RHINO_CONFIG_TIMER is enabled."
|
||||
#endif
|
||||
|
||||
#if ((RHINO_CONFIG_MM_TLF >= 1) && (RHINO_CONFIG_MM_BLK == 0))
|
||||
#error "RHINO_CONFIG_MM_BLK should be 1 when RHINO_CONFIG_MM_TLF is enabled."
|
||||
#endif
|
||||
|
||||
#if ((RHINO_CONFIG_KOBJ_DYN_ALLOC >= 1) && (RHINO_CONFIG_MM_TLF == 0))
|
||||
#error \
|
||||
"RHINO_CONFIG_MM_TLF should be 1 when RHINO_CONFIG_KOBJ_DYN_ALLOC is enabled."
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_PRI_MAX >= 256)
|
||||
#error "RHINO_CONFIG_PRI_MAX must be <= 255."
|
||||
#endif
|
||||
|
||||
#if ((RHINO_CONFIG_SEM == 0) && (RHINO_CONFIG_TASK_SEM >= 1))
|
||||
#error "you need enable RHINO_CONFIG_SEM as well."
|
||||
#endif
|
||||
|
||||
#if ((RHINO_CONFIG_HW_COUNT == 0) && (RHINO_CONFIG_TASK_SCHED_STATS >= 1))
|
||||
#error "you need enable RHINO_CONFIG_HW_COUNT as well."
|
||||
#endif
|
||||
|
||||
#if ((RHINO_CONFIG_HW_COUNT == 0) && (RHINO_CONFIG_DISABLE_SCHED_STATS >= 1))
|
||||
#error "you need enable RHINO_CONFIG_HW_COUNT as well."
|
||||
#endif
|
||||
|
||||
#if ((RHINO_CONFIG_HW_COUNT == 0) && (RHINO_CONFIG_DISABLE_INTRPT_STATS >= 1))
|
||||
#error "you need enable RHINO_CONFIG_HW_COUNT as well."
|
||||
#endif
|
||||
|
||||
#endif /* K_DEFAULT_CONFIG_H */
|
||||
46
Living_SDK/kernel/rhino/core/include/k_endian.h
Normal file
46
Living_SDK/kernel/rhino/core/include/k_endian.h
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef K_ENDIAN_H
|
||||
#define K_ENDIAN_H
|
||||
|
||||
#if (RHINO_CONFIG_LITTLE_ENDIAN != 1)
|
||||
|
||||
#define krhino_htons(x) x
|
||||
#define krhino_htonl(x) x
|
||||
#define krhino_ntohl(x) x
|
||||
#define krhino_ntohs(x) x
|
||||
|
||||
#else
|
||||
|
||||
#ifndef krhino_htons
|
||||
#define krhino_htons(x) ((uint16_t)(((x) & 0x00ffU) << 8)| \
|
||||
(((x) & 0xff00U) >> 8))
|
||||
#endif
|
||||
|
||||
#ifndef krhino_htonl
|
||||
#define krhino_htonl(x) ((uint32_t)(((x) & 0x000000ffUL) << 24) | \
|
||||
(((x) & 0x0000ff00UL) << 8) | \
|
||||
(((x) & 0x00ff0000UL) >> 8) | \
|
||||
(((x) & 0xff000000UL) >> 24))
|
||||
#endif
|
||||
|
||||
#ifndef krhino_ntohs
|
||||
#define krhino_ntohs(x) ((uint16_t)((x & 0x00ffU) << 8) | \
|
||||
((x & 0xff00U) >> 8))
|
||||
#endif
|
||||
|
||||
#ifndef krhino_ntohl
|
||||
#define krhino_ntohl(x) ((uint32_t)(((x) & 0x000000ffUL) << 24) | \
|
||||
(((x) & 0x0000ff00UL) << 8) | \
|
||||
(((x) & 0x00ff0000UL) >> 8) | \
|
||||
(((x) & 0xff000000UL) >> 24))
|
||||
#endif
|
||||
|
||||
|
||||
#endif /*RHINO_CONFIG_LITTLE_ENDIAN*/
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
108
Living_SDK/kernel/rhino/core/include/k_err.h
Normal file
108
Living_SDK/kernel/rhino/core/include/k_err.h
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef K_ERR_H
|
||||
#define K_ERR_H
|
||||
|
||||
typedef enum {
|
||||
RHINO_SUCCESS = 0u,
|
||||
RHINO_SYS_FATAL_ERR,
|
||||
RHINO_SYS_SP_ERR,
|
||||
RHINO_RUNNING,
|
||||
RHINO_STOPPED,
|
||||
RHINO_INV_PARAM,
|
||||
RHINO_NULL_PTR,
|
||||
RHINO_INV_ALIGN,
|
||||
RHINO_KOBJ_TYPE_ERR,
|
||||
RHINO_KOBJ_DEL_ERR,
|
||||
RHINO_KOBJ_DOCKER_EXIST,
|
||||
RHINO_KOBJ_BLK,
|
||||
RHINO_KOBJ_SET_FULL,
|
||||
RHINO_NOTIFY_FUNC_EXIST,
|
||||
|
||||
RHINO_MM_POOL_SIZE_ERR = 100u,
|
||||
RHINO_MM_ALLOC_SIZE_ERR,
|
||||
RHINO_MM_FREE_ADDR_ERR,
|
||||
RHINO_MM_CORRUPT_ERR,
|
||||
RHINO_DYN_MEM_PROC_ERR,
|
||||
RHINO_NO_MEM,
|
||||
RHINO_RINGBUF_FULL,
|
||||
RHINO_RINGBUF_EMPTY,
|
||||
|
||||
RHINO_SCHED_DISABLE = 200u,
|
||||
RHINO_SCHED_ALREADY_ENABLED,
|
||||
RHINO_SCHED_LOCK_COUNT_OVF,
|
||||
RHINO_INV_SCHED_WAY,
|
||||
|
||||
RHINO_TASK_INV_STACK_SIZE = 300u,
|
||||
RHINO_TASK_NOT_SUSPENDED,
|
||||
RHINO_TASK_DEL_NOT_ALLOWED,
|
||||
RHINO_TASK_SUSPEND_NOT_ALLOWED,
|
||||
RHINO_SUSPENDED_COUNT_OVF,
|
||||
RHINO_BEYOND_MAX_PRI,
|
||||
RHINO_PRI_CHG_NOT_ALLOWED,
|
||||
RHINO_INV_TASK_STATE,
|
||||
RHINO_IDLE_TASK_EXIST,
|
||||
|
||||
RHINO_NO_PEND_WAIT = 400u,
|
||||
RHINO_BLK_ABORT,
|
||||
RHINO_BLK_TIMEOUT,
|
||||
RHINO_BLK_DEL,
|
||||
RHINO_BLK_INV_STATE,
|
||||
RHINO_BLK_POOL_SIZE_ERR,
|
||||
|
||||
RHINO_TIMER_STATE_INV = 500u,
|
||||
|
||||
RHINO_NO_THIS_EVENT_OPT = 600u,
|
||||
|
||||
RHINO_BUF_QUEUE_INV_SIZE = 700u,
|
||||
RHINO_BUF_QUEUE_SIZE_ZERO,
|
||||
RHINO_BUF_QUEUE_FULL,
|
||||
RHINO_BUF_QUEUE_MSG_SIZE_OVERFLOW,
|
||||
RHINO_QUEUE_FULL,
|
||||
RHINO_QUEUE_NOT_FULL,
|
||||
|
||||
RHINO_SEM_OVF = 800u,
|
||||
RHINO_SEM_TASK_WAITING,
|
||||
|
||||
RHINO_MUTEX_NOT_RELEASED_BY_OWNER = 900u,
|
||||
RHINO_MUTEX_OWNER_NESTED,
|
||||
RHINO_MUTEX_NESTED_OVF,
|
||||
|
||||
RHINO_NOT_CALLED_BY_INTRPT = 1000u,
|
||||
RHINO_TRY_AGAIN,
|
||||
|
||||
RHINO_WORKQUEUE_EXIST = 1100u,
|
||||
RHINO_WORKQUEUE_NOT_EXIST,
|
||||
RHINO_WORKQUEUE_WORK_EXIST,
|
||||
RHINO_WORKQUEUE_BUSY,
|
||||
RHINO_WORKQUEUE_WORK_RUNNING,
|
||||
|
||||
RHINO_TASK_STACK_OVF = 1200u,
|
||||
RHINO_INTRPT_STACK_OVF
|
||||
} kstat_t;
|
||||
|
||||
typedef void (*krhino_err_proc_t)(kstat_t err);
|
||||
extern krhino_err_proc_t g_err_proc;
|
||||
|
||||
/**
|
||||
* convert int to ascii(HEX)
|
||||
* while using format % in libc, malloc/free is involved.
|
||||
* this function avoid using malloc/free. so it works when heap corrupt.
|
||||
* @param[in] num number
|
||||
* @param[in] str fix 8 character str
|
||||
* @return str
|
||||
*/
|
||||
char *k_int2str(int num, char *str);
|
||||
|
||||
/**
|
||||
* call g_err_proc
|
||||
* @param[in] err error_id
|
||||
* @return void
|
||||
*/
|
||||
void k_err_proc(kstat_t err);
|
||||
|
||||
|
||||
#endif /* K_ERR_H */
|
||||
|
||||
84
Living_SDK/kernel/rhino/core/include/k_event.h
Normal file
84
Living_SDK/kernel/rhino/core/include/k_event.h
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef K_EVENT_H
|
||||
#define K_EVENT_H
|
||||
|
||||
typedef struct {
|
||||
blk_obj_t blk_obj;
|
||||
uint32_t flags;
|
||||
|
||||
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
|
||||
klist_t event_item;
|
||||
#endif
|
||||
|
||||
uint8_t mm_alloc_flag;
|
||||
} kevent_t;
|
||||
|
||||
#define RHINO_FLAGS_AND_MASK 0x2u
|
||||
#define RHINO_FLAGS_CLEAR_MASK 0x1u
|
||||
|
||||
#define RHINO_AND 0x02u
|
||||
#define RHINO_AND_CLEAR 0x03u
|
||||
#define RHINO_OR 0x00u
|
||||
#define RHINO_OR_CLEAR 0x01u
|
||||
|
||||
/**
|
||||
* This function will create a event
|
||||
* @param[in] event pointer to the event
|
||||
* @param[in] name name of the event
|
||||
* @param[in] flags flags to be init
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_event_create(kevent_t *event, const name_t *name, uint32_t flags);
|
||||
|
||||
/**
|
||||
* This function will delete a event
|
||||
* @param[in] event pointer to a event
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_event_del(kevent_t *event);
|
||||
|
||||
#if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0)
|
||||
/**
|
||||
* This function will create a dyn-event
|
||||
* @param[out] event pointer to the event
|
||||
* @param[in] name name of the semaphore
|
||||
* @param[in] flags flags to be init
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_event_dyn_create(kevent_t **event, const name_t *name,
|
||||
uint32_t flags);
|
||||
|
||||
/**
|
||||
* This function will delete a dyn created event
|
||||
* @param[in] event pointer to a event
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_event_dyn_del(kevent_t *event);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This function will get event
|
||||
* @param[in] event pointer to the event
|
||||
* @param[in] flags which is provided by users
|
||||
* @param[in] opt could be RHINO_AND, RHINO_AND_CLEAR, RHINO_OR, RHINO_OR_CLEAR
|
||||
* @param[out] actl_flags the actually flag where flags is satisfied
|
||||
* @param[in] ticks ticks to wait
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_event_get(kevent_t *event, uint32_t flags, uint8_t opt,
|
||||
uint32_t *actl_flags, tick_t ticks);
|
||||
|
||||
/**
|
||||
* This function will set a event
|
||||
* @param[in] event pointer to a event
|
||||
* @param[in] flags which users want to be set
|
||||
* @param[in] opt could be RHINO_AND, RHINO_OR
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_event_set(kevent_t *event, uint32_t flags, uint8_t opt);
|
||||
|
||||
#endif /* K_EVENT_H */
|
||||
|
||||
64
Living_SDK/kernel/rhino/core/include/k_hook.h
Executable file
64
Living_SDK/kernel/rhino/core/include/k_hook.h
Executable file
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef K_HOOK_H
|
||||
#define K_HOOK_H
|
||||
|
||||
#if (RHINO_CONFIG_USER_HOOK > 0)
|
||||
/**
|
||||
* This function will provide init hook
|
||||
*/
|
||||
void krhino_init_hook(void);
|
||||
|
||||
/**
|
||||
* This function will provide system start hook
|
||||
*/
|
||||
void krhino_start_hook(void);
|
||||
|
||||
/**
|
||||
* This function will provide task create hook
|
||||
* @param[in] task pointer to the task
|
||||
*/
|
||||
void krhino_task_create_hook(ktask_t *task);
|
||||
|
||||
/**
|
||||
* This function will provide task delete hook
|
||||
* @param[in] task pointer to the task
|
||||
*/
|
||||
void krhino_task_del_hook(ktask_t *task, res_free_t *arg);
|
||||
|
||||
/**
|
||||
* This function will provide task abort hook
|
||||
* @param[in] task pointer to the task
|
||||
*/
|
||||
void krhino_task_abort_hook(ktask_t *task);
|
||||
|
||||
/**
|
||||
* This function will provide task switch hook
|
||||
*/
|
||||
void krhino_task_switch_hook(ktask_t *orgin, ktask_t *dest);
|
||||
|
||||
/**
|
||||
* This function will provide system tick hook
|
||||
*/
|
||||
void krhino_tick_hook(void);
|
||||
|
||||
/**
|
||||
* This function will provide idle hook
|
||||
*/
|
||||
void krhino_idle_hook(void);
|
||||
|
||||
/**
|
||||
* This function will provide idle pre hook
|
||||
*/
|
||||
void krhino_idle_pre_hook(void);
|
||||
|
||||
/**
|
||||
* This function will provide krhino_mm_alloc hook
|
||||
*/
|
||||
void krhino_mm_alloc_hook(void *mem, size_t size);
|
||||
#endif
|
||||
|
||||
#endif /* K_HOOK_H */
|
||||
|
||||
180
Living_SDK/kernel/rhino/core/include/k_internal.h
Executable file
180
Living_SDK/kernel/rhino/core/include/k_internal.h
Executable file
|
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef K_INTERNAL_H
|
||||
#define K_INTERNAL_H
|
||||
|
||||
extern kstat_t g_sys_stat;
|
||||
extern uint8_t g_idle_task_spawned[RHINO_CONFIG_CPU_NUM];
|
||||
|
||||
extern runqueue_t g_ready_queue;
|
||||
|
||||
/* System lock */
|
||||
extern uint8_t g_sched_lock[RHINO_CONFIG_CPU_NUM];
|
||||
extern uint8_t g_intrpt_nested_level[RHINO_CONFIG_CPU_NUM];
|
||||
|
||||
/* highest pri ready task object */
|
||||
extern ktask_t *g_preferred_ready_task[RHINO_CONFIG_CPU_NUM];
|
||||
|
||||
/* current active task */
|
||||
extern ktask_t *g_active_task[RHINO_CONFIG_CPU_NUM];
|
||||
|
||||
/* idle attribute */
|
||||
extern ktask_t g_idle_task[RHINO_CONFIG_CPU_NUM];
|
||||
extern idle_count_t g_idle_count[RHINO_CONFIG_CPU_NUM];
|
||||
extern cpu_stack_t g_idle_task_stack[RHINO_CONFIG_CPU_NUM][RHINO_CONFIG_IDLE_TASK_STACK_SIZE];
|
||||
|
||||
/* tick attribute */
|
||||
extern tick_t g_tick_count;
|
||||
extern klist_t g_tick_head;
|
||||
|
||||
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
|
||||
extern kobj_list_t g_kobj_list;
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_TIMER > 0)
|
||||
extern klist_t g_timer_head;
|
||||
extern sys_time_t g_timer_count;
|
||||
extern ktask_t g_timer_task;
|
||||
extern cpu_stack_t g_timer_task_stack[RHINO_CONFIG_TIMER_TASK_STACK_SIZE];
|
||||
extern kbuf_queue_t g_timer_queue;
|
||||
extern k_timer_queue_cb timer_queue_cb[RHINO_CONFIG_TIMER_MSG_NUM];
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_DISABLE_SCHED_STATS > 0)
|
||||
extern hr_timer_t g_sched_disable_time_start;
|
||||
extern hr_timer_t g_sched_disable_max_time;
|
||||
extern hr_timer_t g_cur_sched_disable_max_time;
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_DISABLE_INTRPT_STATS > 0)
|
||||
extern uint16_t g_intrpt_disable_times;
|
||||
extern hr_timer_t g_intrpt_disable_time_start;
|
||||
extern hr_timer_t g_intrpt_disable_max_time;
|
||||
extern hr_timer_t g_cur_intrpt_disable_max_time;
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_HW_COUNT > 0)
|
||||
extern hr_timer_t g_sys_measure_waste;
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_CPU_USAGE_STATS > 0)
|
||||
extern ktask_t g_cpu_usage_task;
|
||||
extern cpu_stack_t g_cpu_task_stack[RHINO_CONFIG_CPU_USAGE_TASK_STACK];
|
||||
extern idle_count_t g_idle_count_max;
|
||||
extern uint32_t g_cpu_usage;
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_TASK_SCHED_STATS > 0)
|
||||
extern ctx_switch_t g_sys_ctx_switch_times;
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0)
|
||||
extern ksem_t g_res_sem;
|
||||
extern klist_t g_res_list;
|
||||
extern ktask_t g_dyn_task;
|
||||
extern cpu_stack_t g_dyn_task_stack[RHINO_CONFIG_K_DYN_TASK_STACK];
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_WORKQUEUE > 0)
|
||||
extern klist_t g_workqueue_list_head;
|
||||
extern kmutex_t g_workqueue_mutex;
|
||||
extern kworkqueue_t g_workqueue_default;
|
||||
extern cpu_stack_t g_workqueue_stack[RHINO_CONFIG_WORKQUEUE_STACK_SIZE];
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_MM_TLF > 0)
|
||||
extern k_mm_head *g_kmm_head;
|
||||
#endif
|
||||
|
||||
#define K_OBJ_STATIC_ALLOC 1u
|
||||
#define K_OBJ_DYN_ALLOC 2u
|
||||
|
||||
#define NULL_PARA_CHK(para) \
|
||||
do { \
|
||||
if (para == NULL) { \
|
||||
return RHINO_NULL_PTR; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define INTRPT_NESTED_LEVEL_CHK()\
|
||||
do { \
|
||||
if (g_intrpt_nested_level[cpu_cur_get()] > 0u) { \
|
||||
RHINO_CRITICAL_EXIT(); \
|
||||
return RHINO_NOT_CALLED_BY_INTRPT; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define RES_FREE_NUM 4
|
||||
|
||||
typedef struct {
|
||||
uint8_t cnt;
|
||||
void *res[RES_FREE_NUM];
|
||||
klist_t res_list;
|
||||
} res_free_t;
|
||||
|
||||
void preferred_cpu_ready_task_get(runqueue_t *rq, uint8_t cpu_num);
|
||||
|
||||
void core_sched(void);
|
||||
void runqueue_init(runqueue_t *rq);
|
||||
|
||||
void ready_list_add(runqueue_t *rq, ktask_t *task);
|
||||
void ready_list_add_head(runqueue_t *rq, ktask_t *task);
|
||||
void ready_list_add_tail(runqueue_t *rq, ktask_t *task);
|
||||
void ready_list_rm(runqueue_t *rq, ktask_t *task);
|
||||
void ready_list_head_to_tail(runqueue_t *rq, ktask_t *task);
|
||||
|
||||
void time_slice_update(void);
|
||||
void timer_task_sched(void);
|
||||
|
||||
void pend_list_reorder(ktask_t *task);
|
||||
void pend_task_wakeup(ktask_t *task);
|
||||
void pend_to_blk_obj(blk_obj_t *blk_obj, ktask_t *task, tick_t timeout);
|
||||
void pend_task_rm(ktask_t *task);
|
||||
|
||||
kstat_t pend_state_end_proc(ktask_t *task);
|
||||
|
||||
void idle_task(void *p_arg);
|
||||
void idle_count_set(idle_count_t value);
|
||||
idle_count_t idle_count_get(void);
|
||||
|
||||
void tick_list_init(void);
|
||||
void tick_task_start(void);
|
||||
void tick_list_rm(ktask_t *task);
|
||||
void tick_list_insert(ktask_t *task, tick_t time);
|
||||
void tick_list_update(tick_i_t ticks);
|
||||
|
||||
uint8_t mutex_pri_limit(ktask_t *tcb, uint8_t pri);
|
||||
void mutex_task_pri_reset(ktask_t *tcb);
|
||||
uint8_t mutex_pri_look(ktask_t *tcb, kmutex_t *mutex_rel);
|
||||
|
||||
kstat_t task_pri_change(ktask_t *task, uint8_t new_pri);
|
||||
|
||||
void k_err_proc(kstat_t err);
|
||||
|
||||
void ktimer_init(void);
|
||||
|
||||
void intrpt_disable_measure_start(void);
|
||||
void intrpt_disable_measure_stop(void);
|
||||
void dyn_mem_proc_task_start(void);
|
||||
void cpu_usage_stats_start(void);
|
||||
|
||||
kstat_t ringbuf_init(k_ringbuf_t *p_ringbuf, void *buf, size_t len, size_t type,
|
||||
size_t block_size);
|
||||
kstat_t ringbuf_reset(k_ringbuf_t *p_ringbuf);
|
||||
kstat_t ringbuf_push(k_ringbuf_t *p_ringbuf, void *data, size_t len);
|
||||
kstat_t ringbuf_head_push(k_ringbuf_t *p_ringbuf, void *data, size_t len);
|
||||
kstat_t ringbuf_pop(k_ringbuf_t *p_ringbuf, void *pdata, size_t *plen);
|
||||
uint8_t ringbuf_is_full(k_ringbuf_t *p_ringbuf);
|
||||
uint8_t ringbuf_is_empty(k_ringbuf_t *p_ringbuf);
|
||||
void workqueue_init(void);
|
||||
void k_mm_init(void);
|
||||
|
||||
#if (RHINO_CONFIG_CPU_PWR_MGMT > 0)
|
||||
void cpu_pwr_down(void);
|
||||
void cpu_pwr_up(void);
|
||||
#endif
|
||||
|
||||
#endif /* K_INTERNAL_H */
|
||||
|
||||
60
Living_SDK/kernel/rhino/core/include/k_list.h
Normal file
60
Living_SDK/kernel/rhino/core/include/k_list.h
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef K_LIST_H
|
||||
#define K_LIST_H
|
||||
|
||||
typedef struct klist_s {
|
||||
struct klist_s *next;
|
||||
struct klist_s *prev;
|
||||
} klist_t;
|
||||
|
||||
#define krhino_list_entry(node, type, member) ((type *)((uint8_t *)(node) - (size_t)(&((type *)0)->member)))
|
||||
|
||||
RHINO_INLINE void klist_init(klist_t *list_head)
|
||||
{
|
||||
list_head->next = list_head;
|
||||
list_head->prev = list_head;
|
||||
}
|
||||
|
||||
RHINO_INLINE uint8_t is_klist_empty(klist_t *list)
|
||||
{
|
||||
return (list->next == list);
|
||||
}
|
||||
|
||||
RHINO_INLINE void klist_insert(klist_t *head, klist_t *element)
|
||||
{
|
||||
element->prev = head->prev;
|
||||
element->next = head;
|
||||
|
||||
head->prev->next = element;
|
||||
head->prev = element;
|
||||
}
|
||||
|
||||
RHINO_INLINE void klist_add(klist_t *head, klist_t *element)
|
||||
{
|
||||
element->prev = head;
|
||||
element->next = head->next;
|
||||
|
||||
head->next->prev = element;
|
||||
head->next = element;
|
||||
}
|
||||
|
||||
RHINO_INLINE void klist_rm(klist_t *element)
|
||||
{
|
||||
element->prev->next = element->next;
|
||||
element->next->prev = element->prev;
|
||||
}
|
||||
|
||||
RHINO_INLINE void klist_rm_init(klist_t *element)
|
||||
{
|
||||
element->prev->next = element->next;
|
||||
element->next->prev = element->prev;
|
||||
|
||||
element->next = element->prev = element;
|
||||
}
|
||||
|
||||
|
||||
#endif /* K_LIST_H */
|
||||
|
||||
173
Living_SDK/kernel/rhino/core/include/k_mm.h
Normal file
173
Living_SDK/kernel/rhino/core/include/k_mm.h
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef K_MM_H
|
||||
#define K_MM_H
|
||||
|
||||
/*use two level bit map to find free memory block*/
|
||||
|
||||
#if (RHINO_CONFIG_MM_TLF > 0)
|
||||
/* alignment: */
|
||||
#define MM_ALIGN_BIT 3
|
||||
#define MM_ALIGN_SIZE (1 << MM_ALIGN_BIT)
|
||||
#define MM_ALIGN_MASK (MM_ALIGN_SIZE - 1)
|
||||
#define MM_ALIGN_UP(a) (((a) + MM_ALIGN_MASK) & ~MM_ALIGN_MASK)
|
||||
#define MM_ALIGN_DOWN(a) ((a) & ~MM_ALIGN_MASK)
|
||||
|
||||
/* mm bitmask freelist: */
|
||||
#define MM_MAX_BIT RHINO_CONFIG_MM_MAXMSIZEBIT
|
||||
#define MM_MAX_SIZE (1 << MM_MAX_BIT)
|
||||
|
||||
#define MM_MIN_BIT RHINO_CONFIG_MM_MINISIZEBIT
|
||||
#define MM_MIN_SIZE (1 << (MM_MIN_BIT - 1))
|
||||
#define MM_BIT_LEVEL (MM_MAX_BIT - MM_MIN_BIT + 2)
|
||||
|
||||
|
||||
#define MIN_FREE_MEMORY_SIZE 1024 /*at least need 1k for user alloced*/
|
||||
|
||||
/*bit 0 and bit 1 mask*/
|
||||
#define RHINO_MM_CURSTAT_MASK 0x1
|
||||
#define RHINO_MM_PRESTAT_MASK 0x2
|
||||
|
||||
/*bit 0*/
|
||||
#define RHINO_MM_FREE 1
|
||||
#define RHINO_MM_ALLOCED 0
|
||||
|
||||
/*bit 1*/
|
||||
#define RHINO_MM_PREVFREE 2
|
||||
#define RHINO_MM_PREVALLOCED 0
|
||||
|
||||
#define MMLIST_HEAD_SIZE (MM_ALIGN_UP(sizeof(k_mm_list_t) - sizeof(free_ptr_t)))
|
||||
|
||||
/* get buffer size */
|
||||
#define MM_GET_BUF_SIZE(blk) ((blk)->buf_size & (~MM_ALIGN_MASK))
|
||||
/* get blk size : head size + buffer size */
|
||||
#define MM_GET_BLK_SIZE(blk) (MM_GET_BUF_SIZE(blk) + MMLIST_HEAD_SIZE)
|
||||
/* get next blk */
|
||||
#define MM_GET_NEXT_BLK(blk) \
|
||||
((k_mm_list_t *)((blk)->mbinfo.buffer + MM_GET_BUF_SIZE(blk)))
|
||||
/* get this blk */
|
||||
#define MM_GET_THIS_BLK(buf) ((k_mm_list_t *)((char *)(buf)-MMLIST_HEAD_SIZE))
|
||||
|
||||
/* MM critical */
|
||||
#if (RHINO_CONFIG_MM_REGION_MUTEX == 0)
|
||||
#define MM_CRITICAL_ENTER(pmmhead) \
|
||||
krhino_spin_lock_irq_save(&(pmmhead->mm_lock));
|
||||
#define MM_CRITICAL_EXIT(pmmhead) \
|
||||
krhino_spin_unlock_irq_restore(&(pmmhead->mm_lock));
|
||||
#else //(RHINO_CONFIG_MM_REGION_MUTEX != 0)
|
||||
#define MM_CRITICAL_ENTER(pmmhead) \
|
||||
do { \
|
||||
CPSR_ALLOC(); \
|
||||
RHINO_CRITICAL_ENTER(); \
|
||||
if (g_intrpt_nested_level[cpu_cur_get()] > 0u) { \
|
||||
k_err_proc(RHINO_NOT_CALLED_BY_INTRPT); \
|
||||
} \
|
||||
RHINO_CRITICAL_EXIT(); \
|
||||
krhino_mutex_lock(&(pmmhead->mm_mutex), RHINO_WAIT_FOREVER); \
|
||||
} while (0);
|
||||
#define MM_CRITICAL_EXIT(pmmhead) krhino_mutex_unlock(&(pmmhead->mm_mutex))
|
||||
#endif
|
||||
|
||||
/*struct of memory list ,every memory block include this information*/
|
||||
typedef struct free_ptr_struct
|
||||
{
|
||||
struct k_mm_list_struct *prev;
|
||||
struct k_mm_list_struct *next;
|
||||
} free_ptr_t;
|
||||
|
||||
typedef struct k_mm_list_struct
|
||||
{
|
||||
#if (RHINO_CONFIG_MM_DEBUG > 0)
|
||||
size_t dye;
|
||||
size_t owner;
|
||||
#endif
|
||||
struct k_mm_list_struct *prev;
|
||||
/* bit 0 indicates whether the block is used and */
|
||||
/* bit 1 allows to know whether the previous block is free */
|
||||
size_t buf_size;
|
||||
union
|
||||
{
|
||||
struct free_ptr_struct free_ptr;
|
||||
uint8_t buffer[1];
|
||||
} mbinfo;
|
||||
} k_mm_list_t;
|
||||
|
||||
typedef struct k_mm_region_info_struct
|
||||
{
|
||||
k_mm_list_t * end;
|
||||
struct k_mm_region_info_struct *next;
|
||||
} k_mm_region_info_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
#if (RHINO_CONFIG_MM_REGION_MUTEX > 0)
|
||||
kmutex_t mm_mutex;
|
||||
#else
|
||||
kspinlock_t mm_lock;
|
||||
#endif
|
||||
k_mm_region_info_t *regioninfo;
|
||||
#if (RHINO_CONFIG_MM_BLK > 0)
|
||||
void *fix_pool;
|
||||
#endif
|
||||
#if (K_MM_STATISTIC > 0)
|
||||
size_t used_size;
|
||||
size_t maxused_size;
|
||||
size_t free_size;
|
||||
/* number of times for each TLF level */
|
||||
size_t alloc_times[MM_BIT_LEVEL];
|
||||
#endif
|
||||
/* msb (MM_BIT_LEVEL-1) <-> lsb 0, one bit match one freelist */
|
||||
uint32_t free_bitmap;
|
||||
/* freelist[N]: contain free blks at level N,
|
||||
2^(N + MM_MIN_BIT) <= level N buffer size < 2^(1 + N + MM_MIN_BIT) */
|
||||
k_mm_list_t *freelist[MM_BIT_LEVEL];
|
||||
} k_mm_head;
|
||||
|
||||
kstat_t krhino_init_mm_head(k_mm_head **ppmmhead, void *addr, size_t len);
|
||||
kstat_t krhino_deinit_mm_head(k_mm_head *mmhead);
|
||||
kstat_t krhino_add_mm_region(k_mm_head *mmhead, void *addr, size_t len);
|
||||
|
||||
void *k_mm_alloc(k_mm_head *mmhead, size_t size);
|
||||
void k_mm_free(k_mm_head *mmhead, void *ptr);
|
||||
void *k_mm_realloc(k_mm_head *mmhead, void *oldmem, size_t new_size);
|
||||
|
||||
/**
|
||||
* This function is wrapper of mm allocation
|
||||
* @param[in] size size of the mem to malloc
|
||||
* @return the operation status, NULL is error, others is memory address
|
||||
*/
|
||||
void *krhino_mm_alloc(size_t size);
|
||||
|
||||
/**
|
||||
* This function is wrapper of mm free
|
||||
* @param[in] ptr address point of the mem
|
||||
*/
|
||||
|
||||
void krhino_mm_free(void *ptr);
|
||||
|
||||
|
||||
/**
|
||||
* This function is wrapper of mm rallocation
|
||||
* @param[in] oldmem oldmem address
|
||||
* @param[in] size size of the mem to malloc
|
||||
* @return the operation status, NULL is error, others is realloced memory
|
||||
* address
|
||||
*/
|
||||
void *krhino_mm_realloc(void *oldmem, size_t newsize);
|
||||
|
||||
|
||||
/**
|
||||
* This function is wrapper of mm rallocation
|
||||
* @param[in] oldmem oldmem address
|
||||
* @param[in] size size of the mem to malloc
|
||||
* @return the operation status, NULL is error, others is realloced memory
|
||||
* address
|
||||
*/
|
||||
void krhino_mm_overview(int (*print_func)(const char *fmt, ...));
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* K_MM_BESTFIT_H */
|
||||
63
Living_SDK/kernel/rhino/core/include/k_mm_blk.h
Normal file
63
Living_SDK/kernel/rhino/core/include/k_mm_blk.h
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef K_MM_BLK_H
|
||||
#define K_MM_BLK_H
|
||||
|
||||
typedef struct {
|
||||
const name_t *pool_name;
|
||||
void *pool_end; /* end address */
|
||||
void *pool_start; /* start address */
|
||||
size_t blk_size;
|
||||
size_t blk_avail; /* num of available(free) blk */
|
||||
size_t blk_whole; /* num of all blk */
|
||||
uint8_t *avail_list;
|
||||
kspinlock_t blk_lock;
|
||||
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
|
||||
klist_t mblkpool_stats_item;
|
||||
#endif
|
||||
} mblk_pool_t;
|
||||
|
||||
/**
|
||||
* This function will init a blk-pool
|
||||
* @param[in] pool pointer to the pool
|
||||
* @param[in] name name of the pool
|
||||
* @param[in] pool_start start addr of the pool
|
||||
* @param[in] blk_size size of the blk
|
||||
* @param[in] pool_size size of the pool
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_mblk_pool_init(mblk_pool_t *pool, const name_t *name,
|
||||
void *pool_start,
|
||||
size_t blk_size, size_t pool_size);
|
||||
|
||||
/**
|
||||
* This function will alloc a blk-pool
|
||||
* @param[in] pool pointer to a pool
|
||||
* @param[in] blk pointer to a blk
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_mblk_alloc(mblk_pool_t *pool, void **blk);
|
||||
|
||||
/**
|
||||
* This function will free a blk-pool
|
||||
* @param[in] pool pointer to the pool
|
||||
* @param[in] blk pointer to the blk
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_mblk_free(mblk_pool_t *pool, void *blk);
|
||||
|
||||
/**
|
||||
* is blk in pool?
|
||||
* @param[in] pool pointer to the pool
|
||||
* @param[in] blk pointer to the blk
|
||||
* @return yes return 1, no reture 0
|
||||
*/
|
||||
#define krhino_mblk_check(pool, blk) \
|
||||
((pool) != NULL \
|
||||
&& ((void *)(blk) >= ((mblk_pool_t*)(pool))->pool_start) \
|
||||
&& ((void *)(blk) < ((mblk_pool_t*)(pool))->pool_end))
|
||||
|
||||
#endif /* K_MM_BLK_H */
|
||||
|
||||
40
Living_SDK/kernel/rhino/core/include/k_mm_debug.h
Normal file
40
Living_SDK/kernel/rhino/core/include/k_mm_debug.h
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef RHINO_MM_DEBUG_H
|
||||
#define RHINO_MM_DEBUG_H
|
||||
|
||||
#if (RHINO_CONFIG_MM_DEBUG > 0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define AOS_MM_SCAN_REGION_MAX 10
|
||||
typedef struct {
|
||||
void *start;
|
||||
void *end;
|
||||
} mm_scan_region_t;
|
||||
|
||||
#if (RHINO_CONFIG_GCC_RETADDR > 0u)
|
||||
#include <k_mm.h>
|
||||
#define AOS_UNSIGNED_INT_MSB (1u << (sizeof(unsigned int) * 8 - 1))
|
||||
void krhino_owner_attach(k_mm_head *mmhead, void *addr, size_t allocator);
|
||||
#endif
|
||||
|
||||
uint32_t krhino_mm_leak_region_init(void *start, void *end);
|
||||
|
||||
uint32_t dumpsys_mm_info_func(uint32_t len);
|
||||
|
||||
uint32_t dump_mmleak(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* RHINO_CONFIG_MM_DEBUG */
|
||||
|
||||
#endif /* YSH_H */
|
||||
|
||||
|
||||
14
Living_SDK/kernel/rhino/core/include/k_mm_region.h
Normal file
14
Living_SDK/kernel/rhino/core/include/k_mm_region.h
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef K_MM_REGION_H
|
||||
#define K_MM_REGION_H
|
||||
|
||||
typedef struct {
|
||||
uint8_t *start;
|
||||
size_t len;
|
||||
} k_mm_region_t;
|
||||
|
||||
#endif /* K_MM_REGION_H */
|
||||
|
||||
69
Living_SDK/kernel/rhino/core/include/k_mutex.h
Normal file
69
Living_SDK/kernel/rhino/core/include/k_mutex.h
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef K_MUTEX_H
|
||||
#define K_MUTEX_H
|
||||
|
||||
typedef struct mutex_s {
|
||||
blk_obj_t blk_obj;
|
||||
ktask_t *mutex_task; /* mutex owner task */
|
||||
struct mutex_s *mutex_list; /* task mutex list */
|
||||
mutex_nested_t owner_nested;
|
||||
|
||||
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
|
||||
klist_t mutex_item;
|
||||
#endif
|
||||
|
||||
uint8_t mm_alloc_flag;
|
||||
} kmutex_t;
|
||||
|
||||
/**
|
||||
* This function will create a mutex
|
||||
* @param[in] mutex pointer to the mutex(the space is provided by user)
|
||||
* @param[in] name name of the mutex
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_mutex_create(kmutex_t *mutex, const name_t *name);
|
||||
|
||||
/**
|
||||
* This function will delete a mutex
|
||||
* @param[in] mutex pointer to the mutex
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_mutex_del(kmutex_t *mutex);
|
||||
|
||||
#if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0)
|
||||
/**
|
||||
* This function will create a dyn mutex
|
||||
* @param[in] mutex pointer to the mutex(the space is provided by user)
|
||||
* @param[in] name name of the mutex
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_mutex_dyn_create(kmutex_t **mutex, const name_t *name);
|
||||
|
||||
/**
|
||||
* This function will delete a dyn mutex
|
||||
* @param[in] mutex pointer to the mutex
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_mutex_dyn_del(kmutex_t *mutex);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This function will lock mutex
|
||||
* @param[in] mutex pointer to the mutex
|
||||
* @param[in] ticks ticks to be wait for before lock
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_mutex_lock(kmutex_t *mutex, tick_t ticks);
|
||||
|
||||
/**
|
||||
* This function will unlock a mutex
|
||||
* @param[in] mutex pointer to the mutex
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_mutex_unlock(kmutex_t *mutex);
|
||||
|
||||
#endif /* K_MUTEX_H */
|
||||
|
||||
65
Living_SDK/kernel/rhino/core/include/k_obj.h
Normal file
65
Living_SDK/kernel/rhino/core/include/k_obj.h
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef K_OBJ_H
|
||||
#define K_OBJ_H
|
||||
|
||||
typedef enum {
|
||||
BLK_POLICY_PRI = 0u,
|
||||
BLK_POLICY_FIFO
|
||||
} blk_policy_t;
|
||||
|
||||
typedef enum {
|
||||
BLK_FINISH = 0,
|
||||
BLK_ABORT,
|
||||
BLK_TIMEOUT,
|
||||
BLK_DEL,
|
||||
BLK_INVALID
|
||||
} blk_state_t;
|
||||
|
||||
typedef enum {
|
||||
RHINO_OBJ_TYPE_NONE = 0,
|
||||
RHINO_SEM_OBJ_TYPE,
|
||||
RHINO_MUTEX_OBJ_TYPE,
|
||||
RHINO_QUEUE_OBJ_TYPE,
|
||||
RHINO_BUF_QUEUE_OBJ_TYPE,
|
||||
RHINO_TIMER_OBJ_TYPE,
|
||||
RHINO_EVENT_OBJ_TYPE,
|
||||
RHINO_MM_OBJ_TYPE
|
||||
} kobj_type_t;
|
||||
|
||||
typedef struct blk_obj {
|
||||
klist_t blk_list;
|
||||
const name_t *name;
|
||||
blk_policy_t blk_policy;
|
||||
kobj_type_t obj_type;
|
||||
} blk_obj_t;
|
||||
|
||||
typedef struct {
|
||||
klist_t task_head;
|
||||
klist_t mutex_head;
|
||||
|
||||
#if (RHINO_CONFIG_MM_BLK > 0)
|
||||
klist_t mblkpool_head;
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_SEM > 0)
|
||||
klist_t sem_head;
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_QUEUE > 0)
|
||||
klist_t queue_head;
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_EVENT_FLAG > 0)
|
||||
klist_t event_head;
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_BUF_QUEUE > 0)
|
||||
klist_t buf_queue_head;
|
||||
#endif
|
||||
} kobj_list_t;
|
||||
|
||||
#endif /* K_OBJ_H */
|
||||
|
||||
118
Living_SDK/kernel/rhino/core/include/k_queue.h
Normal file
118
Living_SDK/kernel/rhino/core/include/k_queue.h
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef K_QUEUE_H
|
||||
#define K_QUEUE_H
|
||||
|
||||
#define WAKE_ONE_TASK 0u
|
||||
#define WAKE_ALL_TASK 1u
|
||||
|
||||
typedef struct {
|
||||
void **queue_start;
|
||||
size_t size;
|
||||
size_t cur_num;
|
||||
size_t peak_num;
|
||||
} msg_q_t;
|
||||
|
||||
typedef struct {
|
||||
msg_q_t msg_q;
|
||||
klist_t *pend_entry;
|
||||
} msg_info_t;
|
||||
|
||||
typedef struct queue_s {
|
||||
blk_obj_t blk_obj;
|
||||
k_ringbuf_t ringbuf;
|
||||
msg_q_t msg_q;
|
||||
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
|
||||
klist_t queue_item;
|
||||
#endif
|
||||
uint8_t mm_alloc_flag;
|
||||
} kqueue_t;
|
||||
|
||||
/**
|
||||
* This function will create a queue
|
||||
* @param[in] queue pointer to the queue(the space is provided by user)
|
||||
* @param[in] name name of the queue
|
||||
* @param[in] start start address of the queue internal space
|
||||
* @param[in] msg_num num of the msg
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_queue_create(kqueue_t *queue, const name_t *name, void **start,
|
||||
size_t msg_num);
|
||||
|
||||
/**
|
||||
* This function will delete a queue
|
||||
* @param[in] queue pointer to the queue
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_queue_del(kqueue_t *queue);
|
||||
|
||||
#if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0)
|
||||
/**
|
||||
* This function will create a dyn queue
|
||||
* @param[in] queue pointer to the queue
|
||||
* @param[in] name name of the queue
|
||||
* @param[in] msg_num num of the msg
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_queue_dyn_create(kqueue_t **queue, const name_t *name,
|
||||
size_t msg_num);
|
||||
|
||||
/**
|
||||
* This function will delete a dyn created queue
|
||||
* @param[in] queue pointer to the queue
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_queue_dyn_del(kqueue_t *queue);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This function will send a msg to the back of a queue
|
||||
* @param[in] queue pointer to the queue
|
||||
* @param[in] msg msg to send
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_queue_back_send(kqueue_t *queue, void *msg);
|
||||
|
||||
/**
|
||||
* This function will send a msg to a queue and wake all tasks
|
||||
* @param[in] queue pointer to the queue
|
||||
* @param[in] msg msg to send
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_queue_all_send(kqueue_t *queue, void *msg);
|
||||
|
||||
/**
|
||||
* This function will receive msg from a queue
|
||||
* @param[in] queue pointer to the queue
|
||||
* @param[in] ticks ticks to wait before receive
|
||||
* @param[out] msg buf to save msg
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_queue_recv(kqueue_t *queue, tick_t ticks, void **msg);
|
||||
|
||||
/**
|
||||
* This function will detect a queue full or not
|
||||
* @param[in] queue pointer to the queue
|
||||
* @return the operation status, RHINO_QUEUE_FULL/RHINO_QUEUE_NOT_FULL
|
||||
*/
|
||||
kstat_t krhino_queue_is_full(kqueue_t *queue);
|
||||
|
||||
/**
|
||||
* This function will reset a queue
|
||||
* @param[in] queue pointer to the queue
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_queue_flush(kqueue_t *queue);
|
||||
|
||||
/**
|
||||
* This function will get information of a queue
|
||||
* @param[in] queue pointer to the queue
|
||||
* @param[out] info buf to save msg-info
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_queue_info_get(kqueue_t *queue, msg_info_t *info);
|
||||
|
||||
#endif /* K_QUEUE_H */
|
||||
|
||||
101
Living_SDK/kernel/rhino/core/include/k_ringbuf.h
Normal file
101
Living_SDK/kernel/rhino/core/include/k_ringbuf.h
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef K_MM_RINGBUF_H
|
||||
#define K_MM_RINGBUF_H
|
||||
|
||||
#define RINGBUF_TYPE_FIX 0
|
||||
#define RINGBUF_TYPE_DYN 1
|
||||
|
||||
#define RINGBUF_LEN_MAX_SIZE 3
|
||||
#define RINGBUF_LEN_MASK_ONEBIT 0x80 //1000 0000
|
||||
#define RINGBUF_LEN_MASK_TWOBIT 0xC0 //1100 0000
|
||||
#define RINGBUF_LEN_MASK_CLEAN_TWOBIT 0x3f //0011 1111
|
||||
|
||||
|
||||
#define RINGBUF_LEN_VLE_2BYTES 0x80 //1000 0000
|
||||
#define RINGBUF_LEN_VLE_3BYTES 0xC0 //1100 0000
|
||||
|
||||
#define RINGBUF_LEN_1BYTE_MAXVALUE 0x7f //0111 1111; 127
|
||||
#define RINGBUF_LEN_2BYTES_MAXVALUE 0x3fff // 16383
|
||||
#define RINGBUF_LEN_3BYTES_MAXVALUE 0x3fffff //4194303
|
||||
|
||||
|
||||
#ifndef true
|
||||
#define true 1
|
||||
#endif
|
||||
|
||||
#ifndef false
|
||||
#define false 0
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uint8_t *buf;
|
||||
uint8_t *end;
|
||||
uint8_t *head;
|
||||
uint8_t *tail;
|
||||
size_t freesize;
|
||||
size_t type;
|
||||
size_t blk_size;
|
||||
} k_ringbuf_t;
|
||||
|
||||
#define COMPRESS_LEN(x) ((x) <= RINGBUF_LEN_1BYTE_MAXVALUE ? 1: (x) <= RINGBUF_LEN_2BYTES_MAXVALUE ? 2: \
|
||||
(x) <= RINGBUF_LEN_3BYTES_MAXVALUE ? 3 : RHINO_INV_PARAM)
|
||||
|
||||
|
||||
#if (RHINO_CONFIG_RINGBUF_VENDOR > 0)
|
||||
/**
|
||||
* This function will init the mm ring buffer.
|
||||
* @param[in] p_ringbuf pointer to ring buffer
|
||||
* @param[in] buf pointer to memory buffer
|
||||
* @param[in] len length of memory buffer
|
||||
* @param[in] type type of ring buffer, fix length or dynamic length
|
||||
* @param[in] block_size block size of fix length ringbuf, if dynamic ringbuffer, ignore this parameter
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_ringbuf_init (k_ringbuf_t *p_ringbuf, void *buf, size_t len,
|
||||
size_t type, size_t block_size);
|
||||
|
||||
/**
|
||||
* This function will clean all data in mm ring buffer.
|
||||
* @param[in] p_ringbuf pointer to ring buffer
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_ringbuf_reset(k_ringbuf_t *p_ringbuf);
|
||||
|
||||
/**
|
||||
* This function will push the data to ring buffer end.
|
||||
* @param[in] p_ringbuf pointer to ring buffer
|
||||
* @param[in] data pointer to data
|
||||
* @param[in] len length of data
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_ringbuf_push(k_ringbuf_t *p_ringbuf, void *data, size_t len);
|
||||
|
||||
/**
|
||||
* This function will pop the data from ring buffer head.
|
||||
* @param[in] p_ringbuf pointer to ring buffer
|
||||
* @param[out] pdata pointer to data
|
||||
* @param[out] plen length of data
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_ringbuf_pop(k_ringbuf_t *p_ringbuf, void *pdata, size_t *plen);
|
||||
|
||||
|
||||
/**
|
||||
* This function will check if the ring buffer is full.
|
||||
* @param[in] p_ringbuf pointer to ring buffer
|
||||
* @return the ringbuf status, true is full. else is not.
|
||||
*/
|
||||
uint8_t krhino_ringbuf_is_full(k_ringbuf_t *p_ringbuf);
|
||||
|
||||
/**
|
||||
* This function will check if the ring buffer is empty.
|
||||
* @param[in] p_ringbuf pointer to ring buffer
|
||||
* @return the ringbuf status, true is empty. else is not.
|
||||
*/
|
||||
uint8_t krhino_ringbuf_is_empty(k_ringbuf_t *p_ringbuf);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
32
Living_SDK/kernel/rhino/core/include/k_sched.h
Normal file
32
Living_SDK/kernel/rhino/core/include/k_sched.h
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef K_SCHED_H
|
||||
#define K_SCHED_H
|
||||
|
||||
#define KSCHED_FIFO 0u
|
||||
#define KSCHED_RR 1u
|
||||
#define SCHED_MAX_LOCK_COUNT 200u
|
||||
#define NUM_WORDS ((RHINO_CONFIG_PRI_MAX + 31) / 32)
|
||||
|
||||
typedef struct {
|
||||
klist_t *cur_list_item[RHINO_CONFIG_PRI_MAX];
|
||||
uint32_t task_bit_map[NUM_WORDS];
|
||||
uint8_t highest_pri;
|
||||
} runqueue_t;
|
||||
|
||||
/**
|
||||
* This function will disable schedule
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_sched_disable(void);
|
||||
|
||||
/**
|
||||
* This function will enable schedule
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_sched_enable(void);
|
||||
|
||||
#endif /* K_SCHED_H */
|
||||
|
||||
95
Living_SDK/kernel/rhino/core/include/k_sem.h
Normal file
95
Living_SDK/kernel/rhino/core/include/k_sem.h
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef K_SEM_H
|
||||
#define K_SEM_H
|
||||
|
||||
#define WAKE_ONE_SEM 0u
|
||||
#define WAKE_ALL_SEM 1u
|
||||
|
||||
typedef struct sem_s {
|
||||
blk_obj_t blk_obj;
|
||||
sem_count_t count;
|
||||
sem_count_t peak_count;
|
||||
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
|
||||
klist_t sem_item;
|
||||
#endif
|
||||
uint8_t mm_alloc_flag;
|
||||
} ksem_t;
|
||||
|
||||
/**
|
||||
* This function will create a semaphore
|
||||
* @param[in] sem pointer to the semaphore(the space is provided by user)
|
||||
* @param[in] name name of the semaphore
|
||||
* @param[in] count the init count of the semaphore
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_sem_create(ksem_t *sem, const name_t *name, sem_count_t count);
|
||||
|
||||
/**
|
||||
* This function will delete a semaphore
|
||||
* @param[in] sem pointer to the semaphore
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_sem_del(ksem_t *sem);
|
||||
|
||||
#if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0)
|
||||
/**
|
||||
* This function will create a dyn-semaphore
|
||||
* @param[out] sem pointer to the semaphore(the space is provided by kernel)
|
||||
* @param[in] name name of the semaphore
|
||||
* @param[in] count the init count of the semaphore
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_sem_dyn_create(ksem_t **sem, const name_t *name,
|
||||
sem_count_t count);
|
||||
|
||||
/**
|
||||
* This function will delete a dyn-semaphore
|
||||
* @param[in] sem pointer to the semaphore
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_sem_dyn_del(ksem_t *sem);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This function will give a semaphore
|
||||
* @param[in] sem pointer to the semphore
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_sem_give(ksem_t *sem);
|
||||
|
||||
/**
|
||||
* This function will give a semaphore and wakeup all thee waiting task
|
||||
* @param[in] sem pointer to the semaphore
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_sem_give_all(ksem_t *sem);
|
||||
|
||||
/**
|
||||
* This function will take a semaphore
|
||||
* @param[in] sem pointer to the semaphore
|
||||
* @param[in] ticks ticks to wait before take
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_sem_take(ksem_t *sem, tick_t ticks);
|
||||
|
||||
/**
|
||||
* This function will set the count of a semaphore
|
||||
* @param[in] sem pointer to the semaphore
|
||||
* @param[in] sem_count count of the semaphore
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_sem_count_set(ksem_t *sem, sem_count_t count);
|
||||
|
||||
/**
|
||||
* This function will get count of a semaphore
|
||||
* @param[in] sem pointer to the semaphore
|
||||
* @param[out] count count of the semaphore
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_sem_count_get(ksem_t *sem, sem_count_t *count);
|
||||
|
||||
#endif /* K_SEM_H */
|
||||
|
||||
40
Living_SDK/kernel/rhino/core/include/k_soc.h
Normal file
40
Living_SDK/kernel/rhino/core/include/k_soc.h
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef K_SOC_H
|
||||
#define K_SOC_H
|
||||
|
||||
#if (RHINO_CONFIG_HW_COUNT > 0)
|
||||
void soc_hw_timer_init(void);
|
||||
hr_timer_t soc_hr_hw_cnt_get(void);
|
||||
lr_timer_t soc_lr_hw_cnt_get(void);
|
||||
#define HR_COUNT_GET() soc_hr_hw_cnt_get()
|
||||
#else /* RHINO_CONFIG_HW_COUNT */
|
||||
#define HR_COUNT_GET() 0u
|
||||
#endif /* RHINO_CONFIG_HW_COUNT */
|
||||
|
||||
#if (RHINO_CONFIG_TASK_SCHED_STATS > 0)
|
||||
#define LR_COUNT_GET() soc_lr_hw_cnt_get()
|
||||
#else /* RHINO_CONFIG_TASK_SCHED_STATS */
|
||||
#define LR_COUNT_GET() 0u
|
||||
#endif /* RHINO_CONFIG_TASK_SCHED_STATS */
|
||||
|
||||
#if (RHINO_CONFIG_INTRPT_GUARD > 0)
|
||||
void soc_intrpt_guard(void);
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_INTRPT_STACK_REMAIN_GET > 0)
|
||||
size_t soc_intrpt_stack_remain_get(void);
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_INTRPT_STACK_OVF_CHECK > 0)
|
||||
void soc_intrpt_stack_ovf_check(void);
|
||||
#endif
|
||||
|
||||
void soc_err_proc(kstat_t err);
|
||||
|
||||
size_t soc_get_cur_sp(void);
|
||||
|
||||
#endif /* K_SOC_H */
|
||||
|
||||
61
Living_SDK/kernel/rhino/core/include/k_spin_lock.h
Normal file
61
Living_SDK/kernel/rhino/core/include/k_spin_lock.h
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef K_SPIN_LOCK_H
|
||||
#define K_SPIN_LOCK_H
|
||||
|
||||
typedef struct {
|
||||
#if (RHINO_CONFIG_CPU_NUM > 1)
|
||||
uint32_t owner; /* cpu index of owner */
|
||||
#endif
|
||||
cpu_cpsr_t cpsr; /* the interrupt key for this lock */
|
||||
} kspinlock_t;
|
||||
|
||||
/* Be careful nested spin lock is not supported */
|
||||
#if (RHINO_CONFIG_CPU_NUM > 1)
|
||||
/* SMP spin lock */
|
||||
#define krhino_spin_lock(lock) do { \
|
||||
cpu_spin_lock((lock)); \
|
||||
} while (0) \
|
||||
|
||||
#define krhino_spin_unlock(lock) do { \
|
||||
cpu_spin_unlock((lock)); \
|
||||
} while (0)
|
||||
|
||||
#define krhino_spin_lock_irq_save(lock) do { \
|
||||
kspinlock_t *s = (kspinlock_t *)(lock);\
|
||||
s->cpsr = cpu_intrpt_save(); \
|
||||
cpu_spin_lock((lock)); \
|
||||
} while (0)
|
||||
|
||||
#define krhino_spin_unlock_irq_restore(lock) do { \
|
||||
kspinlock_t *s = (kspinlock_t *)(lock);\
|
||||
cpu_spin_unlock((lock)); \
|
||||
cpu_intrpt_restore(s->cpsr); \
|
||||
} while (0)
|
||||
|
||||
#define krhino_spin_lock_init(lock) do { \
|
||||
kspinlock_t *s = (kspinlock_t *)(lock);\
|
||||
s->owner = (uint32_t)-1; \
|
||||
} while(0)
|
||||
#else
|
||||
/* UP spin lock */
|
||||
#define krhino_spin_lock(lock) krhino_sched_disable();
|
||||
#define krhino_spin_unlock(lock) krhino_sched_enable();
|
||||
|
||||
#define krhino_spin_lock_irq_save(lock) do { \
|
||||
kspinlock_t *s = (kspinlock_t *)(lock);\
|
||||
s->cpsr = cpu_intrpt_save(); \
|
||||
} while (0)
|
||||
|
||||
#define krhino_spin_unlock_irq_restore(lock) do { \
|
||||
kspinlock_t *s = (kspinlock_t *)(lock);\
|
||||
cpu_intrpt_restore(s->cpsr); \
|
||||
} while (0)
|
||||
|
||||
#define krhino_spin_lock_init(lock)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
35
Living_SDK/kernel/rhino/core/include/k_stats.h
Normal file
35
Living_SDK/kernel/rhino/core/include/k_stats.h
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef K_STATS_H
|
||||
#define K_STATS_H
|
||||
|
||||
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
|
||||
void kobj_list_init(void);
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_TASK_STACK_OVF_CHECK > 0)
|
||||
/**
|
||||
* This function will check task stack overflow
|
||||
*/
|
||||
void krhino_stack_ovf_check(void);
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_TASK_SCHED_STATS > 0)
|
||||
/**
|
||||
* This function will reset task schedule stats
|
||||
*/
|
||||
void krhino_task_sched_stats_reset(void);
|
||||
/**
|
||||
* This function will get task statistic data
|
||||
*/
|
||||
void krhino_task_sched_stats_get(void);
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_HW_COUNT > 0)
|
||||
void krhino_overhead_measure(void);
|
||||
#endif
|
||||
|
||||
#endif /* K_STATS_H */
|
||||
|
||||
83
Living_SDK/kernel/rhino/core/include/k_sys.h
Executable file
83
Living_SDK/kernel/rhino/core/include/k_sys.h
Executable file
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef K_SYS_H
|
||||
#define K_SYS_H
|
||||
|
||||
#define RHINO_VERSION 12000
|
||||
#define RHINO_IDLE_PRI (RHINO_CONFIG_PRI_MAX - 1)
|
||||
#define RHINO_FALSE 0u
|
||||
#define RHINO_TRUE 1u
|
||||
|
||||
#define RHINO_NO_WAIT 0u
|
||||
#define RHINO_WAIT_FOREVER ((uint64_t)-1)
|
||||
|
||||
#define MAX_TIMER_TICKS ((tick_t)-1 >> 1)
|
||||
|
||||
typedef char name_t;
|
||||
typedef uint8_t suspend_nested_t;
|
||||
typedef uint32_t sem_count_t;
|
||||
typedef uint32_t mutex_nested_t;
|
||||
typedef uint64_t sys_time_t;
|
||||
typedef int64_t sys_time_i_t;
|
||||
typedef uint64_t tick_t;
|
||||
typedef int64_t tick_i_t;
|
||||
typedef uint64_t idle_count_t;
|
||||
typedef uint64_t ctx_switch_t;
|
||||
|
||||
#if (RHINO_CONFIG_INTRPT_STACK_OVF_CHECK > 0)
|
||||
#if (RHINO_CONFIG_CPU_STACK_DOWN > 0)
|
||||
extern cpu_stack_t *g_intrpt_stack_bottom;
|
||||
#else
|
||||
extern cpu_stack_t *g_intrpt_stack_top;
|
||||
#endif
|
||||
#endif /* RHINO_CONFIG_INTRPT_STACK_OVF_CHECK */
|
||||
|
||||
/**
|
||||
* This function will init AliOS
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_init(void);
|
||||
|
||||
/**
|
||||
* This function will start AliOS
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_start(void);
|
||||
|
||||
/**
|
||||
* This function will enter interrupt
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_intrpt_enter(void);
|
||||
|
||||
/**
|
||||
* This function will exit interrupt
|
||||
*/
|
||||
void krhino_intrpt_exit(void);
|
||||
|
||||
/**
|
||||
* This function will check intrpt-stack overflow
|
||||
*/
|
||||
void krhino_intrpt_stack_ovf_check(void);
|
||||
|
||||
/**
|
||||
* This function get the system next sleep ticks
|
||||
*/
|
||||
tick_t krhino_next_sleep_ticks_get(void);
|
||||
|
||||
/**
|
||||
* This function will get the whole ram space used by kernel
|
||||
* @return the whole ram space used by kernel
|
||||
*/
|
||||
size_t krhino_global_space_get(void);
|
||||
|
||||
/**
|
||||
* This function will get kernel version
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
uint32_t krhino_version_get(void);
|
||||
|
||||
#endif /* K_SYS_H */
|
||||
|
||||
324
Living_SDK/kernel/rhino/core/include/k_task.h
Normal file
324
Living_SDK/kernel/rhino/core/include/k_task.h
Normal file
|
|
@ -0,0 +1,324 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef K_TASK_H
|
||||
#define K_TASK_H
|
||||
|
||||
typedef enum
|
||||
{
|
||||
K_SEED,
|
||||
K_RDY,
|
||||
K_PEND,
|
||||
K_SUSPENDED,
|
||||
K_PEND_SUSPENDED,
|
||||
K_SLEEP,
|
||||
K_SLEEP_SUSPENDED,
|
||||
K_DELETED,
|
||||
} task_stat_t;
|
||||
|
||||
|
||||
/* task control information */
|
||||
typedef struct
|
||||
{
|
||||
/* update while task switching
|
||||
access by assemble code, so do not change position */
|
||||
void *task_stack;
|
||||
/* access by activation, so do not change position */
|
||||
const name_t *task_name;
|
||||
#if (RHINO_CONFIG_TASK_INFO > 0)
|
||||
/* access by assemble code, so do not change position */
|
||||
void *user_info[RHINO_CONFIG_TASK_INFO_NUM];
|
||||
#endif
|
||||
|
||||
cpu_stack_t *task_stack_base;
|
||||
uint32_t stack_size;
|
||||
klist_t task_list;
|
||||
|
||||
#if (RHINO_CONFIG_TASK_SUSPEND > 0)
|
||||
suspend_nested_t suspend_count;
|
||||
#endif
|
||||
|
||||
struct mutex_s *mutex_list;
|
||||
|
||||
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
|
||||
klist_t task_stats_item;
|
||||
#endif
|
||||
|
||||
klist_t tick_list;
|
||||
tick_t tick_match;
|
||||
tick_t tick_remain;
|
||||
klist_t *tick_head;
|
||||
|
||||
void *msg;
|
||||
|
||||
#if (RHINO_CONFIG_BUF_QUEUE > 0)
|
||||
size_t bq_msg_size;
|
||||
#endif
|
||||
|
||||
task_stat_t task_state;
|
||||
blk_state_t blk_state;
|
||||
|
||||
/* Task block on mutex, queue, semphore, event */
|
||||
blk_obj_t *blk_obj;
|
||||
|
||||
#if (RHINO_CONFIG_TASK_SEM > 0)
|
||||
struct sem_s *task_sem_obj;
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_TASK_SCHED_STATS > 0)
|
||||
size_t task_free_stack_size;
|
||||
ctx_switch_t task_ctx_switch_times;
|
||||
sys_time_t task_time_total_run;
|
||||
sys_time_t task_time_total_run_prev;
|
||||
lr_timer_t task_exec_time;
|
||||
lr_timer_t task_time_start;
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_DISABLE_INTRPT_STATS > 0)
|
||||
hr_timer_t task_intrpt_disable_time_max;
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_DISABLE_SCHED_STATS > 0)
|
||||
hr_timer_t task_sched_disable_time_max;
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_SCHED_RR > 0)
|
||||
/* for task time slice*/
|
||||
uint32_t time_slice;
|
||||
uint32_t time_total;
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_EVENT_FLAG > 0)
|
||||
uint32_t pend_flags;
|
||||
void *pend_info;
|
||||
uint8_t pend_option;
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_SCHED_RR > 0)
|
||||
uint8_t sched_policy;
|
||||
#endif
|
||||
|
||||
uint8_t cpu_num;
|
||||
|
||||
#if (RHINO_CONFIG_CPU_NUM > 1)
|
||||
uint8_t cpu_binded;
|
||||
uint8_t cur_exc;
|
||||
#endif
|
||||
|
||||
/* current prio */
|
||||
uint8_t prio;
|
||||
/* base prio */
|
||||
uint8_t b_prio;
|
||||
uint8_t mm_alloc_flag;
|
||||
} ktask_t;
|
||||
|
||||
typedef void (*task_entry_t)(void *arg);
|
||||
|
||||
/**
|
||||
* This function will initialize a task
|
||||
* @param[in] task the task to be created
|
||||
* @param[in] name the name of task, which shall be unique
|
||||
* @param[in] arg the parameter of task enter function
|
||||
* @param[in] pri the prio of task
|
||||
* @param[in] ticks the time slice if there are same prio task
|
||||
* @param[in] stack_buf the start address of task stack
|
||||
* @param[in] stack the size of thread stack
|
||||
* @param[in] entry the entry function of task
|
||||
* @param[in] autorun the autorunning flag of task
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_task_create(ktask_t *task, const name_t *name, void *arg,
|
||||
uint8_t prio, tick_t ticks, cpu_stack_t *stack_buf,
|
||||
size_t stack_size, task_entry_t entry,
|
||||
uint8_t autorun);
|
||||
|
||||
#if (RHINO_CONFIG_CPU_NUM > 1)
|
||||
kstat_t krhino_task_cpu_create(ktask_t *task, const name_t *name, void *arg,
|
||||
uint8_t prio, tick_t ticks,
|
||||
cpu_stack_t *stack_buf, size_t stack_size,
|
||||
task_entry_t entry, uint8_t cpu_num,
|
||||
uint8_t autorun);
|
||||
|
||||
kstat_t krhino_task_cpu_bind(ktask_t *task, uint8_t cpu_num);
|
||||
kstat_t krhino_task_cpu_unbind(ktask_t *task);
|
||||
#endif
|
||||
|
||||
|
||||
#if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0)
|
||||
/**
|
||||
* This function will initialize a task
|
||||
* @param[in] task the task to be created
|
||||
* @param[in] name the name of task, which shall be unique
|
||||
* @param[in] arg the parameter of task enter function
|
||||
* @param[in] pri the prio of task
|
||||
* @param[in] ticks the time slice if there are same prio task
|
||||
* @param[in] stack the size of thread stack
|
||||
* @param[in] entry the entry function of task
|
||||
* @param[in] autorun the autorunning flag of task
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_task_dyn_create(ktask_t **task, const name_t *name, void *arg,
|
||||
uint8_t pri, tick_t ticks, size_t stack,
|
||||
task_entry_t entry, uint8_t autorun);
|
||||
|
||||
#if (RHINO_CONFIG_CPU_NUM > 1)
|
||||
kstat_t krhino_task_cpu_dyn_create(ktask_t **task, const name_t *name,
|
||||
void *arg, uint8_t pri, tick_t ticks,
|
||||
size_t stack, task_entry_t entry,
|
||||
uint8_t cpu_num, uint8_t autorun);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_TASK_DEL > 0)
|
||||
/**
|
||||
* This function will delete a task
|
||||
* @param[in] task the task to be deleted.
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_task_del(ktask_t *task);
|
||||
#if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0)
|
||||
/**
|
||||
* This function will delete a dyn-task
|
||||
* @param[in] task the task to be deleted.
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_task_dyn_del(ktask_t *task);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This function will cause a task to sleep for some ticks
|
||||
* @param[in] ticks the ticks to sleep
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
|
||||
kstat_t krhino_task_sleep(tick_t dly);
|
||||
|
||||
/**
|
||||
* This function will yield a task
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_task_yield(void);
|
||||
|
||||
/**
|
||||
* This function will get the current task for this cpu
|
||||
* @return the current task
|
||||
*/
|
||||
ktask_t *krhino_cur_task_get(void);
|
||||
|
||||
#if (RHINO_CONFIG_TASK_SUSPEND > 0)
|
||||
/**
|
||||
* This function will suspend a task
|
||||
* @param[in] task the task to be suspended
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_task_suspend(ktask_t *task);
|
||||
|
||||
/**
|
||||
* This function will resume a task
|
||||
* @param[in] task the task to be resumed
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_task_resume(ktask_t *task);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This function will get min free stack size in the total runtime
|
||||
* @param[in] task the task where get free stack size.
|
||||
* @param[in] free the free task stack size to be filled with.
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_task_stack_min_free(ktask_t *task, size_t *free);
|
||||
|
||||
|
||||
/**
|
||||
* This function will get current free stack size
|
||||
* @param[in] task the task where get free stack size.
|
||||
* @param[in] free the free task stack size to be filled with.
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_task_stack_cur_free(ktask_t *task, size_t *free);
|
||||
|
||||
/**
|
||||
* This function will change the prio of task
|
||||
* @param[in] task the task to be changed prio
|
||||
* @param[in] pri the prio to be changed.
|
||||
* @param[out] old_pri the old task prio to be filled with
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_task_pri_change(ktask_t *task, uint8_t pri, uint8_t *old_pri);
|
||||
|
||||
#if (RHINO_CONFIG_TASK_WAIT_ABORT > 0)
|
||||
/**
|
||||
* This function will abort a task and wakup the task
|
||||
* @param[in] task the task to be aborted
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_task_wait_abort(ktask_t *task);
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_SCHED_RR > 0)
|
||||
/**
|
||||
* This function will set task timeslice
|
||||
* @param[in] task the task to be set timeslice
|
||||
* @param[in] slice the task time slice
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_task_time_slice_set(ktask_t *task, size_t slice);
|
||||
|
||||
/**
|
||||
* This function will set task sched policy
|
||||
* @param[in] task the task to be set timeslice
|
||||
* @param[in] policy the policy to be set, pllicy option can be either
|
||||
* KSCHED_FIFO or KSCHED_RR
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_sched_policy_set(ktask_t *task, uint8_t policy);
|
||||
|
||||
/**
|
||||
* This function will get task sched policy
|
||||
* @param[in] task the task to be get timeslice
|
||||
* @param[out] policy the policy to be get
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_sched_policy_get(ktask_t *task, uint8_t *policy);
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_TASK_INFO > 0)
|
||||
/**
|
||||
* This function will set task private infomation
|
||||
* @param[in] task the task to be set private infomation
|
||||
* @param[out] info the private information
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_task_info_set(ktask_t *task, size_t idx, void *info);
|
||||
|
||||
/**
|
||||
* This function will get task private infomation
|
||||
* @param[in] task the task to be get private infomation
|
||||
* @param[out] info to save private infomation
|
||||
* @return the task private information
|
||||
*/
|
||||
kstat_t krhino_task_info_get(ktask_t *task, size_t idx, void **info);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This function will be set in cpu_task_stack_init,set LR reg with
|
||||
* this funtion pointer
|
||||
*/
|
||||
void krhino_task_deathbed(void);
|
||||
|
||||
/**
|
||||
* This function will find the task by its name
|
||||
*/
|
||||
ktask_t *krhino_task_find(char *name);
|
||||
|
||||
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
|
||||
/**
|
||||
* This function print the overview of tasks
|
||||
*/
|
||||
void krhino_task_overview(int (*print_func)(const char *fmt, ...));
|
||||
#endif
|
||||
|
||||
#endif /* K_TASK_H */
|
||||
57
Living_SDK/kernel/rhino/core/include/k_task_sem.h
Normal file
57
Living_SDK/kernel/rhino/core/include/k_task_sem.h
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef K_TASK_SEM_H
|
||||
#define K_TASK_SEM_H
|
||||
|
||||
/**
|
||||
* This function will create a task-semaphore
|
||||
* @param[in] task pointer to the task
|
||||
* @param[in] sem pointer to the semaphore
|
||||
* @param[in] name name of the task-semaphore
|
||||
* @param[in] count count of the semaphore
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_task_sem_create(ktask_t *task, ksem_t *sem, const name_t *name,
|
||||
size_t count);
|
||||
|
||||
/**
|
||||
* This function will delete a task-semaphore
|
||||
* @param[in] task pointer to the semaphore
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_task_sem_del(ktask_t *task);
|
||||
|
||||
/**
|
||||
* This function will give up a task-semaphore
|
||||
* @param[in] task pointer to the task
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_task_sem_give(ktask_t *task);
|
||||
|
||||
/**
|
||||
* This function will take a task-semaphore
|
||||
* @param[in] ticks ticks to wait before take the semaphore
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_task_sem_take(tick_t ticks);
|
||||
|
||||
/**
|
||||
* This function will set the count of a task-semaphore
|
||||
* @param[in] task pointer to the task
|
||||
* @param[in] count count of the semaphre to set
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_task_sem_count_set(ktask_t *task, sem_count_t count);
|
||||
|
||||
/**
|
||||
* This function will get task-semaphore count
|
||||
* @param[in] task pointer to the semphore
|
||||
* @param[out] count count of the semaphore
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_task_sem_count_get(ktask_t *task, sem_count_t *count);
|
||||
|
||||
#endif /* K_TASK_SEM_H */
|
||||
|
||||
41
Living_SDK/kernel/rhino/core/include/k_time.h
Normal file
41
Living_SDK/kernel/rhino/core/include/k_time.h
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef K_TIME_H
|
||||
#define K_TIME_H
|
||||
|
||||
/**
|
||||
* This function will handle systick routine
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
void krhino_tick_proc(void);
|
||||
|
||||
/**
|
||||
* This function will get time of the system in ms
|
||||
* @return system time
|
||||
*/
|
||||
sys_time_t krhino_sys_time_get(void);
|
||||
|
||||
/**
|
||||
* This function will get ticks of the system
|
||||
* @return the system ticks
|
||||
*/
|
||||
sys_time_t krhino_sys_tick_get(void);
|
||||
|
||||
/**
|
||||
* This function will convert ms to ticks
|
||||
* @param[in] ms ms which will be converted to ticks
|
||||
* @return the ticks of the ms
|
||||
*/
|
||||
tick_t krhino_ms_to_ticks(sys_time_t ms);
|
||||
|
||||
/**
|
||||
* This function will convert ticks to ms
|
||||
* @param[in] ticks ticks which will be converted to ms
|
||||
* @return the ms of the ticks
|
||||
*/
|
||||
sys_time_t krhino_ticks_to_ms(tick_t ticks);
|
||||
|
||||
#endif /* K_TIME_H */
|
||||
|
||||
137
Living_SDK/kernel/rhino/core/include/k_timer.h
Executable file
137
Living_SDK/kernel/rhino/core/include/k_timer.h
Executable file
|
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef K_TIMER_H
|
||||
#define K_TIMER_H
|
||||
|
||||
enum {
|
||||
TIMER_CMD_CB = 0u,
|
||||
TIMER_CMD_START,
|
||||
TIMER_CMD_STOP,
|
||||
TIMER_CMD_CHG,
|
||||
TIMER_ARG_CHG,
|
||||
TIMER_ARG_CHG_AUTO,
|
||||
TIMER_CMD_DEL,
|
||||
TIMER_CMD_DYN_DEL
|
||||
};
|
||||
|
||||
typedef void (*timer_cb_t)(void *timer, void *arg);
|
||||
|
||||
typedef struct {
|
||||
klist_t timer_list;
|
||||
klist_t *to_head;
|
||||
const name_t *name;
|
||||
timer_cb_t cb;
|
||||
void *timer_cb_arg;
|
||||
sys_time_t match;
|
||||
sys_time_t remain;
|
||||
sys_time_t init_count;
|
||||
sys_time_t round_ticks;
|
||||
void *priv;
|
||||
kobj_type_t obj_type;
|
||||
uint8_t timer_state;
|
||||
uint8_t mm_alloc_flag;
|
||||
} ktimer_t;
|
||||
|
||||
typedef struct {
|
||||
ktimer_t *timer;
|
||||
uint8_t cb_num;
|
||||
sys_time_t first;
|
||||
union {
|
||||
sys_time_t round;
|
||||
void *arg;
|
||||
} u;
|
||||
} k_timer_queue_cb;
|
||||
|
||||
typedef enum {
|
||||
TIMER_DEACTIVE = 0u,
|
||||
TIMER_ACTIVE
|
||||
} k_timer_state_t;
|
||||
|
||||
/**
|
||||
* This function will create a timer
|
||||
* @param[in] timer pointer to the timer(the space is provided by user)
|
||||
* @param[in] name name of the timer
|
||||
* @param[in] cb callbak of the timer
|
||||
* @param[in] first ticks of the first timer triger
|
||||
* @param[in] round ticks of the normal timer triger
|
||||
* @param[in] arg the argument of the callback
|
||||
* @param[in] auto_run auto run or not when the timer is created
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_timer_create(ktimer_t *timer, const name_t *name, timer_cb_t cb,
|
||||
sys_time_t first, sys_time_t round, void *arg, uint8_t auto_run);
|
||||
|
||||
/**
|
||||
* This function will delete a timer
|
||||
* @param[in] timer pointer to a timer
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_timer_del(ktimer_t *timer);
|
||||
|
||||
#if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0)
|
||||
/**
|
||||
* This function will create a dyn-timer
|
||||
* @param[in] timer pointer to the timer
|
||||
* @param[in] name name of the timer
|
||||
* @param[in] cb callbak of the timer
|
||||
* @param[in] first ticks of the first timer triger
|
||||
* @param[in] round ticks of the normal timer triger
|
||||
* @param[in] arg the argument of the callback
|
||||
* @param[in] auto_run auto run or not when the timer is created
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_timer_dyn_create(ktimer_t **timer, const name_t *name,
|
||||
timer_cb_t cb,
|
||||
sys_time_t first, sys_time_t round, void *arg, uint8_t auto_run);
|
||||
/**
|
||||
* This function will delete a dyn-timer
|
||||
* @param[in] timer pointer to a timer
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_timer_dyn_del(ktimer_t *timer);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This function will start a timer
|
||||
* @param[in] timer pointer to the timer
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_timer_start(ktimer_t *timer);
|
||||
|
||||
/**
|
||||
* This function will stop a timer
|
||||
* @param[in] timer pointer to the timer
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_timer_stop(ktimer_t *timer);
|
||||
|
||||
/**
|
||||
* This function will change attributes of a timer
|
||||
* @param[in] timer pointer to the timer
|
||||
* @param[in] first ticks of the first timer triger
|
||||
* @param[in] round ticks of the normal timer triger
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_timer_change(ktimer_t *timer, sys_time_t first, sys_time_t round);
|
||||
|
||||
/**
|
||||
* This function will change attributes of a timer without stop and start
|
||||
* @param[in] timer pointer to the timer
|
||||
* @param[in] first ticks of the first timer triger
|
||||
* @param[in] round ticks of the normal timer triger
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_timer_arg_change_auto(ktimer_t *timer, void *arg);
|
||||
|
||||
/**
|
||||
* This function will change callback arg attributes of a timer
|
||||
* @param[in] timer pointer to the timer
|
||||
* @param[in] arg timer callback arg
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_timer_arg_change(ktimer_t *timer, void *arg);
|
||||
|
||||
#endif /* K_TIMER_H */
|
||||
|
||||
207
Living_SDK/kernel/rhino/core/include/k_trace.h
Normal file
207
Living_SDK/kernel/rhino/core/include/k_trace.h
Normal file
|
|
@ -0,0 +1,207 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef K_TRACE_H
|
||||
#define K_TRACE_H
|
||||
|
||||
|
||||
#if (RHINO_CONFIG_TRACE > 0)
|
||||
/* task trace function */
|
||||
void _trace_init(void);
|
||||
void _trace_task_switch(ktask_t *from, ktask_t *to);
|
||||
void _trace_intrpt_task_switch(ktask_t *from, ktask_t *to);
|
||||
void _trace_task_create(ktask_t *task);
|
||||
void _trace_task_sleep(ktask_t *task, tick_t ticks);
|
||||
void _trace_task_pri_change(ktask_t *task, ktask_t *task_pri_chg, uint8_t pri);
|
||||
void _trace_task_suspend(ktask_t *task, ktask_t *task_suspended);
|
||||
void _trace_task_resume(ktask_t *task, ktask_t *task_resumed);
|
||||
void _trace_task_del(ktask_t *task, ktask_t *task_del);
|
||||
void _trace_task_abort(ktask_t *task, ktask_t *task_abort);
|
||||
|
||||
/* semaphore trace function */
|
||||
void _trace_sem_create(ktask_t *task, ksem_t *sem);
|
||||
void _trace_sem_overflow(ktask_t *task, ksem_t *sem);
|
||||
void _trace_sem_del(ktask_t *task, ksem_t *sem);
|
||||
void _trace_sem_get_success(ktask_t *task, ksem_t *sem);
|
||||
void _trace_sem_get_blk(ktask_t *task, ksem_t *sem, tick_t wait_option);
|
||||
void _trace_sem_task_wake(ktask_t *task, ktask_t *task_waked_up, ksem_t *sem,
|
||||
uint8_t opt_wake_all);
|
||||
void _trace_sem_cnt_increase(ktask_t *task, ksem_t *sem);
|
||||
|
||||
/* mutex trace function */
|
||||
void _trace_mutex_create(ktask_t *task, kmutex_t *mutex, const name_t *name);
|
||||
void _trace_mutex_release(ktask_t *task, ktask_t *task_release,
|
||||
uint8_t new_pri);
|
||||
void _trace_mutex_get(ktask_t *task, kmutex_t *mutex, tick_t wait_option);
|
||||
void _trace_task_pri_inv(ktask_t *task, ktask_t *mtxtsk);
|
||||
void _trace_mutex_get_blk(ktask_t *task, kmutex_t *mutex, tick_t wait_option);
|
||||
void _trace_mutex_release_success(ktask_t *task, kmutex_t *mutex);
|
||||
void _trace_mutex_task_wake(ktask_t *task, ktask_t *task_waked_up,
|
||||
kmutex_t *mutex);
|
||||
void _trace_mutex_del(ktask_t *task, kmutex_t *mutex);
|
||||
|
||||
/* event trace function */
|
||||
void _trace_event_create(ktask_t *task, kevent_t *event, const name_t *name,
|
||||
uint32_t flags_init);
|
||||
void _trace_event_get(ktask_t *task, kevent_t *event);
|
||||
void _trace_event_get_blk(ktask_t *task, kevent_t *event, tick_t wait_option);
|
||||
void _trace_event_task_wake(ktask_t *task, ktask_t *task_waked_up,
|
||||
kevent_t *event);
|
||||
void _trace_event_del(ktask_t *task, kevent_t *event);
|
||||
|
||||
/* buf_queue trace function */
|
||||
void _trace_buf_queue_create(ktask_t *task, kbuf_queue_t *buf_queue);
|
||||
void _trace_buf_max(ktask_t *task, kbuf_queue_t *buf_queue, void *p_void,
|
||||
size_t msg_size);
|
||||
void _trace_buf_post(ktask_t *task, kbuf_queue_t *buf_queue, void *p_void,
|
||||
size_t msg_size);
|
||||
void _trace_buf_queue_task_wake(ktask_t *task, ktask_t *task_waked_up,
|
||||
kbuf_queue_t *buf_queue);
|
||||
void _trace_buf_queue_get_blk(ktask_t *task, kbuf_queue_t *buf_queue,
|
||||
tick_t wait_option);
|
||||
|
||||
/* timer trace function */
|
||||
void _trace_timer_create(ktask_t *task, ktimer_t *timer);
|
||||
void _trace_timer_del(ktask_t *task, ktimer_t *timer);
|
||||
|
||||
/* mblk trace function */
|
||||
void _trace_mblk_pool_create(ktask_t *task, mblk_pool_t *pool);
|
||||
|
||||
/* mm trace function */
|
||||
//void _trace_mm_pool_create(ktask_t *task, mm_pool_t *pool);
|
||||
|
||||
/* work queue trace */
|
||||
void _trace_work_init(ktask_t *task, kwork_t *work);
|
||||
void _trace_workqueue_create(ktask_t *task, kworkqueue_t *workqueue);
|
||||
void _trace_workqueue_del(ktask_t *task, kworkqueue_t *workqueue);
|
||||
|
||||
/* task trace */
|
||||
#define TRACE_INIT() _trace_init()
|
||||
#define TRACE_TASK_SWITCH(from, to) _trace_task_switch(from, to)
|
||||
#define TRACE_TASK_CREATE(task) _trace_task_create(task)
|
||||
#define TRACE_TASK_SLEEP(task, ticks) _trace_task_sleep(task, ticks)
|
||||
#define TRACE_INTRPT_TASK_SWITCH(from, to) _trace_intrpt_task_switch(from, to)
|
||||
#define TRACE_TASK_PRI_CHANGE(task, task_pri_chg, pri) _trace_task_pri_change(task, task_pri_chg, pri)
|
||||
#define TRACE_TASK_SUSPEND(task, task_suspended) _trace_task_suspend(task, task_suspended)
|
||||
#define TRACE_TASK_RESUME(task, task_resumed) _trace_task_resume(task, task_resumed)
|
||||
#define TRACE_TASK_DEL(task, task_del) _trace_task_del(task, task_del)
|
||||
#define TRACE_TASK_WAIT_ABORT(task, task_abort) _trace_task_abort(task, task_abort)
|
||||
|
||||
/* semaphore trace */
|
||||
#define TRACE_SEM_CREATE(task, sem) _trace_sem_create(task, sem)
|
||||
#define TRACE_SEM_OVERFLOW(task, sem) _trace_sem_overflow(task, sem)
|
||||
#define TRACE_SEM_CNT_INCREASE(task, sem) _trace_sem_cnt_increase(task, sem)
|
||||
#define TRACE_SEM_GET_SUCCESS(task, sem) _trace_sem_get_success(task, sem)
|
||||
#define TRACE_SEM_GET_BLK(task, sem, wait_option) _trace_sem_get_blk(task, sem, wait_option)
|
||||
#define TRACE_SEM_TASK_WAKE(task, task_waked_up, sem, opt_wake_all) _trace_sem_task_wake(task, task_waked_up, sem, opt_wake_all)
|
||||
#define TRACE_SEM_DEL(task, sem) _trace_sem_del(task, sem);
|
||||
|
||||
/* mutex trace */
|
||||
#define TRACE_MUTEX_CREATE(task, mutex, name) _trace_mutex_create(task, mutex, name)
|
||||
#define TRACE_MUTEX_RELEASE(task, task_release, new_pri) _trace_mutex_release(task, task_release, new_pri)
|
||||
#define TRACE_MUTEX_GET(task, mutex, wait_option) _trace_mutex_get(task, mutex, wait_option)
|
||||
#define TRACE_TASK_PRI_INV(task, mtxtsk) _trace_task_pri_inv(task, mtxtsk)
|
||||
#define TRACE_MUTEX_GET_BLK(task, mutex, wait_option) _trace_mutex_get_blk(task, mutex, wait_option)
|
||||
#define TRACE_MUTEX_RELEASE_SUCCESS(task, mutex) _trace_mutex_release_success(task, mutex)
|
||||
#define TRACE_MUTEX_TASK_WAKE(task, task_waked_up, mutex) _trace_mutex_task_wake(task, task_waked_up, mutex)
|
||||
#define TRACE_MUTEX_DEL(task, mutex) _trace_mutex_del(task, mutex)
|
||||
|
||||
/* event trace */
|
||||
#define TRACE_EVENT_CREATE(task, event, name, flags_init) _trace_event_create(task, event, name, flags_init)
|
||||
#define TRACE_EVENT_GET(task, event) _trace_event_get(task, event)
|
||||
#define TRACE_EVENT_GET_BLK(task, event, wait_option) _trace_event_get_blk(task, event, wait_option)
|
||||
#define TRACE_EVENT_TASK_WAKE(task, task_waked_up, event) _trace_event_task_wake(task, task_waked_up, event)
|
||||
#define TRACE_EVENT_DEL(task, event) _trace_event_del(task, event)
|
||||
|
||||
/* buf_queue trace */
|
||||
#define TRACE_BUF_QUEUE_CREATE(task, buf_queue) _trace_buf_queue_create(task, buf_queue)
|
||||
#define TRACE_BUF_QUEUE_MAX(task, buf_queue, msg, msg_size) _trace_buf_max(task, buf_queue, msg, msg_size)
|
||||
#define TRACE_BUF_QUEUE_POST(task, buf_queue, msg, msg_size) _trace_buf_post(task, buf_queue, msg, msg_size)
|
||||
#define TRACE_BUF_QUEUE_TASK_WAKE(task, task_waked_up, queue) _trace_buf_queue_task_wake(task, task_waked_up, queue)
|
||||
#define TRACE_BUF_QUEUE_GET_BLK(task, buf_queue, wait_option) _trace_buf_queue_get_blk(task, buf_queue, wait_option)
|
||||
|
||||
/* timer trace */
|
||||
#define TRACE_TIMER_CREATE(task, timer) _trace_timer_create(task, timer)
|
||||
#define TRACE_TIMER_DEL(task, timer) _trace_timer_del(task, timer)
|
||||
|
||||
/* mblk trace */
|
||||
#define TRACE_MBLK_POOL_CREATE(task, pool) _trace_mblk_pool_create(task, pool)
|
||||
|
||||
/* mm trace */
|
||||
#define TRACE_MM_POOL_CREATE(task, pool) _trace_mm_pool_create(task, pool)
|
||||
|
||||
/* mm region */
|
||||
#define TRACE_MM_REGION_CREATE(task, regions) _trace_mm_region_create(task, regions)
|
||||
|
||||
/* work queue trace */
|
||||
#define TRACE_WORK_INIT(task, work) _trace_work_init(task, work)
|
||||
#define TRACE_WORKQUEUE_CREATE(task, workqueue) _trace_workqueue_create(task, workqueue)
|
||||
#define TRACE_WORKQUEUE_DEL(task, workqueue) _trace_workqueue_del(task, workqueue)
|
||||
|
||||
#else
|
||||
/* task trace */
|
||||
#define TRACE_INIT()
|
||||
#define TRACE_TASK_SWITCH(from, to)
|
||||
#define TRACE_TASK_CREATE(task)
|
||||
#define TRACE_TASK_SLEEP(task, ticks)
|
||||
#define TRACE_INTRPT_TASK_SWITCH(from, to)
|
||||
#define TRACE_TASK_PRI_CHANGE(task, task_pri_chg, pri)
|
||||
#define TRACE_TASK_SUSPEND(task, task_suspended)
|
||||
#define TRACE_TASK_RESUME(task, task_resumed)
|
||||
#define TRACE_TASK_DEL(task, task_del)
|
||||
#define TRACE_TASK_WAIT_ABORT(task, task_abort)
|
||||
|
||||
/* semaphore trace */
|
||||
#define TRACE_SEM_CREATE(task, sem)
|
||||
#define TRACE_SEM_OVERFLOW(task, sem)
|
||||
#define TRACE_SEM_CNT_INCREASE(task, sem)
|
||||
#define TRACE_SEM_GET_SUCCESS(task, sem)
|
||||
#define TRACE_SEM_GET_BLK(task, sem, wait_option)
|
||||
#define TRACE_SEM_TASK_WAKE(task, task_waked_up, sem, opt_wake_all)
|
||||
#define TRACE_SEM_DEL(task, sem)
|
||||
|
||||
/* mutex trace */
|
||||
#define TRACE_MUTEX_CREATE(task, mutex, name)
|
||||
#define TRACE_MUTEX_RELEASE(task, task_release, new_pri)
|
||||
#define TRACE_MUTEX_GET(task, mutex, wait_option)
|
||||
#define TRACE_TASK_PRI_INV(task, mtxtsk)
|
||||
#define TRACE_MUTEX_GET_BLK(task, mutex, wait_option)
|
||||
#define TRACE_MUTEX_RELEASE_SUCCESS(task, mutex)
|
||||
#define TRACE_MUTEX_TASK_WAKE(task, task_waked_up, mutex)
|
||||
#define TRACE_MUTEX_DEL(task, mutex)
|
||||
|
||||
/* event trace */
|
||||
#define TRACE_EVENT_CREATE(task, event, name, flags_init)
|
||||
#define TRACE_EVENT_GET(task, event)
|
||||
#define TRACE_EVENT_GET_BLK(task, event, wait_option)
|
||||
#define TRACE_EVENT_TASK_WAKE(task, task_waked_up, event)
|
||||
#define TRACE_EVENT_DEL(task, event)
|
||||
|
||||
/* buf_queue trace */
|
||||
#define TRACE_BUF_QUEUE_CREATE(task, buf_queue)
|
||||
#define TRACE_BUF_QUEUE_MAX(task, buf_queue, msg, msg_size)
|
||||
#define TRACE_BUF_QUEUE_POST(task, buf_queue, msg, msg_size)
|
||||
#define TRACE_BUF_QUEUE_TASK_WAKE(task, task_waked_up, queue)
|
||||
#define TRACE_BUF_QUEUE_GET_BLK(task, buf_queue, wait_option)
|
||||
|
||||
/* timer trace */
|
||||
#define TRACE_TIMER_CREATE(task, timer)
|
||||
#define TRACE_TIMER_DEL(task, timer)
|
||||
|
||||
/* MBLK trace */
|
||||
#define TRACE_MBLK_POOL_CREATE(task, pool)
|
||||
|
||||
/* MM trace */
|
||||
#define TRACE_MM_POOL_CREATE(task, pool)
|
||||
|
||||
/* MM region trace*/
|
||||
#define TRACE_MM_REGION_CREATE(task, regions)
|
||||
|
||||
/* work queue trace */
|
||||
#define TRACE_WORK_INIT(task, work)
|
||||
#define TRACE_WORKQUEUE_CREATE(task, workqueue)
|
||||
#define TRACE_WORKQUEUE_DEL(task, workqueue)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
79
Living_SDK/kernel/rhino/core/include/k_workqueue.h
Executable file
79
Living_SDK/kernel/rhino/core/include/k_workqueue.h
Executable file
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef K_WORKQUEUE_H
|
||||
#define K_WORKQUEUE_H
|
||||
|
||||
#if (RHINO_CONFIG_WORKQUEUE > 0)
|
||||
#define WORKQUEUE_WORK_MAX 32
|
||||
|
||||
typedef void (*work_handle_t)(void *arg);
|
||||
|
||||
typedef struct {
|
||||
klist_t work_node;
|
||||
work_handle_t handle;
|
||||
void *arg;
|
||||
tick_t dly;
|
||||
ktimer_t *timer;
|
||||
void *wq;
|
||||
uint8_t work_exit;
|
||||
} kwork_t;
|
||||
|
||||
typedef struct {
|
||||
klist_t workqueue_node;
|
||||
klist_t work_list;
|
||||
kwork_t *work_current; /* current work */
|
||||
const name_t *name;
|
||||
ktask_t worker;
|
||||
ksem_t sem;
|
||||
} kworkqueue_t;
|
||||
|
||||
/**
|
||||
* This function will creat a workqueue
|
||||
* @param[in] workqueue the workqueue to be created
|
||||
* @param[in] name the name of workqueue/worker, which should be unique
|
||||
* @param[in] pri the priority of the worker
|
||||
* @param[in] stack_buf the stack of the worker(task)
|
||||
* @param[in] stack_size the size of the worker-stack
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_workqueue_create(kworkqueue_t *workqueue, const name_t *name,
|
||||
uint8_t pri, cpu_stack_t *stack_buf, size_t stack_size);
|
||||
|
||||
/**
|
||||
* This function will initialize a work
|
||||
* @param[in] work the work to be initialized
|
||||
* @param[in] handle the call back function to run
|
||||
* @param[in] arg the paraments of the function
|
||||
* @param[in] dly the ticks to delay before run
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_work_init(kwork_t *work, work_handle_t handle, void *arg,
|
||||
tick_t dly);
|
||||
|
||||
/**
|
||||
* This function will run a work on a workqueue
|
||||
* @param[in] workqueue the workqueue to run work
|
||||
* @param[in] work the work to run
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_work_run(kworkqueue_t *workqueue, kwork_t *work);
|
||||
|
||||
/**
|
||||
* This function will run a work on the default workqueue
|
||||
* @param[in] work the work to run
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_work_sched(kwork_t *work);
|
||||
|
||||
/**
|
||||
* This function will cancel a work
|
||||
* @param[in] work the work to cancel
|
||||
* @return the operation status, RHINO_SUCCESS is OK, others is error
|
||||
*/
|
||||
kstat_t krhino_work_cancel(kwork_t *work);
|
||||
#endif
|
||||
|
||||
#endif /* K_WORKQUEUE_H */
|
||||
|
||||
403
Living_SDK/kernel/rhino/core/k_buf_queue.c
Executable file
403
Living_SDK/kernel/rhino/core/k_buf_queue.c
Executable file
|
|
@ -0,0 +1,403 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
|
||||
#if (RHINO_CONFIG_BUF_QUEUE > 0)
|
||||
|
||||
static kstat_t buf_queue_create(kbuf_queue_t *queue, const name_t *name,
|
||||
void *buf, size_t size, size_t max_msg, uint8_t mm_alloc_flag, size_t type)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
NULL_PARA_CHK(queue);
|
||||
NULL_PARA_CHK(buf);
|
||||
NULL_PARA_CHK(name);
|
||||
|
||||
if (max_msg == 0u) {
|
||||
return RHINO_INV_PARAM;
|
||||
}
|
||||
|
||||
if (size == 0u) {
|
||||
return RHINO_BUF_QUEUE_SIZE_ZERO;
|
||||
}
|
||||
|
||||
/* init the queue blocked list */
|
||||
klist_init(&queue->blk_obj.blk_list);
|
||||
|
||||
queue->buf = buf;
|
||||
queue->cur_num = 0u;
|
||||
queue->peak_num = 0u;
|
||||
queue->max_msg_size = max_msg;
|
||||
queue->blk_obj.name = name;
|
||||
queue->blk_obj.blk_policy = BLK_POLICY_PRI;
|
||||
queue->mm_alloc_flag = mm_alloc_flag;
|
||||
|
||||
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
|
||||
RHINO_CRITICAL_ENTER();
|
||||
klist_insert(&(g_kobj_list.buf_queue_head), &queue->buf_queue_item);
|
||||
RHINO_CRITICAL_EXIT();
|
||||
#endif
|
||||
|
||||
queue->blk_obj.obj_type = RHINO_BUF_QUEUE_OBJ_TYPE;
|
||||
|
||||
ringbuf_init(&(queue->ringbuf), buf, size, type, max_msg);
|
||||
queue->min_free_buf_size = queue->ringbuf.freesize;
|
||||
TRACE_BUF_QUEUE_CREATE(krhino_cur_task_get(), queue);
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
kstat_t krhino_buf_queue_create(kbuf_queue_t *queue, const name_t *name,
|
||||
void *buf, size_t size, size_t max_msg)
|
||||
{
|
||||
return buf_queue_create(queue, name, buf, size, max_msg, K_OBJ_STATIC_ALLOC, RINGBUF_TYPE_DYN);
|
||||
}
|
||||
|
||||
kstat_t krhino_fix_buf_queue_create(kbuf_queue_t *queue, const name_t *name,
|
||||
void *buf, size_t msg_size, size_t msg_num)
|
||||
{
|
||||
return buf_queue_create(queue, name, buf, msg_size * msg_num, msg_size, K_OBJ_STATIC_ALLOC, RINGBUF_TYPE_FIX);
|
||||
}
|
||||
|
||||
kstat_t krhino_buf_queue_del(kbuf_queue_t *queue)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
klist_t *head;
|
||||
|
||||
NULL_PARA_CHK(queue);
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
|
||||
INTRPT_NESTED_LEVEL_CHK();
|
||||
|
||||
if (queue->blk_obj.obj_type != RHINO_BUF_QUEUE_OBJ_TYPE) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_KOBJ_TYPE_ERR;
|
||||
}
|
||||
|
||||
if (queue->mm_alloc_flag != K_OBJ_STATIC_ALLOC) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_KOBJ_DEL_ERR;
|
||||
}
|
||||
|
||||
head = &queue->blk_obj.blk_list;
|
||||
|
||||
queue->blk_obj.obj_type = RHINO_OBJ_TYPE_NONE;
|
||||
|
||||
/* all task blocked on this queue is waken up */
|
||||
while (!is_klist_empty(head)) {
|
||||
|
||||
pend_task_rm(krhino_list_entry(head->next, ktask_t, task_list));
|
||||
}
|
||||
|
||||
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
|
||||
klist_rm(&queue->buf_queue_item);
|
||||
#endif
|
||||
|
||||
ringbuf_reset(&queue->ringbuf);
|
||||
|
||||
RHINO_CRITICAL_EXIT_SCHED();
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
#if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0)
|
||||
kstat_t krhino_buf_queue_dyn_create(kbuf_queue_t **queue, const name_t *name,
|
||||
size_t size, size_t max_msg)
|
||||
{
|
||||
kstat_t stat;
|
||||
kbuf_queue_t *queue_obj;
|
||||
|
||||
NULL_PARA_CHK(queue);
|
||||
|
||||
if (size == 0u) {
|
||||
return RHINO_BUF_QUEUE_SIZE_ZERO;
|
||||
}
|
||||
|
||||
queue_obj = krhino_mm_alloc(sizeof(kbuf_queue_t));
|
||||
|
||||
if (queue_obj == NULL) {
|
||||
return RHINO_NO_MEM;
|
||||
}
|
||||
|
||||
queue_obj->buf = krhino_mm_alloc(size);
|
||||
|
||||
if (queue_obj->buf == NULL) {
|
||||
krhino_mm_free(queue_obj);
|
||||
return RHINO_NO_MEM;
|
||||
}
|
||||
|
||||
stat = buf_queue_create(queue_obj, name, queue_obj->buf, size, max_msg,
|
||||
K_OBJ_DYN_ALLOC, RINGBUF_TYPE_DYN);
|
||||
|
||||
if (stat != RHINO_SUCCESS) {
|
||||
krhino_mm_free(queue_obj->buf);
|
||||
krhino_mm_free(queue_obj);
|
||||
return stat;
|
||||
}
|
||||
|
||||
*queue = queue_obj;
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
kstat_t krhino_buf_queue_dyn_del(kbuf_queue_t *queue)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
klist_t *head;
|
||||
|
||||
NULL_PARA_CHK(queue);
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
|
||||
INTRPT_NESTED_LEVEL_CHK();
|
||||
|
||||
if (queue->blk_obj.obj_type != RHINO_BUF_QUEUE_OBJ_TYPE) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_KOBJ_TYPE_ERR;
|
||||
}
|
||||
|
||||
if (queue->mm_alloc_flag != K_OBJ_DYN_ALLOC) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_KOBJ_DEL_ERR;
|
||||
}
|
||||
|
||||
head = &queue->blk_obj.blk_list;
|
||||
|
||||
queue->blk_obj.obj_type = RHINO_OBJ_TYPE_NONE;
|
||||
|
||||
while (!is_klist_empty(head)) {
|
||||
pend_task_rm(krhino_list_entry(head->next, ktask_t, task_list));
|
||||
}
|
||||
|
||||
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
|
||||
klist_rm(&queue->buf_queue_item);
|
||||
#endif
|
||||
|
||||
ringbuf_reset(&queue->ringbuf);
|
||||
|
||||
RHINO_CRITICAL_EXIT_SCHED();
|
||||
krhino_mm_free(queue->buf);
|
||||
krhino_mm_free(queue);
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
static kstat_t buf_queue_send(kbuf_queue_t *queue, void *msg, size_t msg_size)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
klist_t *head;
|
||||
ktask_t *task;
|
||||
kstat_t err;
|
||||
|
||||
uint8_t cur_cpu_num;
|
||||
|
||||
/* this is only needed when system zero interrupt feature is enabled */
|
||||
#if (RHINO_CONFIG_INTRPT_GUARD > 0)
|
||||
soc_intrpt_guard();
|
||||
#endif
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
|
||||
if (queue->blk_obj.obj_type != RHINO_BUF_QUEUE_OBJ_TYPE) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_KOBJ_TYPE_ERR;
|
||||
}
|
||||
|
||||
cur_cpu_num = cpu_cur_get();
|
||||
(void)cur_cpu_num;
|
||||
|
||||
if (msg_size > queue->max_msg_size) {
|
||||
TRACE_BUF_QUEUE_MAX(g_active_task[cur_cpu_num], queue, msg, msg_size);
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_BUF_QUEUE_MSG_SIZE_OVERFLOW;
|
||||
}
|
||||
|
||||
if (msg_size == 0) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_INV_PARAM;
|
||||
}
|
||||
|
||||
head = &queue->blk_obj.blk_list;
|
||||
|
||||
/* buf queue is not full here, if there is no blocked receive task */
|
||||
if (is_klist_empty(head)) {
|
||||
|
||||
err = ringbuf_push(&(queue->ringbuf), msg, msg_size);
|
||||
|
||||
if (err != RHINO_SUCCESS) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
if (err == RHINO_RINGBUF_FULL) {
|
||||
err = RHINO_BUF_QUEUE_FULL;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
queue->cur_num++;
|
||||
|
||||
if (queue->peak_num < queue->cur_num) {
|
||||
queue->peak_num = queue->cur_num;
|
||||
}
|
||||
|
||||
if (queue->min_free_buf_size > queue->ringbuf.freesize) {
|
||||
queue->min_free_buf_size = queue->ringbuf.freesize;
|
||||
}
|
||||
|
||||
TRACE_BUF_QUEUE_POST(g_active_task[cur_cpu_num], queue, msg, msg_size);
|
||||
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
task = krhino_list_entry(head->next, ktask_t, task_list);
|
||||
memcpy(task->msg, msg, msg_size);
|
||||
task->bq_msg_size = msg_size;
|
||||
|
||||
pend_task_wakeup(task);
|
||||
|
||||
TRACE_BUF_QUEUE_TASK_WAKE(g_active_task[cur_cpu_num], task, queue);
|
||||
|
||||
RHINO_CRITICAL_EXIT_SCHED();
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
kstat_t krhino_buf_queue_send(kbuf_queue_t *queue, void *msg, size_t size)
|
||||
{
|
||||
NULL_PARA_CHK(queue);
|
||||
NULL_PARA_CHK(msg);
|
||||
|
||||
return buf_queue_send(queue, msg, size);
|
||||
}
|
||||
|
||||
kstat_t krhino_buf_queue_recv(kbuf_queue_t *queue, tick_t ticks, void *msg,
|
||||
size_t *size)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
kstat_t ret;
|
||||
uint8_t cur_cpu_num;
|
||||
|
||||
NULL_PARA_CHK(queue);
|
||||
NULL_PARA_CHK(msg);
|
||||
NULL_PARA_CHK(size);
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
|
||||
cur_cpu_num = cpu_cur_get();
|
||||
|
||||
if ((g_intrpt_nested_level[cur_cpu_num] > 0u) && (ticks != RHINO_NO_WAIT)) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_NOT_CALLED_BY_INTRPT;
|
||||
}
|
||||
|
||||
if (queue->blk_obj.obj_type != RHINO_BUF_QUEUE_OBJ_TYPE) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_KOBJ_TYPE_ERR;
|
||||
}
|
||||
|
||||
if (!ringbuf_is_empty(&(queue->ringbuf))) {
|
||||
ringbuf_pop(&(queue->ringbuf), msg, size);
|
||||
queue->cur_num --;
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
if (ticks == RHINO_NO_WAIT) {
|
||||
*size = 0u;
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_NO_PEND_WAIT;
|
||||
}
|
||||
|
||||
if (g_sched_lock[cur_cpu_num] > 0u) {
|
||||
*size = 0u;
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_SCHED_DISABLE;
|
||||
}
|
||||
|
||||
g_active_task[cur_cpu_num]->msg = msg;
|
||||
pend_to_blk_obj((blk_obj_t *)queue, g_active_task[cur_cpu_num], ticks);
|
||||
|
||||
TRACE_BUF_QUEUE_GET_BLK(g_active_task[cur_cpu_num], queue, ticks);
|
||||
|
||||
RHINO_CRITICAL_EXIT_SCHED();
|
||||
|
||||
RHINO_CPU_INTRPT_DISABLE();
|
||||
|
||||
cur_cpu_num = cpu_cur_get();
|
||||
|
||||
ret = pend_state_end_proc(g_active_task[cur_cpu_num]);
|
||||
|
||||
switch (ret) {
|
||||
case RHINO_SUCCESS:
|
||||
*size = g_active_task[cur_cpu_num]->bq_msg_size;
|
||||
break;
|
||||
|
||||
default:
|
||||
*size = 0u;
|
||||
break;
|
||||
}
|
||||
|
||||
RHINO_CPU_INTRPT_ENABLE();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
kstat_t krhino_buf_queue_flush(kbuf_queue_t *queue)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
NULL_PARA_CHK(queue);
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
|
||||
INTRPT_NESTED_LEVEL_CHK();
|
||||
|
||||
if (queue->blk_obj.obj_type != RHINO_BUF_QUEUE_OBJ_TYPE) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_KOBJ_TYPE_ERR;
|
||||
}
|
||||
|
||||
ringbuf_reset(&(queue->ringbuf));
|
||||
queue->cur_num = 0u;
|
||||
queue->peak_num = 0u;
|
||||
queue->min_free_buf_size = queue->ringbuf.freesize;
|
||||
|
||||
RHINO_CRITICAL_EXIT();
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
kstat_t krhino_buf_queue_info_get(kbuf_queue_t *queue, kbuf_queue_info_t *info)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
NULL_PARA_CHK(queue);
|
||||
NULL_PARA_CHK(info);
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
|
||||
if (queue->blk_obj.obj_type != RHINO_BUF_QUEUE_OBJ_TYPE) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_KOBJ_TYPE_ERR;
|
||||
}
|
||||
|
||||
info->free_buf_size = queue->ringbuf.freesize;
|
||||
info->min_free_buf_size = queue->min_free_buf_size;
|
||||
info->buf_size = queue->ringbuf.end - queue->ringbuf.buf;
|
||||
info->max_msg_size = queue->max_msg_size;
|
||||
info->cur_num = queue->cur_num;
|
||||
info->peak_num = queue->peak_num;
|
||||
|
||||
RHINO_CRITICAL_EXIT();
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
51
Living_SDK/kernel/rhino/core/k_dyn_mem_proc.c
Normal file
51
Living_SDK/kernel/rhino/core/k_dyn_mem_proc.c
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
|
||||
#if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0)
|
||||
void dyn_mem_proc_task(void *arg)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
uint8_t i;
|
||||
kstat_t ret;
|
||||
res_free_t *res_free;
|
||||
res_free_t tmp;
|
||||
|
||||
(void)arg;
|
||||
|
||||
while (1) {
|
||||
ret = krhino_sem_take(&g_res_sem, RHINO_WAIT_FOREVER);
|
||||
if (ret != RHINO_SUCCESS) {
|
||||
k_err_proc(RHINO_DYN_MEM_PROC_ERR);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
RHINO_CRITICAL_ENTER();
|
||||
if (!is_klist_empty(&g_res_list)) {
|
||||
res_free = krhino_list_entry(g_res_list.next, res_free_t, res_list);
|
||||
klist_rm(&res_free->res_list);
|
||||
RHINO_CRITICAL_EXIT();
|
||||
memcpy(&tmp, res_free, sizeof(res_free_t));
|
||||
for (i = 0; i < tmp.cnt; i++) {
|
||||
krhino_mm_free(tmp.res[i]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dyn_mem_proc_task_start(void)
|
||||
{
|
||||
krhino_task_create(&g_dyn_task, "dyn_mem_proc_task", 0, RHINO_CONFIG_K_DYN_MEM_TASK_PRI,
|
||||
0, g_dyn_task_stack, RHINO_CONFIG_K_DYN_TASK_STACK,
|
||||
dyn_mem_proc_task, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
17
Living_SDK/kernel/rhino/core/k_err.c
Normal file
17
Living_SDK/kernel/rhino/core/k_err.c
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
#include <k_dbg_api.h>
|
||||
|
||||
void k_err_proc(kstat_t err)
|
||||
{
|
||||
#if (RHINO_CONFIG_PANIC > 0)
|
||||
debug_fatal_error(err, __FILE__, __LINE__);
|
||||
#endif
|
||||
if (g_err_proc != NULL) {
|
||||
g_err_proc(err);
|
||||
}
|
||||
}
|
||||
|
||||
338
Living_SDK/kernel/rhino/core/k_event.c
Normal file
338
Living_SDK/kernel/rhino/core/k_event.c
Normal file
|
|
@ -0,0 +1,338 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
|
||||
#if (RHINO_CONFIG_EVENT_FLAG > 0)
|
||||
static kstat_t event_create(kevent_t *event, const name_t *name, uint32_t flags,
|
||||
uint8_t mm_alloc_flag)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
NULL_PARA_CHK(event);
|
||||
NULL_PARA_CHK(name);
|
||||
|
||||
/* init the list */
|
||||
klist_init(&event->blk_obj.blk_list);
|
||||
event->blk_obj.blk_policy = BLK_POLICY_PRI;
|
||||
event->blk_obj.name = name;
|
||||
event->flags = flags;
|
||||
event->mm_alloc_flag = mm_alloc_flag;
|
||||
|
||||
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
|
||||
RHINO_CRITICAL_ENTER();
|
||||
klist_insert(&(g_kobj_list.event_head), &event->event_item);
|
||||
RHINO_CRITICAL_EXIT();
|
||||
#endif
|
||||
|
||||
TRACE_EVENT_CREATE(krhino_cur_task_get(), event, name, flags);
|
||||
|
||||
event->blk_obj.obj_type = RHINO_EVENT_OBJ_TYPE;
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
kstat_t krhino_event_create(kevent_t *event, const name_t *name, uint32_t flags)
|
||||
{
|
||||
return event_create(event, name, flags, K_OBJ_STATIC_ALLOC);
|
||||
}
|
||||
|
||||
kstat_t krhino_event_del(kevent_t *event)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
klist_t *blk_list_head;
|
||||
|
||||
NULL_PARA_CHK(event);
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
|
||||
INTRPT_NESTED_LEVEL_CHK();
|
||||
|
||||
if (event->blk_obj.obj_type != RHINO_EVENT_OBJ_TYPE) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_KOBJ_TYPE_ERR;
|
||||
}
|
||||
|
||||
if (event->mm_alloc_flag != K_OBJ_STATIC_ALLOC) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_KOBJ_DEL_ERR;
|
||||
}
|
||||
|
||||
blk_list_head = &event->blk_obj.blk_list;
|
||||
|
||||
event->blk_obj.obj_type = RHINO_OBJ_TYPE_NONE;
|
||||
|
||||
while (!is_klist_empty(blk_list_head)) {
|
||||
pend_task_rm(krhino_list_entry(blk_list_head->next, ktask_t, task_list));
|
||||
}
|
||||
|
||||
event->flags = 0u;
|
||||
|
||||
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
|
||||
klist_rm(&event->event_item);
|
||||
#endif
|
||||
|
||||
TRACE_EVENT_DEL(g_active_task[cpu_cur_get()], event);
|
||||
|
||||
RHINO_CRITICAL_EXIT_SCHED();
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
#if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0)
|
||||
kstat_t krhino_event_dyn_create(kevent_t **event, const name_t *name,
|
||||
uint32_t flags)
|
||||
{
|
||||
kstat_t stat;
|
||||
kevent_t *event_obj;
|
||||
|
||||
if (event == NULL) {
|
||||
return RHINO_NULL_PTR;
|
||||
}
|
||||
|
||||
event_obj = krhino_mm_alloc(sizeof(kevent_t));
|
||||
|
||||
if (event_obj == NULL) {
|
||||
return RHINO_NO_MEM;
|
||||
}
|
||||
|
||||
stat = event_create(event_obj, name, flags, K_OBJ_DYN_ALLOC);
|
||||
|
||||
if (stat != RHINO_SUCCESS) {
|
||||
krhino_mm_free(event_obj);
|
||||
return stat;
|
||||
}
|
||||
|
||||
*event = event_obj;
|
||||
|
||||
return stat;
|
||||
}
|
||||
|
||||
kstat_t krhino_event_dyn_del(kevent_t *event)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
klist_t *blk_list_head;
|
||||
|
||||
NULL_PARA_CHK(event);
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
|
||||
INTRPT_NESTED_LEVEL_CHK();
|
||||
|
||||
if (event->blk_obj.obj_type != RHINO_EVENT_OBJ_TYPE) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_KOBJ_TYPE_ERR;
|
||||
}
|
||||
|
||||
if (event->mm_alloc_flag != K_OBJ_DYN_ALLOC) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_KOBJ_DEL_ERR;
|
||||
}
|
||||
|
||||
blk_list_head = &event->blk_obj.blk_list;
|
||||
|
||||
event->blk_obj.obj_type = RHINO_OBJ_TYPE_NONE;
|
||||
|
||||
while (!is_klist_empty(blk_list_head)) {
|
||||
pend_task_rm(krhino_list_entry(blk_list_head->next, ktask_t, task_list));
|
||||
}
|
||||
|
||||
event->flags = 0u;
|
||||
|
||||
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
|
||||
klist_rm(&event->event_item);
|
||||
#endif
|
||||
|
||||
RHINO_CRITICAL_EXIT_SCHED();
|
||||
|
||||
krhino_mm_free(event);
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
kstat_t krhino_event_get(kevent_t *event, uint32_t flags, uint8_t opt,
|
||||
uint32_t *actl_flags, tick_t ticks)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
kstat_t stat;
|
||||
uint8_t status;
|
||||
uint8_t cur_cpu_num;
|
||||
|
||||
NULL_PARA_CHK(event);
|
||||
NULL_PARA_CHK(actl_flags);
|
||||
|
||||
if ((opt != RHINO_AND) && (opt != RHINO_OR) && (opt != RHINO_AND_CLEAR) &&
|
||||
(opt != RHINO_OR_CLEAR)) {
|
||||
return RHINO_NO_THIS_EVENT_OPT;
|
||||
}
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
|
||||
INTRPT_NESTED_LEVEL_CHK();
|
||||
|
||||
if (event->blk_obj.obj_type != RHINO_EVENT_OBJ_TYPE) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_KOBJ_TYPE_ERR;
|
||||
}
|
||||
|
||||
cur_cpu_num = cpu_cur_get();
|
||||
|
||||
/* if option is AND MASK or OR MASK */
|
||||
if (opt & RHINO_FLAGS_AND_MASK) {
|
||||
if ((event->flags & flags) == flags) {
|
||||
status = RHINO_TRUE;
|
||||
} else {
|
||||
status = RHINO_FALSE;
|
||||
}
|
||||
} else {
|
||||
if ((event->flags & flags) > 0u) {
|
||||
status = RHINO_TRUE;
|
||||
} else {
|
||||
status = RHINO_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (status == RHINO_TRUE) {
|
||||
*actl_flags = event->flags;
|
||||
|
||||
if (opt & RHINO_FLAGS_CLEAR_MASK) {
|
||||
event->flags &= ~flags;
|
||||
}
|
||||
|
||||
TRACE_EVENT_GET(g_active_task[cur_cpu_num], event);
|
||||
RHINO_CRITICAL_EXIT();
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
/* can't get event, and return immediately if wait_option is RHINO_NO_WAIT */
|
||||
if (ticks == RHINO_NO_WAIT) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_NO_PEND_WAIT;
|
||||
}
|
||||
|
||||
/* system is locked so task can not be blocked just return immediately */
|
||||
if (g_sched_lock[cur_cpu_num] > 0u) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_SCHED_DISABLE;
|
||||
}
|
||||
|
||||
/* remember the passed information */
|
||||
g_active_task[cur_cpu_num]->pend_option = opt;
|
||||
g_active_task[cur_cpu_num]->pend_flags = flags;
|
||||
g_active_task[cur_cpu_num]->pend_info = actl_flags;
|
||||
|
||||
pend_to_blk_obj((blk_obj_t *)event, g_active_task[cur_cpu_num], ticks);
|
||||
|
||||
TRACE_EVENT_GET_BLK(g_active_task[cur_cpu_num], event, ticks);
|
||||
|
||||
RHINO_CRITICAL_EXIT_SCHED();
|
||||
|
||||
RHINO_CPU_INTRPT_DISABLE();
|
||||
|
||||
/* so the task is waked up, need know which reason cause wake up */
|
||||
stat = pend_state_end_proc(g_active_task[cpu_cur_get()]);
|
||||
|
||||
RHINO_CPU_INTRPT_ENABLE();
|
||||
|
||||
return stat;
|
||||
}
|
||||
|
||||
static kstat_t event_set(kevent_t *event, uint32_t flags, uint8_t opt)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
klist_t *iter;
|
||||
klist_t *event_head;
|
||||
klist_t *iter_temp;
|
||||
ktask_t *task;
|
||||
uint8_t status;
|
||||
uint32_t cur_event_flags;
|
||||
|
||||
/* this is only needed when system zero interrupt feature is enabled */
|
||||
#if (RHINO_CONFIG_INTRPT_GUARD > 0)
|
||||
soc_intrpt_guard();
|
||||
#endif
|
||||
|
||||
status = RHINO_FALSE;
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
|
||||
if (event->blk_obj.obj_type != RHINO_EVENT_OBJ_TYPE) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_KOBJ_TYPE_ERR;
|
||||
}
|
||||
|
||||
event_head = &event->blk_obj.blk_list;
|
||||
|
||||
/* if the set_option is AND_MASK, it just clears the flags and will return immediately */
|
||||
if (opt & RHINO_FLAGS_AND_MASK) {
|
||||
event->flags &= flags;
|
||||
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_SUCCESS;
|
||||
} else {
|
||||
event->flags |= flags;
|
||||
}
|
||||
|
||||
cur_event_flags = event->flags;
|
||||
iter = event_head->next;
|
||||
|
||||
/* if list is not empty */
|
||||
while (iter != event_head) {
|
||||
task = krhino_list_entry(iter, ktask_t, task_list);
|
||||
iter_temp = iter->next;
|
||||
|
||||
if (task->pend_option & RHINO_FLAGS_AND_MASK) {
|
||||
if ((cur_event_flags & task->pend_flags) == task->pend_flags) {
|
||||
status = RHINO_TRUE;
|
||||
} else {
|
||||
status = RHINO_FALSE;
|
||||
}
|
||||
} else {
|
||||
if (cur_event_flags & task->pend_flags) {
|
||||
status = RHINO_TRUE;
|
||||
} else {
|
||||
status = RHINO_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (status == RHINO_TRUE) {
|
||||
(*(uint32_t *)(task->pend_info)) = cur_event_flags;
|
||||
|
||||
/* the task condition is met, just wake this task */
|
||||
pend_task_wakeup(task);
|
||||
|
||||
TRACE_EVENT_TASK_WAKE(g_active_task[cpu_cur_get()], task, event);
|
||||
|
||||
/* does it need to clear the flags */
|
||||
if (task->pend_option & RHINO_FLAGS_CLEAR_MASK) {
|
||||
event->flags &= ~(task->pend_flags);
|
||||
}
|
||||
}
|
||||
|
||||
iter = iter_temp;
|
||||
}
|
||||
|
||||
RHINO_CRITICAL_EXIT_SCHED();
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
kstat_t krhino_event_set(kevent_t *event, uint32_t flags, uint8_t opt)
|
||||
{
|
||||
NULL_PARA_CHK(event);
|
||||
|
||||
if ((opt != RHINO_AND) && (opt != RHINO_OR)) {
|
||||
return RHINO_NO_THIS_EVENT_OPT;
|
||||
}
|
||||
|
||||
return event_set(event, flags, opt);
|
||||
}
|
||||
#endif /* RHINO_CONFIG_EVENT_FLAG */
|
||||
|
||||
62
Living_SDK/kernel/rhino/core/k_idle.c
Executable file
62
Living_SDK/kernel/rhino/core/k_idle.c
Executable file
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
|
||||
#if (RHINO_CONFIG_CPU_USAGE_STATS > 0)
|
||||
void idle_count_set(idle_count_t value)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
RHINO_CPU_INTRPT_DISABLE();
|
||||
|
||||
g_idle_count[cpu_cur_get()] = value;
|
||||
|
||||
RHINO_CPU_INTRPT_ENABLE();
|
||||
}
|
||||
|
||||
idle_count_t idle_count_get(void)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
idle_count_t idle_count;
|
||||
|
||||
RHINO_CPU_INTRPT_DISABLE();
|
||||
|
||||
idle_count = g_idle_count[cpu_cur_get()];
|
||||
|
||||
RHINO_CPU_INTRPT_ENABLE();
|
||||
|
||||
return idle_count;
|
||||
}
|
||||
#endif
|
||||
|
||||
void idle_task(void *arg)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
/* avoid warning */
|
||||
(void)arg;
|
||||
|
||||
#if (RHINO_CONFIG_USER_HOOK > 0)
|
||||
krhino_idle_pre_hook();
|
||||
#endif
|
||||
|
||||
while (RHINO_TRUE) {
|
||||
RHINO_CPU_INTRPT_DISABLE();
|
||||
|
||||
g_idle_count[cpu_cur_get()]++;
|
||||
|
||||
RHINO_CPU_INTRPT_ENABLE();
|
||||
|
||||
#if (RHINO_CONFIG_USER_HOOK > 0)
|
||||
krhino_idle_hook();
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_CPU_PWR_MGMT > 0)
|
||||
cpu_pwr_down();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
890
Living_SDK/kernel/rhino/core/k_mm.c
Normal file
890
Living_SDK/kernel/rhino/core/k_mm.c
Normal file
|
|
@ -0,0 +1,890 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if (RHINO_CONFIG_MM_TLF > 0)
|
||||
extern k_mm_region_t g_mm_region[];
|
||||
extern int g_region_num;
|
||||
extern void aos_mm_leak_region_init(void);
|
||||
|
||||
void k_mm_init(void)
|
||||
{
|
||||
uint32_t e = 0;
|
||||
|
||||
/* init memory region */
|
||||
krhino_init_mm_head(&g_kmm_head, g_mm_region[0].start, g_mm_region[0].len);
|
||||
for (e = 1; e < g_region_num; e++) {
|
||||
krhino_add_mm_region(g_kmm_head, g_mm_region[e].start,
|
||||
g_mm_region[e].len);
|
||||
}
|
||||
|
||||
#if (RHINO_CONFIG_MM_LEAKCHECK > 0)
|
||||
aos_mm_leak_region_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* init a region, contain 3 mmblk
|
||||
-------------------------------------------------------------------
|
||||
| k_mm_list_t | k_mm_region_info_t | k_mm_list_t | free space |k_mm_list_t|
|
||||
-------------------------------------------------------------------
|
||||
|
||||
"regionaddr" and "len" is aligned by caller */
|
||||
RHINO_INLINE k_mm_list_t *init_mm_region(void *regionaddr, size_t len)
|
||||
{
|
||||
k_mm_list_t * midblk, *lastblk, *firstblk;
|
||||
k_mm_region_info_t *region;
|
||||
|
||||
/* "regionaddr" and "len" is aligned by caller */
|
||||
|
||||
/*first mmblk for region info*/
|
||||
firstblk = (k_mm_list_t *)regionaddr;
|
||||
firstblk->prev = NULL;
|
||||
firstblk->buf_size = MM_ALIGN_UP(sizeof(k_mm_region_info_t)) |
|
||||
RHINO_MM_ALLOCED | RHINO_MM_PREVALLOCED;
|
||||
#if (RHINO_CONFIG_MM_DEBUG > 0u)
|
||||
firstblk->dye = RHINO_MM_CORRUPT_DYE;
|
||||
firstblk->owner = 0;
|
||||
#endif
|
||||
|
||||
/*last mmblk for stop merge */
|
||||
lastblk = (k_mm_list_t *)((char *)regionaddr + len - MMLIST_HEAD_SIZE);
|
||||
|
||||
/*middle mmblk for heap use */
|
||||
midblk = MM_GET_NEXT_BLK(firstblk);
|
||||
midblk->buf_size = ((char *)lastblk - (char *)midblk->mbinfo.buffer) |
|
||||
RHINO_MM_ALLOCED | RHINO_MM_PREVALLOCED;
|
||||
midblk->mbinfo.free_ptr.prev = midblk->mbinfo.free_ptr.next = 0;
|
||||
|
||||
/*last mmblk for stop merge */
|
||||
lastblk->prev = midblk;
|
||||
/* set alloced, can't be merged */
|
||||
lastblk->buf_size = 0 | RHINO_MM_ALLOCED | RHINO_MM_PREVFREE;
|
||||
#if (RHINO_CONFIG_MM_DEBUG > 0u)
|
||||
lastblk->dye = RHINO_MM_CORRUPT_DYE;
|
||||
lastblk->owner = 0;
|
||||
#endif
|
||||
|
||||
region = (k_mm_region_info_t *)firstblk->mbinfo.buffer;
|
||||
region->next = 0;
|
||||
region->end = lastblk;
|
||||
|
||||
return firstblk;
|
||||
}
|
||||
|
||||
/* 2^(N + MM_MIN_BIT) <= size < 2^(1 + N + MM_MIN_BIT) */
|
||||
static int32_t size_to_level(size_t size)
|
||||
{
|
||||
size_t cnt;
|
||||
cnt = 32 - krhino_clz32(size);
|
||||
if (cnt < MM_MIN_BIT) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (cnt > MM_MAX_BIT) {
|
||||
return -1;
|
||||
}
|
||||
return cnt - MM_MIN_BIT;
|
||||
}
|
||||
|
||||
#if (K_MM_STATISTIC > 0)
|
||||
static void addsize(k_mm_head *mmhead, size_t size, size_t req_size)
|
||||
{
|
||||
int32_t level;
|
||||
|
||||
if (mmhead->free_size > size) {
|
||||
mmhead->free_size -= size;
|
||||
} else {
|
||||
mmhead->free_size = 0;
|
||||
}
|
||||
|
||||
mmhead->used_size += size;
|
||||
if (mmhead->used_size > mmhead->maxused_size) {
|
||||
mmhead->maxused_size = mmhead->used_size;
|
||||
}
|
||||
|
||||
if (req_size > 0) {
|
||||
level = size_to_level(req_size);
|
||||
if (level != -1) {
|
||||
mmhead->alloc_times[level]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void removesize(k_mm_head *mmhead, size_t size)
|
||||
{
|
||||
if (mmhead->used_size > size) {
|
||||
mmhead->used_size -= size;
|
||||
} else {
|
||||
mmhead->used_size = 0;
|
||||
}
|
||||
mmhead->free_size += size;
|
||||
}
|
||||
|
||||
/* used_size++, free_size--, maybe maxused_size++ */
|
||||
#define stats_addsize(mmhead, size, req_size) addsize(mmhead, size, req_size)
|
||||
/* used_size--, free_size++ */
|
||||
#define stats_removesize(mmhead, size) removesize(mmhead, size)
|
||||
#else
|
||||
#define stats_addsize(mmhead, size, req_size) \
|
||||
do { \
|
||||
} while (0)
|
||||
#define stats_removesize(mmhead, size) \
|
||||
do { \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
kstat_t krhino_init_mm_head(k_mm_head **ppmmhead, void *addr, size_t len)
|
||||
{
|
||||
k_mm_list_t *nextblk;
|
||||
k_mm_list_t *firstblk;
|
||||
k_mm_head * pmmhead;
|
||||
void * orig_addr;
|
||||
#if (RHINO_CONFIG_MM_BLK > 0)
|
||||
mblk_pool_t *mmblk_pool;
|
||||
kstat_t stat;
|
||||
#endif
|
||||
|
||||
NULL_PARA_CHK(ppmmhead);
|
||||
NULL_PARA_CHK(addr);
|
||||
|
||||
/*check paramters, addr and len need algin
|
||||
1. the length at least need RHINO_CONFIG_MM_TLF_BLK_SIZE for fixed size
|
||||
memory block
|
||||
2. and also ast least have 1k for user alloced
|
||||
*/
|
||||
orig_addr = addr;
|
||||
addr = (void *)MM_ALIGN_UP((size_t)addr);
|
||||
len -= (size_t)addr - (size_t)orig_addr;
|
||||
len = MM_ALIGN_DOWN(len);
|
||||
|
||||
if (len == 0 || len < MIN_FREE_MEMORY_SIZE + RHINO_CONFIG_MM_TLF_BLK_SIZE ||
|
||||
len > MM_MAX_SIZE) {
|
||||
return RHINO_MM_POOL_SIZE_ERR;
|
||||
}
|
||||
|
||||
pmmhead = (k_mm_head *)addr;
|
||||
|
||||
/* Zeroing the memory head */
|
||||
memset(pmmhead, 0, sizeof(k_mm_head));
|
||||
#if (RHINO_CONFIG_MM_REGION_MUTEX > 0)
|
||||
krhino_mutex_create(&pmmhead->mm_mutex, "mm_mutex");
|
||||
#else
|
||||
krhino_spin_lock_init(&pmmhead->mm_lock);
|
||||
#endif
|
||||
|
||||
firstblk =
|
||||
init_mm_region((void *)((size_t)addr + MM_ALIGN_UP(sizeof(k_mm_head))),
|
||||
MM_ALIGN_DOWN(len - sizeof(k_mm_head)));
|
||||
|
||||
|
||||
pmmhead->regioninfo = (k_mm_region_info_t *)firstblk->mbinfo.buffer;
|
||||
|
||||
nextblk = MM_GET_NEXT_BLK(firstblk);
|
||||
|
||||
*ppmmhead = pmmhead;
|
||||
|
||||
/*mark it as free and set it to bitmap*/
|
||||
#if (RHINO_CONFIG_MM_DEBUG > 0u)
|
||||
nextblk->dye = RHINO_MM_CORRUPT_DYE;
|
||||
nextblk->owner = 0;
|
||||
#endif
|
||||
|
||||
/* release free blk */
|
||||
k_mm_free(pmmhead, nextblk->mbinfo.buffer);
|
||||
|
||||
/*after free, we need acess mmhead and nextblk again*/
|
||||
|
||||
#if (K_MM_STATISTIC > 0)
|
||||
pmmhead->free_size = MM_GET_BUF_SIZE(nextblk);
|
||||
pmmhead->used_size = len - MM_GET_BUF_SIZE(nextblk);
|
||||
pmmhead->maxused_size = pmmhead->used_size;
|
||||
#endif
|
||||
/* default no fixblk */
|
||||
pmmhead->fix_pool = NULL;
|
||||
|
||||
#if (RHINO_CONFIG_MM_BLK > 0)
|
||||
/* note: stats_addsize inside */
|
||||
mmblk_pool = k_mm_alloc(pmmhead, RHINO_CONFIG_MM_TLF_BLK_SIZE +
|
||||
MM_ALIGN_UP(sizeof(mblk_pool_t)));
|
||||
if (mmblk_pool) {
|
||||
stat = krhino_mblk_pool_init(
|
||||
mmblk_pool, "fixed_mm_blk",
|
||||
(void *)((size_t)mmblk_pool + MM_ALIGN_UP(sizeof(mblk_pool_t))),
|
||||
RHINO_CONFIG_MM_BLK_SIZE, RHINO_CONFIG_MM_TLF_BLK_SIZE);
|
||||
if (stat == RHINO_SUCCESS) {
|
||||
pmmhead->fix_pool = mmblk_pool;
|
||||
#if (K_MM_STATISTIC > 0)
|
||||
stats_removesize(pmmhead, RHINO_CONFIG_MM_TLF_BLK_SIZE);
|
||||
#endif
|
||||
} else {
|
||||
/* note: stats_removesize inside */
|
||||
k_mm_free(pmmhead, mmblk_pool);
|
||||
}
|
||||
#if (K_MM_STATISTIC > 0)
|
||||
pmmhead->maxused_size = pmmhead->used_size;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
void show_mm()
|
||||
{
|
||||
#if (K_MM_STATISTIC > 0)
|
||||
printf("[HEAP]| TotalSize | FreeSize | UsedSize | MinFreeSz |\r\n");
|
||||
printf(" | %10d | %10d | %10d | %10d |\r\n",
|
||||
g_kmm_head->free_size + g_kmm_head->used_size, g_kmm_head->free_size,
|
||||
g_kmm_head->used_size,
|
||||
g_kmm_head->free_size + g_kmm_head->used_size -
|
||||
g_kmm_head->maxused_size);
|
||||
#else
|
||||
printf("K_MM_STATISTIC is cloesd\r\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
kstat_t krhino_deinit_mm_head(k_mm_head *mmhead)
|
||||
{
|
||||
#if (RHINO_CONFIG_MM_REGION_MUTEX > 0)
|
||||
krhino_mutex_del(&mmhead->mm_mutex);
|
||||
#endif
|
||||
|
||||
memset(mmhead, 0, sizeof(k_mm_head));
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
kstat_t krhino_add_mm_region(k_mm_head *mmhead, void *addr, size_t len)
|
||||
{
|
||||
void * orig_addr;
|
||||
k_mm_region_info_t *region;
|
||||
k_mm_list_t * firstblk, *nextblk;
|
||||
|
||||
NULL_PARA_CHK(mmhead);
|
||||
NULL_PARA_CHK(addr);
|
||||
|
||||
orig_addr = addr;
|
||||
addr = (void *)MM_ALIGN_UP((size_t)addr);
|
||||
len -= (size_t)addr - (size_t)orig_addr;
|
||||
len = MM_ALIGN_DOWN(len);
|
||||
|
||||
if (!len ||
|
||||
len < sizeof(k_mm_region_info_t) + MMLIST_HEAD_SIZE * 3 + MM_MIN_SIZE) {
|
||||
return RHINO_MM_POOL_SIZE_ERR;
|
||||
}
|
||||
|
||||
memset(addr, 0, len);
|
||||
|
||||
MM_CRITICAL_ENTER(mmhead);
|
||||
|
||||
firstblk = init_mm_region(addr, len);
|
||||
nextblk = MM_GET_NEXT_BLK(firstblk);
|
||||
|
||||
/* Inserting the area in the list of linked areas */
|
||||
region = (k_mm_region_info_t *)firstblk->mbinfo.buffer;
|
||||
region->next = mmhead->regioninfo;
|
||||
mmhead->regioninfo = region;
|
||||
|
||||
#if (RHINO_CONFIG_MM_DEBUG > 0u)
|
||||
nextblk->dye = RHINO_MM_CORRUPT_DYE;
|
||||
nextblk->owner = 0;
|
||||
#endif
|
||||
|
||||
#if (K_MM_STATISTIC > 0)
|
||||
/* keep "used_size" not changed.
|
||||
change "used_size" here then k_mm_free will decrease it. */
|
||||
mmhead->used_size += MM_GET_BLK_SIZE(nextblk);
|
||||
#endif
|
||||
|
||||
MM_CRITICAL_EXIT(mmhead);
|
||||
|
||||
/*mark nextblk as free*/
|
||||
k_mm_free(mmhead, nextblk->mbinfo.buffer);
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
#if (RHINO_CONFIG_MM_BLK > 0)
|
||||
static void *k_mm_smallblk_alloc(k_mm_head *mmhead, size_t size)
|
||||
{
|
||||
kstat_t sta;
|
||||
void * tmp;
|
||||
|
||||
if (!mmhead) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sta = krhino_mblk_alloc((mblk_pool_t *)mmhead->fix_pool, &tmp);
|
||||
if (sta != RHINO_SUCCESS) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
stats_addsize(mmhead, RHINO_CONFIG_MM_BLK_SIZE, 0);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
static void k_mm_smallblk_free(k_mm_head *mmhead, void *ptr)
|
||||
{
|
||||
kstat_t sta;
|
||||
|
||||
if (!mmhead || !ptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
sta = krhino_mblk_free((mblk_pool_t *)mmhead->fix_pool, ptr);
|
||||
if (sta != RHINO_SUCCESS) {
|
||||
k_err_proc(RHINO_SYS_FATAL_ERR);
|
||||
}
|
||||
|
||||
stats_removesize(mmhead, RHINO_CONFIG_MM_BLK_SIZE);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* insert blk to freelist[level], and set freebitmap */
|
||||
static void k_mm_freelist_insert(k_mm_head *mmhead, k_mm_list_t *blk)
|
||||
{
|
||||
int32_t level;
|
||||
|
||||
level = size_to_level(MM_GET_BUF_SIZE(blk));
|
||||
if (level < 0 || level >= MM_BIT_LEVEL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* free list is LIFO */
|
||||
|
||||
blk->mbinfo.free_ptr.prev = NULL;
|
||||
blk->mbinfo.free_ptr.next = mmhead->freelist[level];
|
||||
|
||||
if (mmhead->freelist[level] != NULL) {
|
||||
mmhead->freelist[level]->mbinfo.free_ptr.prev = blk;
|
||||
}
|
||||
|
||||
mmhead->freelist[level] = blk;
|
||||
|
||||
/* freelist not null, so set the bit */
|
||||
mmhead->free_bitmap |= (1 << level);
|
||||
}
|
||||
|
||||
/* get blk from freelist[level], and clear freebitmap if needed */
|
||||
static void k_mm_freelist_delete(k_mm_head *mmhead, k_mm_list_t *blk)
|
||||
{
|
||||
int32_t level;
|
||||
|
||||
level = size_to_level(MM_GET_BUF_SIZE(blk));
|
||||
if (level < 0 || level >= MM_BIT_LEVEL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (blk->mbinfo.free_ptr.next != NULL) {
|
||||
blk->mbinfo.free_ptr.next->mbinfo.free_ptr.prev =
|
||||
blk->mbinfo.free_ptr.prev;
|
||||
}
|
||||
if (blk->mbinfo.free_ptr.prev != NULL) {
|
||||
blk->mbinfo.free_ptr.prev->mbinfo.free_ptr.next =
|
||||
blk->mbinfo.free_ptr.next;
|
||||
}
|
||||
|
||||
if (mmhead->freelist[level] == blk) {
|
||||
/* first blk in this freelist */
|
||||
mmhead->freelist[level] = blk->mbinfo.free_ptr.next;
|
||||
if (mmhead->freelist[level] == NULL) {
|
||||
/* freelist null, so clear the bit */
|
||||
mmhead->free_bitmap &= (~(1 << level));
|
||||
}
|
||||
}
|
||||
|
||||
blk->mbinfo.free_ptr.prev = NULL;
|
||||
blk->mbinfo.free_ptr.next = NULL;
|
||||
}
|
||||
|
||||
/* find a freelist at higher level */
|
||||
static k_mm_list_t *find_up_level(k_mm_head *mmhead, int32_t level)
|
||||
{
|
||||
uint32_t bitmap;
|
||||
|
||||
bitmap = mmhead->free_bitmap & (0xfffffffful << (level + 1));
|
||||
level = krhino_ctz32(bitmap);
|
||||
|
||||
if (level < MM_BIT_LEVEL) {
|
||||
return mmhead->freelist[level];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *k_mm_alloc(k_mm_head *mmhead, size_t size)
|
||||
{
|
||||
void * retptr;
|
||||
k_mm_list_t *get_b, *new_b, *next_b;
|
||||
int32_t level;
|
||||
size_t left_size;
|
||||
size_t req_size = size;
|
||||
#if (RHINO_CONFIG_MM_BLK > 0)
|
||||
mblk_pool_t *mm_pool;
|
||||
#endif
|
||||
|
||||
(void)req_size;
|
||||
|
||||
if (!mmhead) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MM_CRITICAL_ENTER(mmhead);
|
||||
|
||||
#if (RHINO_CONFIG_MM_BLK > 0)
|
||||
/* little blk, try to get from mm_pool */
|
||||
if (mmhead->fix_pool != NULL) {
|
||||
mm_pool = (mblk_pool_t *)mmhead->fix_pool;
|
||||
if (size <= RHINO_CONFIG_MM_BLK_SIZE && mm_pool->blk_avail > 0) {
|
||||
retptr = k_mm_smallblk_alloc(mmhead, size);
|
||||
if (retptr) {
|
||||
MM_CRITICAL_EXIT(mmhead);
|
||||
return retptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
retptr = NULL;
|
||||
|
||||
size = MM_ALIGN_UP(size);
|
||||
size = size < MM_MIN_SIZE ? MM_MIN_SIZE : size;
|
||||
|
||||
if ((level = size_to_level(size)) == -1) {
|
||||
goto ALLOCEXIT;
|
||||
}
|
||||
|
||||
#if (RHINO_CONFIG_MM_QUICK > 0)
|
||||
/* try to find in higher level */
|
||||
get_b = find_up_level(mmhead, level);
|
||||
if (get_b == NULL) {
|
||||
/* try to find in same level */
|
||||
get_b = mmhead->freelist[level];
|
||||
while ( get_b != NULL ) {
|
||||
if ( MM_GET_BUF_SIZE(get_b) >= size ) {
|
||||
break;
|
||||
}
|
||||
get_b = get_b->mbinfo.free_ptr.next;
|
||||
}
|
||||
|
||||
if ( get_b == NULL ) {
|
||||
/* do not find availalbe freeblk */
|
||||
goto ALLOCEXIT;
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* try to find in same level */
|
||||
get_b = mmhead->freelist[level];
|
||||
while ( get_b != NULL ) {
|
||||
if ( MM_GET_BUF_SIZE(get_b) >= size ) {
|
||||
break;
|
||||
}
|
||||
get_b = get_b->mbinfo.free_ptr.next;
|
||||
}
|
||||
|
||||
if ( get_b == NULL ) {
|
||||
/* try to find in higher level */
|
||||
get_b = find_up_level(mmhead, level);
|
||||
if ( get_b == NULL ) {
|
||||
/* do not find availalbe freeblk */
|
||||
goto ALLOCEXIT;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
k_mm_freelist_delete(mmhead, get_b);
|
||||
|
||||
next_b = MM_GET_NEXT_BLK(get_b);
|
||||
|
||||
/* Should the block be split? */
|
||||
if (MM_GET_BUF_SIZE(get_b) >= size + MMLIST_HEAD_SIZE + MM_MIN_SIZE) {
|
||||
left_size = MM_GET_BUF_SIZE(get_b) - size - MMLIST_HEAD_SIZE;
|
||||
|
||||
get_b->buf_size = size | (get_b->buf_size & RHINO_MM_PRESTAT_MASK);
|
||||
new_b = MM_GET_NEXT_BLK(get_b);
|
||||
|
||||
new_b->prev = get_b;
|
||||
new_b->buf_size = left_size | RHINO_MM_FREE | RHINO_MM_PREVALLOCED;
|
||||
#if (RHINO_CONFIG_MM_DEBUG > 0u)
|
||||
new_b->dye = RHINO_MM_FREE_DYE;
|
||||
new_b->owner = 0;
|
||||
#endif
|
||||
next_b->prev = new_b;
|
||||
k_mm_freelist_insert(mmhead, new_b);
|
||||
} else {
|
||||
next_b->buf_size &= (~RHINO_MM_PREVFREE);
|
||||
}
|
||||
get_b->buf_size &= (~RHINO_MM_FREE); /* Now it's used */
|
||||
|
||||
#if (RHINO_CONFIG_MM_DEBUG > 0u)
|
||||
get_b->dye = RHINO_MM_CORRUPT_DYE;
|
||||
get_b->owner = 0;
|
||||
#endif
|
||||
retptr = (void *)get_b->mbinfo.buffer;
|
||||
if (retptr != NULL) {
|
||||
stats_addsize(mmhead, MM_GET_BLK_SIZE(get_b), req_size);
|
||||
}
|
||||
|
||||
ALLOCEXIT:
|
||||
|
||||
MM_CRITICAL_EXIT(mmhead);
|
||||
|
||||
return retptr;
|
||||
}
|
||||
|
||||
void k_mm_free(k_mm_head *mmhead, void *ptr)
|
||||
{
|
||||
k_mm_list_t *free_b, *next_b, *prev_b;
|
||||
|
||||
if (!ptr || !mmhead) {
|
||||
return;
|
||||
}
|
||||
|
||||
MM_CRITICAL_ENTER(mmhead);
|
||||
|
||||
#if (RHINO_CONFIG_MM_BLK > 0)
|
||||
/* fix blk, free to mm_pool */
|
||||
if (krhino_mblk_check(mmhead->fix_pool, ptr)) {
|
||||
/*it's fixed size memory block*/
|
||||
k_mm_smallblk_free(mmhead, ptr);
|
||||
MM_CRITICAL_EXIT(mmhead);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
free_b = MM_GET_THIS_BLK(ptr);
|
||||
|
||||
#if (RHINO_CONFIG_MM_DEBUG > 0u)
|
||||
if (free_b->dye == RHINO_MM_FREE_DYE) {
|
||||
MM_CRITICAL_EXIT(mmhead);
|
||||
printf("WARNING!! memory maybe double free!!\r\n");
|
||||
k_err_proc(RHINO_SYS_FATAL_ERR);
|
||||
}
|
||||
if (free_b->dye != RHINO_MM_CORRUPT_DYE) {
|
||||
MM_CRITICAL_EXIT(mmhead);
|
||||
printf("WARNING,memory maybe corrupt!!\r\n");
|
||||
k_err_proc(RHINO_SYS_FATAL_ERR);
|
||||
}
|
||||
free_b->dye = RHINO_MM_FREE_DYE;
|
||||
free_b->owner = 0;
|
||||
#endif
|
||||
free_b->buf_size |= RHINO_MM_FREE;
|
||||
|
||||
stats_removesize(mmhead, MM_GET_BLK_SIZE(free_b));
|
||||
|
||||
/* if the blk after this freed one is freed too, merge them */
|
||||
next_b = MM_GET_NEXT_BLK(free_b);
|
||||
if (next_b->buf_size & RHINO_MM_FREE) {
|
||||
k_mm_freelist_delete(mmhead, next_b);
|
||||
free_b->buf_size += MM_GET_BLK_SIZE(next_b);
|
||||
}
|
||||
|
||||
/* if the blk before this freed one is freed too, merge them */
|
||||
if (free_b->buf_size & RHINO_MM_PREVFREE) {
|
||||
prev_b = free_b->prev;
|
||||
#if (RHINO_CONFIG_MM_DEBUG > 0u)
|
||||
if (prev_b->dye != RHINO_MM_FREE_DYE) {
|
||||
MM_CRITICAL_EXIT(mmhead);
|
||||
printf("WARNING,memory overwritten!!\r\n");
|
||||
k_err_proc(RHINO_SYS_FATAL_ERR);
|
||||
}
|
||||
#endif
|
||||
k_mm_freelist_delete(mmhead, prev_b);
|
||||
prev_b->buf_size += MM_GET_BLK_SIZE(free_b);
|
||||
free_b = prev_b;
|
||||
}
|
||||
|
||||
/* after merge, free to list */
|
||||
k_mm_freelist_insert(mmhead, free_b);
|
||||
|
||||
next_b = MM_GET_NEXT_BLK(free_b);
|
||||
#if (RHINO_CONFIG_MM_DEBUG > 0u)
|
||||
if (next_b->dye != RHINO_MM_FREE_DYE &&
|
||||
next_b->dye != RHINO_MM_CORRUPT_DYE) {
|
||||
MM_CRITICAL_EXIT(mmhead);
|
||||
printf("WARNING,memory overwritten!!\r\n");
|
||||
k_err_proc(RHINO_SYS_FATAL_ERR);
|
||||
}
|
||||
#endif
|
||||
next_b->prev = free_b;
|
||||
next_b->buf_size |= RHINO_MM_PREVFREE;
|
||||
|
||||
MM_CRITICAL_EXIT(mmhead);
|
||||
}
|
||||
|
||||
void *k_mm_realloc(k_mm_head *mmhead, void *oldmem, size_t new_size)
|
||||
{
|
||||
void * ptr_aux = NULL;
|
||||
uint32_t cpsize;
|
||||
k_mm_list_t *this_b, *split_b, *next_b;
|
||||
size_t old_size, split_size;
|
||||
size_t req_size = 0;
|
||||
|
||||
(void)req_size;
|
||||
|
||||
if (oldmem == NULL) {
|
||||
if (new_size > 0) {
|
||||
return (void *)k_mm_alloc(mmhead, new_size);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
} else if (new_size == 0) {
|
||||
k_mm_free(mmhead, oldmem);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
req_size = new_size;
|
||||
|
||||
MM_CRITICAL_ENTER(mmhead);
|
||||
|
||||
#if (RHINO_CONFIG_MM_BLK > 0)
|
||||
/*begin of oldmem in mmblk case*/
|
||||
if (krhino_mblk_check(mmhead->fix_pool, oldmem)) {
|
||||
/*it's fixed size memory block*/
|
||||
if (new_size <= RHINO_CONFIG_MM_BLK_SIZE) {
|
||||
ptr_aux = oldmem;
|
||||
MM_CRITICAL_EXIT(mmhead);
|
||||
} else {
|
||||
MM_CRITICAL_EXIT(mmhead);
|
||||
ptr_aux = k_mm_alloc(mmhead, new_size);
|
||||
if (ptr_aux) {
|
||||
memcpy(ptr_aux, oldmem, RHINO_CONFIG_MM_BLK_SIZE);
|
||||
k_mm_smallblk_free(mmhead, oldmem);
|
||||
}
|
||||
}
|
||||
return ptr_aux;
|
||||
}
|
||||
/*end of mmblk case*/
|
||||
#endif
|
||||
|
||||
/*check if there more free block behind oldmem */
|
||||
this_b = MM_GET_THIS_BLK(oldmem);
|
||||
old_size = MM_GET_BUF_SIZE(this_b);
|
||||
next_b = MM_GET_NEXT_BLK(this_b);
|
||||
new_size = MM_ALIGN_UP(new_size);
|
||||
new_size = new_size < MM_MIN_SIZE ? MM_MIN_SIZE : new_size;
|
||||
|
||||
if (new_size <= old_size) {
|
||||
/* shrink blk */
|
||||
stats_removesize(mmhead, MM_GET_BLK_SIZE(this_b));
|
||||
if (next_b->buf_size & RHINO_MM_FREE) {
|
||||
/* merge next free */
|
||||
k_mm_freelist_delete(mmhead, next_b);
|
||||
old_size += MM_GET_BLK_SIZE(next_b);
|
||||
next_b = MM_GET_NEXT_BLK(next_b);
|
||||
}
|
||||
if (old_size >= new_size + MMLIST_HEAD_SIZE + MM_MIN_SIZE) {
|
||||
/* split blk */
|
||||
split_size = old_size - new_size - MMLIST_HEAD_SIZE;
|
||||
|
||||
this_b->buf_size =
|
||||
new_size | (this_b->buf_size & RHINO_MM_PRESTAT_MASK);
|
||||
split_b = MM_GET_NEXT_BLK(this_b);
|
||||
|
||||
split_b->prev = this_b;
|
||||
split_b->buf_size =
|
||||
split_size | RHINO_MM_FREE | RHINO_MM_PREVALLOCED;
|
||||
#if (RHINO_CONFIG_MM_DEBUG > 0u)
|
||||
split_b->dye = RHINO_MM_FREE_DYE;
|
||||
split_b->owner = 0;
|
||||
#endif
|
||||
next_b->prev = split_b;
|
||||
next_b->buf_size |= RHINO_MM_PREVFREE;
|
||||
k_mm_freelist_insert(mmhead, split_b);
|
||||
}
|
||||
stats_addsize(mmhead, MM_GET_BLK_SIZE(this_b), req_size);
|
||||
ptr_aux = (void *)this_b->mbinfo.buffer;
|
||||
} else if ((next_b->buf_size & RHINO_MM_FREE)) {
|
||||
/* enlarge blk */
|
||||
if (new_size <= (old_size + MM_GET_BLK_SIZE(next_b))) {
|
||||
stats_removesize(mmhead, MM_GET_BLK_SIZE(this_b));
|
||||
|
||||
/* delete next blk from freelist */
|
||||
k_mm_freelist_delete(mmhead, next_b);
|
||||
|
||||
/* enlarge this blk */
|
||||
this_b->buf_size += MM_GET_BLK_SIZE(next_b);
|
||||
|
||||
next_b = MM_GET_NEXT_BLK(this_b);
|
||||
next_b->prev = this_b;
|
||||
next_b->buf_size &= ~RHINO_MM_PREVFREE;
|
||||
|
||||
if (MM_GET_BUF_SIZE(this_b) >=
|
||||
new_size + MMLIST_HEAD_SIZE + MM_MIN_SIZE) {
|
||||
/* split blk */
|
||||
split_size =
|
||||
MM_GET_BUF_SIZE(this_b) - new_size - MMLIST_HEAD_SIZE;
|
||||
|
||||
this_b->buf_size =
|
||||
new_size | (this_b->buf_size & RHINO_MM_PRESTAT_MASK);
|
||||
split_b = MM_GET_NEXT_BLK(this_b);
|
||||
|
||||
split_b->prev = this_b;
|
||||
split_b->buf_size =
|
||||
split_size | RHINO_MM_FREE | RHINO_MM_PREVALLOCED;
|
||||
#if (RHINO_CONFIG_MM_DEBUG > 0u)
|
||||
split_b->dye = RHINO_MM_FREE_DYE;
|
||||
split_b->owner = 0;
|
||||
#endif
|
||||
next_b->prev = split_b;
|
||||
next_b->buf_size |= RHINO_MM_PREVFREE;
|
||||
k_mm_freelist_insert(mmhead, split_b);
|
||||
}
|
||||
stats_addsize(mmhead, MM_GET_BLK_SIZE(this_b), req_size);
|
||||
ptr_aux = (void *)this_b->mbinfo.buffer;
|
||||
}
|
||||
}
|
||||
|
||||
if (ptr_aux) {
|
||||
|
||||
#if (RHINO_CONFIG_MM_DEBUG > 0u)
|
||||
this_b->dye = RHINO_MM_CORRUPT_DYE;
|
||||
#endif
|
||||
|
||||
MM_CRITICAL_EXIT(mmhead);
|
||||
return ptr_aux;
|
||||
}
|
||||
|
||||
MM_CRITICAL_EXIT(mmhead);
|
||||
|
||||
/* re alloc blk */
|
||||
ptr_aux = k_mm_alloc(mmhead, new_size);
|
||||
if (!ptr_aux) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cpsize =
|
||||
(MM_GET_BUF_SIZE(this_b) > new_size) ? new_size : MM_GET_BUF_SIZE(this_b);
|
||||
|
||||
memcpy(ptr_aux, oldmem, cpsize);
|
||||
k_mm_free(mmhead, oldmem);
|
||||
|
||||
return ptr_aux;
|
||||
}
|
||||
|
||||
#if (RHINO_CONFIG_MM_DEBUG > 0u && RHINO_CONFIG_GCC_RETADDR > 0u)
|
||||
void krhino_owner_attach(k_mm_head *mmhead, void *addr, size_t allocator)
|
||||
{
|
||||
k_mm_list_t *blk;
|
||||
|
||||
if (!mmhead || !addr) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if (RHINO_CONFIG_MM_BLK > 0)
|
||||
/* fix blk, do not support debug info */
|
||||
if (krhino_mblk_check(mmhead->fix_pool, addr)) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
MM_CRITICAL_ENTER(mmhead);
|
||||
|
||||
blk = MM_GET_THIS_BLK(addr);
|
||||
blk->owner = allocator;
|
||||
|
||||
MM_CRITICAL_EXIT(mmhead);
|
||||
}
|
||||
#endif
|
||||
|
||||
void *krhino_mm_alloc(size_t size)
|
||||
{
|
||||
void *tmp;
|
||||
|
||||
#if (RHINO_CONFIG_MM_DEBUG > 0u && RHINO_CONFIG_GCC_RETADDR > 0u)
|
||||
uint32_t app_malloc = size & AOS_UNSIGNED_INT_MSB;
|
||||
size = size & (~AOS_UNSIGNED_INT_MSB);
|
||||
#endif
|
||||
|
||||
if (size == 0) {
|
||||
printf("WARNING, malloc size = 0\r\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tmp = k_mm_alloc(g_kmm_head, size);
|
||||
if (tmp == NULL) {
|
||||
#if (RHINO_CONFIG_MM_DEBUG > 0)
|
||||
static int32_t dumped;
|
||||
printf("WARNING, malloc failed!!!!\r\n");
|
||||
if (dumped) {
|
||||
return tmp;
|
||||
}
|
||||
dumped = 1;
|
||||
dumpsys_mm_info_func(0);
|
||||
#if (RHINO_CONFIG_MM_LEAKCHECK > 0)
|
||||
dump_mmleak();
|
||||
#endif
|
||||
k_err_proc(RHINO_NO_MEM);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if (RHINO_CONFIG_USER_HOOK > 0)
|
||||
krhino_mm_alloc_hook(tmp, size);
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_MM_DEBUG > 0u && RHINO_CONFIG_GCC_RETADDR > 0u)
|
||||
if (app_malloc == 0) {
|
||||
#if defined(__CC_ARM)
|
||||
krhino_owner_attach(g_kmm_head, tmp, __return_address());
|
||||
#elif defined(__GNUC__)
|
||||
krhino_owner_attach(g_kmm_head, tmp,
|
||||
(size_t)__builtin_return_address(0));
|
||||
#endif /* __CC_ARM */
|
||||
}
|
||||
#endif
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void krhino_mm_free(void *ptr)
|
||||
{
|
||||
k_mm_free(g_kmm_head, ptr);
|
||||
}
|
||||
|
||||
void *krhino_mm_realloc(void *oldmem, size_t newsize)
|
||||
{
|
||||
void *tmp;
|
||||
|
||||
#if (RHINO_CONFIG_MM_DEBUG > 0u && RHINO_CONFIG_GCC_RETADDR > 0u)
|
||||
uint32_t app_malloc = newsize & AOS_UNSIGNED_INT_MSB;
|
||||
newsize = newsize & (~AOS_UNSIGNED_INT_MSB);
|
||||
#endif
|
||||
|
||||
tmp = k_mm_realloc(g_kmm_head, oldmem, newsize);
|
||||
|
||||
#if (RHINO_CONFIG_MM_DEBUG > 0u && RHINO_CONFIG_GCC_RETADDR > 0u)
|
||||
if (app_malloc == 0) {
|
||||
#if defined(__CC_ARM)
|
||||
krhino_owner_attach(g_kmm_head, tmp, __return_address());
|
||||
#elif defined(__GNUC__)
|
||||
krhino_owner_attach(g_kmm_head, tmp,
|
||||
(size_t)__builtin_return_address(0));
|
||||
#endif /* __CC_ARM */
|
||||
}
|
||||
#endif
|
||||
if (tmp == NULL && newsize != 0) {
|
||||
#if (RHINO_CONFIG_MM_DEBUG > 0)
|
||||
static int32_t reallocdumped;
|
||||
printf("WARNING, realloc failed!!!!\r\n");
|
||||
if (reallocdumped) {
|
||||
return tmp;
|
||||
}
|
||||
reallocdumped = 1;
|
||||
dumpsys_mm_info_func(0);
|
||||
#if (RHINO_CONFIG_MM_LEAKCHECK > 0)
|
||||
dump_mmleak();
|
||||
#endif
|
||||
k_err_proc(RHINO_SYS_FATAL_ERR);
|
||||
#endif
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
#endif
|
||||
129
Living_SDK/kernel/rhino/core/k_mm_blk.c
Normal file
129
Living_SDK/kernel/rhino/core/k_mm_blk.c
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
|
||||
#if (RHINO_CONFIG_MM_BLK > 0)
|
||||
kstat_t krhino_mblk_pool_init(mblk_pool_t *pool, const name_t *name,
|
||||
void *pool_start,
|
||||
size_t blk_size, size_t pool_size)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
uint32_t blks; /* max blocks mem pool offers */
|
||||
uint8_t *blk_cur; /* block pointer for traversing */
|
||||
uint8_t *blk_next; /* next block pointe for traversing */
|
||||
uint8_t *pool_end; /* mem pool end */
|
||||
uint8_t addr_align_mask; /* address alignment */
|
||||
|
||||
NULL_PARA_CHK(pool);
|
||||
NULL_PARA_CHK(name);
|
||||
NULL_PARA_CHK(pool_start);
|
||||
|
||||
/* over one block at least */
|
||||
if (pool_size < (blk_size << 1u)) {
|
||||
return RHINO_BLK_POOL_SIZE_ERR;
|
||||
}
|
||||
|
||||
/* check address & size alignment */
|
||||
addr_align_mask = sizeof(void *) - 1u;
|
||||
|
||||
if (((size_t)pool_start & addr_align_mask) > 0u) {
|
||||
return RHINO_INV_ALIGN;
|
||||
}
|
||||
|
||||
if ((blk_size & addr_align_mask) > 0u) {
|
||||
return RHINO_INV_ALIGN;
|
||||
}
|
||||
|
||||
if ((pool_size & addr_align_mask) > 0u) {
|
||||
return RHINO_INV_ALIGN;
|
||||
}
|
||||
|
||||
krhino_spin_lock_init(&pool->blk_lock);
|
||||
|
||||
pool_end = (uint8_t *)pool_start + pool_size;
|
||||
blks = 0u;
|
||||
blk_cur = (uint8_t *)pool_start;
|
||||
blk_next = blk_cur + blk_size;
|
||||
|
||||
while (blk_next < pool_end) {
|
||||
blks++;
|
||||
/* use initial 4 byte point to next block */
|
||||
*(uint8_t **)blk_cur = blk_next;
|
||||
blk_cur = blk_next;
|
||||
blk_next = blk_cur + blk_size;
|
||||
}
|
||||
|
||||
if (blk_next == pool_end) {
|
||||
blks++;
|
||||
}
|
||||
|
||||
/* the last one */
|
||||
*((uint8_t **)blk_cur) = NULL;
|
||||
|
||||
pool->pool_name = name;
|
||||
pool->pool_start = pool_start;
|
||||
pool->pool_end = pool_end;
|
||||
pool->blk_whole = blks;
|
||||
pool->blk_avail = blks;
|
||||
pool->blk_size = blk_size;
|
||||
pool->avail_list = (uint8_t *)pool_start;
|
||||
|
||||
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
|
||||
RHINO_CRITICAL_ENTER();
|
||||
klist_insert(&(g_kobj_list.mblkpool_head), &pool->mblkpool_stats_item);
|
||||
RHINO_CRITICAL_EXIT();
|
||||
#endif
|
||||
|
||||
TRACE_MBLK_POOL_CREATE(krhino_cur_task_get(), pool);
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
kstat_t krhino_mblk_alloc(mblk_pool_t *pool, void **blk)
|
||||
{
|
||||
kstat_t status;
|
||||
uint8_t *avail_blk;
|
||||
|
||||
NULL_PARA_CHK(pool);
|
||||
NULL_PARA_CHK(blk);
|
||||
|
||||
krhino_spin_lock_irq_save(&pool->blk_lock);
|
||||
|
||||
if (pool->blk_avail > 0u) {
|
||||
avail_blk = pool->avail_list;
|
||||
*((uint8_t **)blk) = avail_blk;
|
||||
/* the first 4 byte is the pointer for next block */
|
||||
pool->avail_list = *(uint8_t **)(avail_blk);
|
||||
pool->blk_avail--;
|
||||
status = RHINO_SUCCESS;
|
||||
} else {
|
||||
*((uint8_t **)blk) = NULL;
|
||||
status = RHINO_NO_MEM;
|
||||
}
|
||||
|
||||
krhino_spin_unlock_irq_restore(&pool->blk_lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
kstat_t krhino_mblk_free(mblk_pool_t *pool, void *blk)
|
||||
{
|
||||
NULL_PARA_CHK(pool);
|
||||
NULL_PARA_CHK(blk);
|
||||
|
||||
krhino_spin_lock_irq_save(&pool->blk_lock);
|
||||
|
||||
/* use the first 4 byte of the free block point to head of avail list */
|
||||
*((uint8_t **)blk) = pool->avail_list;
|
||||
pool->avail_list = blk;
|
||||
pool->blk_avail++;
|
||||
|
||||
krhino_spin_unlock_irq_restore(&pool->blk_lock);
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
#endif /* RHINO_CONFIG_MM_BLK */
|
||||
|
||||
446
Living_SDK/kernel/rhino/core/k_mm_debug.c
Executable file
446
Living_SDK/kernel/rhino/core/k_mm_debug.c
Executable file
|
|
@ -0,0 +1,446 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <k_api.h>
|
||||
#if (RHINO_CONFIG_MM_TLF > 0)
|
||||
#include "k_mm.h"
|
||||
#endif
|
||||
#include "k_mm_debug.h"
|
||||
|
||||
|
||||
#ifdef CONFIG_AOS_CLI
|
||||
#include "aos/types.h"
|
||||
#include "aos/cli.h"
|
||||
extern int csp_printf(const char *fmt, ...);
|
||||
#define print aos_cli_printf
|
||||
#else
|
||||
#define print printf
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_MM_DEBUG > 0)
|
||||
|
||||
|
||||
extern klist_t g_mm_region_list_head;
|
||||
|
||||
#if (RHINO_CONFIG_MM_LEAKCHECK > 0)
|
||||
|
||||
|
||||
static mm_scan_region_t g_mm_scan_region[AOS_MM_SCAN_REGION_MAX];
|
||||
static void **g_leak_match;
|
||||
static uint32_t g_recheck_flag = 0;
|
||||
|
||||
static uint32_t check_malloc_region(void *adress);
|
||||
uint32_t if_adress_is_valid(void *adress);
|
||||
uint32_t dump_mmleak(void);
|
||||
|
||||
uint32_t krhino_mm_leak_region_init(void *start, void *end)
|
||||
{
|
||||
static uint32_t i = 0;
|
||||
|
||||
if (i >= AOS_MM_SCAN_REGION_MAX) {
|
||||
return i;
|
||||
}
|
||||
|
||||
if ((start == NULL) || (end == NULL)) {
|
||||
return i;
|
||||
}
|
||||
|
||||
g_mm_scan_region[i].start = start;
|
||||
g_mm_scan_region[i].end = end;
|
||||
|
||||
i++;
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
static uint32_t check_task_stack(ktask_t *task, void **p)
|
||||
{
|
||||
uint32_t offset = 0;
|
||||
kstat_t rst = RHINO_SUCCESS;
|
||||
void *start, *cur, *end;
|
||||
|
||||
start = task->task_stack_base;
|
||||
end = task->task_stack_base + task->stack_size;
|
||||
|
||||
rst = krhino_task_stack_cur_free(task, &offset);
|
||||
if (rst == RHINO_SUCCESS) {
|
||||
cur = task->task_stack_base + task->stack_size - offset;
|
||||
} else {
|
||||
k_err_proc(RHINO_SYS_SP_ERR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((size_t)p >= (size_t)cur &&
|
||||
(size_t)p < (size_t)end) {
|
||||
return 1;
|
||||
} else if ((size_t)p >= (size_t)start && (size_t)p < (size_t)cur) {
|
||||
return 0;
|
||||
}
|
||||
/*maybe lost*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
static uint32_t check_if_in_stack(void **p)
|
||||
{
|
||||
klist_t *taskhead = &g_kobj_list.task_head;
|
||||
klist_t *taskend = taskhead;
|
||||
klist_t *tmp;
|
||||
ktask_t *task;
|
||||
|
||||
|
||||
|
||||
for (tmp = taskhead->next; tmp != taskend; tmp = tmp->next) {
|
||||
task = krhino_list_entry(tmp, ktask_t, task_stats_item);
|
||||
if (1 == check_task_stack(task, p)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t scan_region(void *start, void *end, void *adress)
|
||||
{
|
||||
void **p = (void **)((uint32_t)start & ~(sizeof(size_t) - 1));
|
||||
while ((void *)p < end) {
|
||||
if (NULL != p && adress == *p) {
|
||||
g_leak_match = p;
|
||||
return 1;
|
||||
}
|
||||
|
||||
p++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
uint32_t check_mm_leak(uint8_t *adress)
|
||||
{
|
||||
uint32_t rst = 0;
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < AOS_MM_SCAN_REGION_MAX; i++) {
|
||||
|
||||
if ((NULL == g_mm_scan_region[i].start) || (NULL == g_mm_scan_region[i].end)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (1 == scan_region(g_mm_scan_region[i].start, g_mm_scan_region[i].end,
|
||||
adress)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
rst = check_malloc_region(adress);
|
||||
if (1 == rst) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t recheck(void *start, void *end)
|
||||
{
|
||||
void **p = (void **)((uint32_t)start & ~(sizeof(size_t) - 1));
|
||||
|
||||
g_recheck_flag = 1;
|
||||
|
||||
while ((void *)p <= end) {
|
||||
if (NULL != p && 1 == if_adress_is_valid(*p)) {
|
||||
if ( 1 == check_mm_leak(*p)) {
|
||||
g_recheck_flag = 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
g_recheck_flag = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#if (RHINO_CONFIG_MM_TLF > 0)
|
||||
uint32_t check_malloc_region(void *adress)
|
||||
{
|
||||
uint32_t rst = 0;
|
||||
k_mm_region_info_t *reginfo, *nextreg;
|
||||
k_mm_list_t *next, *cur;
|
||||
|
||||
NULL_PARA_CHK(g_kmm_head);
|
||||
|
||||
reginfo = g_kmm_head->regioninfo;
|
||||
while (reginfo) {
|
||||
cur = MM_GET_THIS_BLK(reginfo);
|
||||
/*jump first blk*/
|
||||
cur = MM_GET_NEXT_BLK(cur);
|
||||
while (cur) {
|
||||
if (MM_GET_BUF_SIZE(cur)) {
|
||||
next = MM_GET_NEXT_BLK(cur);
|
||||
if (0 == g_recheck_flag && !(cur->buf_size & RHINO_MM_FREE)) {
|
||||
if ((uint8_t *)krhino_cur_task_get()->task_stack_base >= cur->mbinfo.buffer
|
||||
&& (uint8_t *)krhino_cur_task_get()->task_stack_base < (uint8_t *)next) {
|
||||
cur = next;
|
||||
continue;
|
||||
}
|
||||
rst = scan_region(cur->mbinfo.buffer, (void *) next, adress);
|
||||
if (1 == rst) {
|
||||
return check_if_in_stack(g_leak_match);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
next = NULL;
|
||||
}
|
||||
if (1 == g_recheck_flag &&
|
||||
(uint32_t)adress >= (uint32_t)cur->mbinfo.buffer &&
|
||||
(uint32_t)adress < (uint32_t)next) {
|
||||
return 1;
|
||||
}
|
||||
cur = next;
|
||||
}
|
||||
nextreg = reginfo->next;
|
||||
reginfo = nextreg;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint32_t if_adress_is_valid(void *adress)
|
||||
{
|
||||
k_mm_region_info_t *reginfo, *nextreg;
|
||||
k_mm_list_t *next, *cur;
|
||||
|
||||
reginfo = g_kmm_head->regioninfo;
|
||||
while (reginfo) {
|
||||
cur = MM_GET_THIS_BLK(reginfo);
|
||||
/*jump first blk*/
|
||||
cur = MM_GET_NEXT_BLK(cur);
|
||||
while (cur) {
|
||||
if (MM_GET_BUF_SIZE(cur)) {
|
||||
next = MM_GET_NEXT_BLK(cur);
|
||||
if (!(cur->buf_size & RHINO_MM_FREE) &&
|
||||
(size_t)adress >= (size_t)cur->mbinfo.buffer && (size_t)adress < (size_t)next ) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
} else {
|
||||
next = NULL;
|
||||
}
|
||||
cur = next;
|
||||
}
|
||||
nextreg = reginfo->next;
|
||||
reginfo = nextreg;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
uint32_t dump_mmleak()
|
||||
{
|
||||
k_mm_region_info_t *reginfo, *nextreg;
|
||||
k_mm_list_t *next, *cur;
|
||||
|
||||
MM_CRITICAL_ENTER(g_kmm_head);
|
||||
|
||||
reginfo = g_kmm_head->regioninfo;
|
||||
while (reginfo) {
|
||||
cur = MM_GET_THIS_BLK(reginfo);
|
||||
/*jump first blk*/
|
||||
cur = MM_GET_NEXT_BLK(cur);
|
||||
while (cur) {
|
||||
if (MM_GET_BUF_SIZE(cur)) {
|
||||
next = MM_GET_NEXT_BLK(cur);
|
||||
if (!(cur->buf_size & RHINO_MM_FREE) &&
|
||||
0 == check_mm_leak(cur->mbinfo.buffer)
|
||||
&& 0 == recheck((void *)cur->mbinfo.buffer , (void *)next)) {
|
||||
print("adress:0x%0x owner:0x%0x len:%-5d type:%s\r\n",
|
||||
(void *)cur->mbinfo.buffer, cur->owner,
|
||||
MM_GET_BUF_SIZE(cur), "leak");
|
||||
}
|
||||
|
||||
} else {
|
||||
next = NULL;
|
||||
}
|
||||
cur = next;
|
||||
}
|
||||
nextreg = reginfo->next;
|
||||
reginfo = nextreg;
|
||||
}
|
||||
|
||||
MM_CRITICAL_EXIT(g_kmm_head);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_MM_TLF > 0)
|
||||
|
||||
void print_block(k_mm_list_t *b)
|
||||
{
|
||||
if (!b) {
|
||||
return;
|
||||
}
|
||||
print("%p ", b);
|
||||
if (b->buf_size & RHINO_MM_FREE) {
|
||||
|
||||
#if (RHINO_CONFIG_MM_DEBUG > 0u)
|
||||
if (b->dye != RHINO_MM_FREE_DYE) {
|
||||
print("!");
|
||||
} else {
|
||||
print(" ");
|
||||
}
|
||||
#endif
|
||||
print("free ");
|
||||
} else {
|
||||
#if (RHINO_CONFIG_MM_DEBUG > 0u)
|
||||
if (b->dye != RHINO_MM_CORRUPT_DYE) {
|
||||
print("!");
|
||||
} else {
|
||||
print(" ");
|
||||
}
|
||||
#endif
|
||||
print("used ");
|
||||
}
|
||||
if (MM_GET_BUF_SIZE(b)) {
|
||||
print(" %6lu ", (unsigned long)MM_GET_BUF_SIZE(b));
|
||||
} else {
|
||||
print(" sentinel ");
|
||||
}
|
||||
|
||||
#if (RHINO_CONFIG_MM_DEBUG > 0u)
|
||||
print(" %8x ", b->dye);
|
||||
print(" 0x%-8x ", b->owner);
|
||||
#endif
|
||||
|
||||
if (b->buf_size & RHINO_MM_PREVFREE) {
|
||||
print("pre-free [%8p];", b->prev);
|
||||
} else {
|
||||
print("pre-used;");
|
||||
}
|
||||
|
||||
if (b->buf_size & RHINO_MM_FREE) {
|
||||
print(" free[%8p,%8p] ", b->mbinfo.free_ptr.prev, b->mbinfo.free_ptr.next);
|
||||
}
|
||||
print("\r\n");
|
||||
|
||||
}
|
||||
|
||||
void dump_kmm_free_map(k_mm_head *mmhead)
|
||||
{
|
||||
k_mm_list_t *next, *tmp;
|
||||
int i;
|
||||
|
||||
if (!mmhead) {
|
||||
return;
|
||||
}
|
||||
|
||||
print("freelist bitmap: 0x%x\r\n", (unsigned)mmhead->free_bitmap);
|
||||
print("address, stat size dye caller pre-stat point\r\n");
|
||||
|
||||
for (i = 0; i < MM_BIT_LEVEL; i++) {
|
||||
next = mmhead->freelist[i];
|
||||
while (next) {
|
||||
print_block(next);
|
||||
tmp = next->mbinfo.free_ptr.next;
|
||||
next = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dump_kmm_map(k_mm_head *mmhead)
|
||||
{
|
||||
k_mm_region_info_t *reginfo, *nextreg;
|
||||
k_mm_list_t *next, *cur;
|
||||
|
||||
if (!mmhead) {
|
||||
return;
|
||||
}
|
||||
|
||||
print("ALL BLOCKS\r\n");
|
||||
print("address, stat size dye caller pre-stat point\r\n");
|
||||
reginfo = mmhead->regioninfo;
|
||||
while (reginfo) {
|
||||
cur = MM_GET_THIS_BLK(reginfo);
|
||||
while (cur) {
|
||||
print_block(cur);
|
||||
if (MM_GET_BUF_SIZE(cur)) {
|
||||
next = MM_GET_NEXT_BLK(cur);
|
||||
} else {
|
||||
next = NULL;
|
||||
}
|
||||
cur = next;
|
||||
}
|
||||
nextreg = reginfo->next;
|
||||
reginfo = nextreg;
|
||||
}
|
||||
}
|
||||
|
||||
void dump_kmm_statistic_info(k_mm_head *mmhead)
|
||||
{
|
||||
#if (K_MM_STATISTIC > 0)
|
||||
int i;
|
||||
#endif
|
||||
#if (RHINO_CONFIG_MM_BLK > 0)
|
||||
mblk_pool_t *pool;
|
||||
#endif
|
||||
|
||||
if (!mmhead) {
|
||||
return;
|
||||
}
|
||||
#if (K_MM_STATISTIC > 0)
|
||||
print(" free | used | maxused\r\n");
|
||||
print(" %10d | %10d | %10d\r\n",
|
||||
mmhead->free_size, mmhead->used_size, mmhead->maxused_size);
|
||||
print("\r\n");
|
||||
print("-----------------number of alloc times:-----------------\r\n");
|
||||
for (i = 0; i < MM_BIT_LEVEL; i++) {
|
||||
if (i % 4 == 0 && i != 0) {
|
||||
print("\r\n");
|
||||
}
|
||||
print("[2^%02d] bytes: %5d |", (i+MM_MIN_BIT), mmhead->alloc_times[i]);
|
||||
}
|
||||
print("\r\n");
|
||||
#endif
|
||||
#if (RHINO_CONFIG_MM_BLK > 0)
|
||||
pool = mmhead->fix_pool;
|
||||
if ( pool != NULL )
|
||||
{
|
||||
print("-----------------fix pool information:-----------------\r\n");
|
||||
print(" free | used | total\r\n");
|
||||
print(" %10d | %10d | %10d\r\n",
|
||||
pool->blk_avail*RHINO_CONFIG_MM_BLK_SIZE,
|
||||
(pool->blk_whole - pool->blk_avail)*RHINO_CONFIG_MM_BLK_SIZE,
|
||||
pool->blk_whole*RHINO_CONFIG_MM_BLK_SIZE);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t dumpsys_mm_info_func(uint32_t len)
|
||||
{
|
||||
MM_CRITICAL_ENTER(g_kmm_head);
|
||||
|
||||
print("\r\n");
|
||||
print("------------------------------- all memory blocks --------------------------------- \r\n");
|
||||
print("g_kmm_head = %8x\r\n", (unsigned int)g_kmm_head);
|
||||
|
||||
dump_kmm_map(g_kmm_head);
|
||||
print("\r\n");
|
||||
print("----------------------------- all free memory blocks ------------------------------- \r\n");
|
||||
dump_kmm_free_map(g_kmm_head);
|
||||
print("\r\n");
|
||||
print("------------------------- memory allocation statistic ------------------------------ \r\n");
|
||||
dump_kmm_statistic_info(g_kmm_head);
|
||||
|
||||
MM_CRITICAL_EXIT(g_kmm_head);
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
433
Living_SDK/kernel/rhino/core/k_mutex.c
Normal file
433
Living_SDK/kernel/rhino/core/k_mutex.c
Normal file
|
|
@ -0,0 +1,433 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
|
||||
kstat_t mutex_create(kmutex_t *mutex, const name_t *name, uint8_t mm_alloc_flag)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
NULL_PARA_CHK(mutex);
|
||||
NULL_PARA_CHK(name);
|
||||
|
||||
/* init the list */
|
||||
klist_init(&mutex->blk_obj.blk_list);
|
||||
mutex->blk_obj.blk_policy = BLK_POLICY_PRI;
|
||||
mutex->blk_obj.name = name;
|
||||
mutex->mutex_task = NULL;
|
||||
mutex->mutex_list = NULL;
|
||||
mutex->mm_alloc_flag = mm_alloc_flag;
|
||||
|
||||
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
|
||||
RHINO_CRITICAL_ENTER();
|
||||
klist_insert(&(g_kobj_list.mutex_head), &mutex->mutex_item);
|
||||
RHINO_CRITICAL_EXIT();
|
||||
#endif
|
||||
|
||||
mutex->blk_obj.obj_type = RHINO_MUTEX_OBJ_TYPE;
|
||||
|
||||
TRACE_MUTEX_CREATE(krhino_cur_task_get(), mutex, name);
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
kstat_t krhino_mutex_create(kmutex_t *mutex, const name_t *name)
|
||||
{
|
||||
return mutex_create(mutex, name, K_OBJ_STATIC_ALLOC);
|
||||
}
|
||||
|
||||
static void mutex_release(ktask_t *task, kmutex_t *mutex_rel)
|
||||
{
|
||||
uint8_t new_pri;
|
||||
|
||||
/* find suitable task prio */
|
||||
new_pri = mutex_pri_look(task, mutex_rel);
|
||||
if (new_pri != task->prio) {
|
||||
/* change prio */
|
||||
task_pri_change(task, new_pri);
|
||||
|
||||
TRACE_MUTEX_RELEASE(g_active_task[cpu_cur_get()], task, new_pri);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
kstat_t krhino_mutex_del(kmutex_t *mutex)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
klist_t *blk_list_head;
|
||||
|
||||
if (mutex == NULL) {
|
||||
return RHINO_NULL_PTR;
|
||||
}
|
||||
|
||||
NULL_PARA_CHK(mutex);
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
|
||||
INTRPT_NESTED_LEVEL_CHK();
|
||||
|
||||
if (mutex->blk_obj.obj_type != RHINO_MUTEX_OBJ_TYPE) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_KOBJ_TYPE_ERR;
|
||||
}
|
||||
|
||||
if (mutex->mm_alloc_flag != K_OBJ_STATIC_ALLOC) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_KOBJ_DEL_ERR;
|
||||
}
|
||||
|
||||
blk_list_head = &mutex->blk_obj.blk_list;
|
||||
|
||||
mutex->blk_obj.obj_type = RHINO_OBJ_TYPE_NONE;
|
||||
|
||||
if (mutex->mutex_task != NULL) {
|
||||
mutex_release(mutex->mutex_task, mutex);
|
||||
}
|
||||
|
||||
/* all task blocked on this mutex is waken up */
|
||||
while (!is_klist_empty(blk_list_head)) {
|
||||
pend_task_rm(krhino_list_entry(blk_list_head->next, ktask_t, task_list));
|
||||
}
|
||||
|
||||
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
|
||||
klist_rm(&mutex->mutex_item);
|
||||
#endif
|
||||
|
||||
TRACE_MUTEX_DEL(g_active_task[cpu_cur_get()], mutex);
|
||||
|
||||
RHINO_CRITICAL_EXIT_SCHED();
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
#if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0)
|
||||
kstat_t krhino_mutex_dyn_create(kmutex_t **mutex, const name_t *name)
|
||||
{
|
||||
kstat_t stat;
|
||||
kmutex_t *mutex_obj;
|
||||
|
||||
if (mutex == NULL) {
|
||||
return RHINO_NULL_PTR;
|
||||
}
|
||||
|
||||
NULL_PARA_CHK(mutex);
|
||||
|
||||
mutex_obj = krhino_mm_alloc(sizeof(kmutex_t));
|
||||
if (mutex_obj == NULL) {
|
||||
return RHINO_NO_MEM;
|
||||
}
|
||||
|
||||
stat = mutex_create(mutex_obj, name, K_OBJ_DYN_ALLOC);
|
||||
if (stat != RHINO_SUCCESS) {
|
||||
krhino_mm_free(mutex_obj);
|
||||
return stat;
|
||||
}
|
||||
|
||||
*mutex = mutex_obj;
|
||||
|
||||
return stat;
|
||||
}
|
||||
|
||||
kstat_t krhino_mutex_dyn_del(kmutex_t *mutex)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
klist_t *blk_list_head;
|
||||
|
||||
if (mutex == NULL) {
|
||||
return RHINO_NULL_PTR;
|
||||
}
|
||||
|
||||
NULL_PARA_CHK(mutex);
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
|
||||
INTRPT_NESTED_LEVEL_CHK();
|
||||
|
||||
if (mutex->blk_obj.obj_type != RHINO_MUTEX_OBJ_TYPE) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_KOBJ_TYPE_ERR;
|
||||
}
|
||||
|
||||
if (mutex->mm_alloc_flag != K_OBJ_DYN_ALLOC) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_KOBJ_DEL_ERR;
|
||||
}
|
||||
|
||||
blk_list_head = &mutex->blk_obj.blk_list;
|
||||
|
||||
mutex->blk_obj.obj_type = RHINO_OBJ_TYPE_NONE;
|
||||
|
||||
if (mutex->mutex_task != NULL) {
|
||||
mutex_release(mutex->mutex_task, mutex);
|
||||
}
|
||||
|
||||
/* all task blocked on this mutex is waken up */
|
||||
while (!is_klist_empty(blk_list_head)) {
|
||||
pend_task_rm(krhino_list_entry(blk_list_head->next, ktask_t, task_list));
|
||||
}
|
||||
|
||||
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
|
||||
klist_rm(&mutex->mutex_item);
|
||||
#endif
|
||||
|
||||
TRACE_MUTEX_DEL(g_active_task[cpu_cur_get()], mutex);
|
||||
|
||||
RHINO_CRITICAL_EXIT_SCHED();
|
||||
|
||||
krhino_mm_free(mutex);
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint8_t mutex_pri_limit(ktask_t *task, uint8_t pri)
|
||||
{
|
||||
kmutex_t *mutex_tmp;
|
||||
uint8_t high_pri;
|
||||
ktask_t *first_blk_task;
|
||||
klist_t *blk_list_head;
|
||||
|
||||
high_pri = pri;
|
||||
|
||||
for (mutex_tmp = task->mutex_list; mutex_tmp != NULL;
|
||||
mutex_tmp = mutex_tmp->mutex_list) {
|
||||
blk_list_head = &mutex_tmp->blk_obj.blk_list;
|
||||
|
||||
if (!is_klist_empty(blk_list_head)) {
|
||||
first_blk_task = krhino_list_entry(blk_list_head->next, ktask_t, task_list);
|
||||
pri = first_blk_task->prio;
|
||||
}
|
||||
|
||||
/* can not set lower prio than the highest prio in all mutexes which hold lock */
|
||||
if (pri < high_pri) {
|
||||
high_pri = pri;
|
||||
}
|
||||
}
|
||||
|
||||
return high_pri;
|
||||
}
|
||||
|
||||
uint8_t mutex_pri_look(ktask_t *task, kmutex_t *mutex_rel)
|
||||
{
|
||||
kmutex_t *mutex_tmp;
|
||||
kmutex_t **prev;
|
||||
uint8_t new_pri;
|
||||
uint8_t pri;
|
||||
ktask_t *first_blk_task;
|
||||
klist_t *blk_list_head;
|
||||
|
||||
/* the base prio of task */
|
||||
new_pri = task->b_prio;
|
||||
|
||||
/* the highest prio in mutex which is locked */
|
||||
pri = new_pri;
|
||||
prev = &task->mutex_list;
|
||||
|
||||
while ((mutex_tmp = *prev) != NULL) {
|
||||
if (mutex_tmp == mutex_rel) {
|
||||
/* delete itself from list and make task->mutex_list point to next */
|
||||
*prev = mutex_tmp->mutex_list;
|
||||
continue;
|
||||
}
|
||||
|
||||
blk_list_head = &mutex_tmp->blk_obj.blk_list;
|
||||
if (!is_klist_empty(blk_list_head)) {
|
||||
first_blk_task = krhino_list_entry(blk_list_head->next, ktask_t, task_list);
|
||||
pri = first_blk_task->prio;
|
||||
}
|
||||
|
||||
if (new_pri > pri) {
|
||||
new_pri = pri;
|
||||
}
|
||||
|
||||
prev = &mutex_tmp->mutex_list;
|
||||
}
|
||||
|
||||
return new_pri;
|
||||
}
|
||||
|
||||
void mutex_task_pri_reset(ktask_t *task)
|
||||
{
|
||||
kmutex_t *mutex_tmp;
|
||||
ktask_t *mutex_task;
|
||||
|
||||
if (task->blk_obj->obj_type == RHINO_MUTEX_OBJ_TYPE) {
|
||||
mutex_tmp = (kmutex_t *)(task->blk_obj);
|
||||
mutex_task = mutex_tmp->mutex_task;
|
||||
|
||||
/* the new highest prio task blocked on this mutex may decrease prio than before so reset the mutex task prio */
|
||||
if (mutex_task->prio == task->prio) {
|
||||
mutex_release(mutex_task, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
kstat_t krhino_mutex_lock(kmutex_t *mutex, tick_t ticks)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
kstat_t ret;
|
||||
ktask_t *mutex_task;
|
||||
uint8_t cur_cpu_num;
|
||||
|
||||
NULL_PARA_CHK(mutex);
|
||||
|
||||
if (g_sys_stat == RHINO_STOPPED) {
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
|
||||
INTRPT_NESTED_LEVEL_CHK();
|
||||
|
||||
if (mutex->blk_obj.obj_type != RHINO_MUTEX_OBJ_TYPE) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_KOBJ_TYPE_ERR;
|
||||
}
|
||||
|
||||
cur_cpu_num = cpu_cur_get();
|
||||
|
||||
/* if the same task get the same mutex again, it causes mutex owner nested */
|
||||
if (g_active_task[cur_cpu_num] == mutex->mutex_task) {
|
||||
if (mutex->owner_nested == (mutex_nested_t)-1) {
|
||||
/* fatal error here, system must be stoped here */
|
||||
k_err_proc(RHINO_MUTEX_NESTED_OVF);
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_MUTEX_NESTED_OVF;
|
||||
} else {
|
||||
mutex->owner_nested++;
|
||||
}
|
||||
|
||||
RHINO_CRITICAL_EXIT();
|
||||
|
||||
return RHINO_MUTEX_OWNER_NESTED;
|
||||
}
|
||||
|
||||
mutex_task = mutex->mutex_task;
|
||||
if (mutex_task == NULL) {
|
||||
/* get lock */
|
||||
mutex->mutex_task = g_active_task[cur_cpu_num];
|
||||
mutex->mutex_list = g_active_task[cur_cpu_num]->mutex_list;
|
||||
g_active_task[cur_cpu_num]->mutex_list = mutex;
|
||||
mutex->owner_nested = 1u;
|
||||
|
||||
TRACE_MUTEX_GET(g_active_task[cur_cpu_num], mutex, ticks);
|
||||
|
||||
RHINO_CRITICAL_EXIT();
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
/* can't get mutex, and return immediately if wait_option is RHINO_NO_WAIT */
|
||||
if (ticks == RHINO_NO_WAIT) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_NO_PEND_WAIT;
|
||||
}
|
||||
|
||||
/* system is locked so task can not be blocked just return immediately */
|
||||
if (g_sched_lock[cur_cpu_num] > 0u) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_SCHED_DISABLE;
|
||||
}
|
||||
|
||||
/* if current task is a higher prio task and block on the mutex
|
||||
prio inverse condition happened, prio inherit method is used here */
|
||||
if (g_active_task[cur_cpu_num]->prio < mutex_task->prio) {
|
||||
task_pri_change(mutex_task, g_active_task[cur_cpu_num]->prio);
|
||||
|
||||
TRACE_TASK_PRI_INV(g_active_task[cur_cpu_num], mutex_task);
|
||||
|
||||
}
|
||||
|
||||
/* any way block the current task */
|
||||
pend_to_blk_obj((blk_obj_t *)mutex, g_active_task[cur_cpu_num], ticks);
|
||||
|
||||
TRACE_MUTEX_GET_BLK(g_active_task[cur_cpu_num], mutex, ticks);
|
||||
|
||||
RHINO_CRITICAL_EXIT_SCHED();
|
||||
|
||||
RHINO_CPU_INTRPT_DISABLE();
|
||||
|
||||
/* so the task is waked up, need know which reason cause wake up */
|
||||
ret = pend_state_end_proc(g_active_task[cpu_cur_get()]);
|
||||
|
||||
RHINO_CPU_INTRPT_ENABLE();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
kstat_t krhino_mutex_unlock(kmutex_t *mutex)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
klist_t *blk_list_head;
|
||||
ktask_t *task;
|
||||
uint8_t cur_cpu_num;
|
||||
|
||||
NULL_PARA_CHK(mutex);
|
||||
|
||||
if (g_sys_stat == RHINO_STOPPED) {
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
|
||||
INTRPT_NESTED_LEVEL_CHK();
|
||||
|
||||
if (mutex->blk_obj.obj_type != RHINO_MUTEX_OBJ_TYPE) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_KOBJ_TYPE_ERR;
|
||||
}
|
||||
|
||||
cur_cpu_num = cpu_cur_get();
|
||||
|
||||
/* mutex must be released by itself */
|
||||
if (g_active_task[cur_cpu_num] != mutex->mutex_task) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_MUTEX_NOT_RELEASED_BY_OWNER;
|
||||
}
|
||||
|
||||
mutex->owner_nested--;
|
||||
|
||||
if (mutex->owner_nested > 0u) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_MUTEX_OWNER_NESTED;
|
||||
}
|
||||
|
||||
mutex_release(g_active_task[cur_cpu_num], mutex);
|
||||
|
||||
blk_list_head = &mutex->blk_obj.blk_list;
|
||||
|
||||
/* if no block task on this list just return */
|
||||
if (is_klist_empty(blk_list_head)) {
|
||||
/* No wait task */
|
||||
mutex->mutex_task = NULL;
|
||||
|
||||
TRACE_MUTEX_RELEASE_SUCCESS(g_active_task[cur_cpu_num], mutex);
|
||||
RHINO_CRITICAL_EXIT();
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
/* there must have task blocked on this mutex object */
|
||||
task = krhino_list_entry(blk_list_head->next, ktask_t, task_list);
|
||||
|
||||
/* wake up the occupy task, which is the highst prio task on the list */
|
||||
pend_task_wakeup(task);
|
||||
|
||||
TRACE_MUTEX_TASK_WAKE(g_active_task[cur_cpu_num], task, mutex);
|
||||
|
||||
/* change mutex get task */
|
||||
mutex->mutex_task = task;
|
||||
mutex->mutex_list = task->mutex_list;
|
||||
task->mutex_list = mutex;
|
||||
mutex->owner_nested = 1u;
|
||||
|
||||
RHINO_CRITICAL_EXIT_SCHED();
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
91
Living_SDK/kernel/rhino/core/k_obj.c
Normal file
91
Living_SDK/kernel/rhino/core/k_obj.c
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
|
||||
kstat_t g_sys_stat;
|
||||
uint8_t g_idle_task_spawned[RHINO_CONFIG_CPU_NUM];
|
||||
|
||||
runqueue_t g_ready_queue;
|
||||
|
||||
/* schedule lock counter */
|
||||
uint8_t g_sched_lock[RHINO_CONFIG_CPU_NUM];
|
||||
uint8_t g_intrpt_nested_level[RHINO_CONFIG_CPU_NUM];
|
||||
|
||||
/* highest pri task in ready queue */
|
||||
ktask_t *g_preferred_ready_task[RHINO_CONFIG_CPU_NUM];
|
||||
|
||||
/* current active task */
|
||||
ktask_t *g_active_task[RHINO_CONFIG_CPU_NUM];
|
||||
|
||||
/* idle task attribute */
|
||||
ktask_t g_idle_task[RHINO_CONFIG_CPU_NUM];
|
||||
idle_count_t g_idle_count[RHINO_CONFIG_CPU_NUM];
|
||||
cpu_stack_t g_idle_task_stack[RHINO_CONFIG_CPU_NUM][RHINO_CONFIG_IDLE_TASK_STACK_SIZE];
|
||||
|
||||
/* tick attribute */
|
||||
tick_t g_tick_count;
|
||||
klist_t g_tick_head;
|
||||
|
||||
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
|
||||
kobj_list_t g_kobj_list;
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_TIMER > 0)
|
||||
klist_t g_timer_head;
|
||||
sys_time_t g_timer_count;
|
||||
ktask_t g_timer_task;
|
||||
cpu_stack_t g_timer_task_stack[RHINO_CONFIG_TIMER_TASK_STACK_SIZE];
|
||||
kbuf_queue_t g_timer_queue;
|
||||
k_timer_queue_cb timer_queue_cb[RHINO_CONFIG_TIMER_MSG_NUM];
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_DISABLE_SCHED_STATS > 0)
|
||||
hr_timer_t g_sched_disable_time_start;
|
||||
hr_timer_t g_sched_disable_max_time;
|
||||
hr_timer_t g_cur_sched_disable_max_time;
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_DISABLE_INTRPT_STATS > 0)
|
||||
uint16_t g_intrpt_disable_times;
|
||||
hr_timer_t g_intrpt_disable_time_start;
|
||||
hr_timer_t g_intrpt_disable_max_time;
|
||||
hr_timer_t g_cur_intrpt_disable_max_time;
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_HW_COUNT > 0)
|
||||
hr_timer_t g_sys_measure_waste;
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_CPU_USAGE_STATS > 0)
|
||||
ktask_t g_cpu_usage_task;
|
||||
cpu_stack_t g_cpu_task_stack[RHINO_CONFIG_CPU_USAGE_TASK_STACK];
|
||||
idle_count_t g_idle_count_max;
|
||||
uint32_t g_cpu_usage;
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_TASK_SCHED_STATS > 0)
|
||||
ctx_switch_t g_sys_ctx_switch_times;
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0)
|
||||
ksem_t g_res_sem;
|
||||
klist_t g_res_list;
|
||||
ktask_t g_dyn_task;
|
||||
cpu_stack_t g_dyn_task_stack[RHINO_CONFIG_K_DYN_TASK_STACK];
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_WORKQUEUE > 0)
|
||||
klist_t g_workqueue_list_head;
|
||||
kmutex_t g_workqueue_mutex;
|
||||
kworkqueue_t g_workqueue_default;
|
||||
cpu_stack_t g_workqueue_stack[RHINO_CONFIG_WORKQUEUE_STACK_SIZE];
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_MM_TLF > 0)
|
||||
|
||||
k_mm_head *g_kmm_head;
|
||||
|
||||
#endif
|
||||
|
||||
135
Living_SDK/kernel/rhino/core/k_pend.c
Normal file
135
Living_SDK/kernel/rhino/core/k_pend.c
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
|
||||
RHINO_INLINE void pend_list_add(klist_t *head, ktask_t *task)
|
||||
{
|
||||
klist_t *tmp;
|
||||
klist_t *list_start = head;
|
||||
klist_t *list_end = head;
|
||||
|
||||
for (tmp = list_start->next; tmp != list_end; tmp = tmp->next) {
|
||||
if (krhino_list_entry(tmp, ktask_t, task_list)->prio > task->prio) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
klist_insert(tmp, &task->task_list);
|
||||
}
|
||||
|
||||
void pend_task_wakeup(ktask_t *task)
|
||||
{
|
||||
/* wake up task depend on the different state of task */
|
||||
switch (task->task_state) {
|
||||
case K_PEND:
|
||||
/* remove task on the block list because task is waken up */
|
||||
klist_rm(&task->task_list);
|
||||
/* add to the ready list again */
|
||||
ready_list_add(&g_ready_queue, task);
|
||||
task->task_state = K_RDY;
|
||||
break;
|
||||
case K_PEND_SUSPENDED:
|
||||
/* remove task on the block list because task is waken up */
|
||||
klist_rm(&task->task_list);
|
||||
task->task_state = K_SUSPENDED;
|
||||
break;
|
||||
default:
|
||||
k_err_proc(RHINO_SYS_FATAL_ERR);
|
||||
break;
|
||||
}
|
||||
|
||||
/* remove task on the tick list because task is waken up */
|
||||
tick_list_rm(task);
|
||||
|
||||
task->blk_state = BLK_FINISH;
|
||||
task->blk_obj = NULL;
|
||||
}
|
||||
|
||||
void pend_to_blk_obj(blk_obj_t *blk_obj, ktask_t *task, tick_t timeout)
|
||||
{
|
||||
/* task need to remember which object is blocked on */
|
||||
task->blk_obj = blk_obj;
|
||||
|
||||
if (timeout != RHINO_WAIT_FOREVER) {
|
||||
tick_list_insert(task, timeout);
|
||||
}
|
||||
|
||||
task->task_state = K_PEND;
|
||||
|
||||
/* remove from the ready list */
|
||||
ready_list_rm(&g_ready_queue, task);
|
||||
|
||||
if (blk_obj->blk_policy == BLK_POLICY_FIFO) {
|
||||
/* add to the end of blocked objet list */
|
||||
klist_insert(&blk_obj->blk_list, &task->task_list);
|
||||
} else {
|
||||
/* add to the prio sorted block list */
|
||||
pend_list_add(&blk_obj->blk_list, task);
|
||||
}
|
||||
}
|
||||
|
||||
void pend_task_rm(ktask_t *task)
|
||||
{
|
||||
switch (task->task_state) {
|
||||
case K_PEND:
|
||||
/* remove task on the block list because task is waken up */
|
||||
klist_rm(&task->task_list);
|
||||
/*add to the ready list again*/
|
||||
ready_list_add(&g_ready_queue, task);
|
||||
task->task_state = K_RDY;
|
||||
break;
|
||||
case K_PEND_SUSPENDED:
|
||||
/* remove task on the block list because task is waken up */
|
||||
klist_rm(&task->task_list);
|
||||
task->task_state = K_SUSPENDED;
|
||||
break;
|
||||
default:
|
||||
k_err_proc(RHINO_SYS_FATAL_ERR);
|
||||
break;
|
||||
}
|
||||
|
||||
/* remove task on the tick list because task is waken up */
|
||||
tick_list_rm(task);
|
||||
task->blk_state = BLK_DEL;
|
||||
|
||||
/* task is nothing blocked on so reset it to NULL */
|
||||
task->blk_obj = NULL;
|
||||
}
|
||||
|
||||
void pend_list_reorder(ktask_t *task)
|
||||
{
|
||||
if (task->blk_obj->blk_policy == BLK_POLICY_PRI) {
|
||||
/* remove it first and add it again in prio sorted list */
|
||||
klist_rm(&task->task_list);
|
||||
pend_list_add(&task->blk_obj->blk_list, task);
|
||||
}
|
||||
}
|
||||
|
||||
kstat_t pend_state_end_proc(ktask_t *task)
|
||||
{
|
||||
kstat_t status;
|
||||
|
||||
switch (task->blk_state) {
|
||||
case BLK_FINISH:
|
||||
status = RHINO_SUCCESS;
|
||||
break;
|
||||
case BLK_ABORT:
|
||||
status = RHINO_BLK_ABORT;
|
||||
break;
|
||||
case BLK_TIMEOUT:
|
||||
status = RHINO_BLK_TIMEOUT;
|
||||
break;
|
||||
case BLK_DEL:
|
||||
status = RHINO_BLK_DEL;
|
||||
break;
|
||||
default:
|
||||
k_err_proc(RHINO_BLK_INV_STATE);
|
||||
status = RHINO_BLK_INV_STATE;
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
409
Living_SDK/kernel/rhino/core/k_queue.c
Executable file
409
Living_SDK/kernel/rhino/core/k_queue.c
Executable file
|
|
@ -0,0 +1,409 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
|
||||
#if (RHINO_CONFIG_QUEUE > 0)
|
||||
RHINO_INLINE void task_msg_recv(ktask_t *task, void *msg)
|
||||
{
|
||||
task->msg = msg;
|
||||
pend_task_wakeup(task);
|
||||
}
|
||||
|
||||
static kstat_t queue_create(kqueue_t *queue, const name_t *name, void **start,
|
||||
size_t msg_num, uint8_t mm_alloc_flag)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
NULL_PARA_CHK(queue);
|
||||
NULL_PARA_CHK(start);
|
||||
NULL_PARA_CHK(name);
|
||||
|
||||
if (msg_num == 0u) {
|
||||
return RHINO_INV_PARAM;
|
||||
}
|
||||
|
||||
/* init the queue blocked list */
|
||||
klist_init(&queue->blk_obj.blk_list);
|
||||
|
||||
queue->blk_obj.name = name;
|
||||
queue->blk_obj.blk_policy = BLK_POLICY_PRI;
|
||||
queue->msg_q.queue_start = start;
|
||||
|
||||
ringbuf_init(&queue->ringbuf, (void *)start, msg_num * sizeof(void *),
|
||||
RINGBUF_TYPE_FIX, sizeof(void *));
|
||||
|
||||
queue->msg_q.size = msg_num;
|
||||
queue->msg_q.cur_num = 0u;
|
||||
queue->msg_q.peak_num = 0u;
|
||||
queue->mm_alloc_flag = mm_alloc_flag;
|
||||
|
||||
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
|
||||
RHINO_CRITICAL_ENTER();
|
||||
klist_insert(&(g_kobj_list.queue_head), &queue->queue_item);
|
||||
RHINO_CRITICAL_EXIT();
|
||||
#endif
|
||||
|
||||
queue->blk_obj.obj_type = RHINO_QUEUE_OBJ_TYPE;
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
kstat_t krhino_queue_create(kqueue_t *queue, const name_t *name, void **start,
|
||||
size_t msg_num)
|
||||
{
|
||||
return queue_create(queue, name, start, msg_num, K_OBJ_STATIC_ALLOC);
|
||||
}
|
||||
|
||||
kstat_t krhino_queue_del(kqueue_t *queue)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
klist_t *blk_list_head;
|
||||
|
||||
NULL_PARA_CHK(queue);
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
|
||||
INTRPT_NESTED_LEVEL_CHK();
|
||||
|
||||
if (queue->blk_obj.obj_type != RHINO_QUEUE_OBJ_TYPE) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_KOBJ_TYPE_ERR;
|
||||
}
|
||||
|
||||
if (queue->mm_alloc_flag != K_OBJ_STATIC_ALLOC) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_KOBJ_DEL_ERR;
|
||||
}
|
||||
|
||||
blk_list_head = &queue->blk_obj.blk_list;
|
||||
|
||||
queue->blk_obj.obj_type = RHINO_OBJ_TYPE_NONE;
|
||||
|
||||
/* all task blocked on this queue is waken up */
|
||||
while (!is_klist_empty(blk_list_head)) {
|
||||
pend_task_rm(krhino_list_entry(blk_list_head->next, ktask_t, task_list));
|
||||
}
|
||||
|
||||
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
|
||||
klist_rm(&queue->queue_item);
|
||||
#endif
|
||||
|
||||
ringbuf_reset(&queue->ringbuf);
|
||||
|
||||
RHINO_CRITICAL_EXIT_SCHED();
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
#if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0)
|
||||
kstat_t krhino_queue_dyn_create(kqueue_t **queue, const name_t *name,
|
||||
size_t msg_num)
|
||||
{
|
||||
kstat_t stat;
|
||||
kqueue_t *queue_obj;
|
||||
void *msg_start;
|
||||
|
||||
NULL_PARA_CHK(queue);
|
||||
|
||||
queue_obj = krhino_mm_alloc(sizeof(kqueue_t));
|
||||
if (queue_obj == NULL) {
|
||||
return RHINO_NO_MEM;
|
||||
}
|
||||
|
||||
msg_start = krhino_mm_alloc(msg_num * sizeof(void *));
|
||||
if (msg_start == NULL) {
|
||||
krhino_mm_free(queue_obj);
|
||||
return RHINO_NO_MEM;
|
||||
}
|
||||
|
||||
stat = queue_create(queue_obj, name, (void **)msg_start, msg_num,
|
||||
K_OBJ_DYN_ALLOC);
|
||||
if (stat != RHINO_SUCCESS) {
|
||||
krhino_mm_free(msg_start);
|
||||
krhino_mm_free(queue_obj);
|
||||
return stat;
|
||||
}
|
||||
|
||||
*queue = queue_obj;
|
||||
|
||||
return stat;
|
||||
}
|
||||
|
||||
kstat_t krhino_queue_dyn_del(kqueue_t *queue)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
klist_t *blk_list_head;
|
||||
|
||||
NULL_PARA_CHK(queue);
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
|
||||
INTRPT_NESTED_LEVEL_CHK();
|
||||
|
||||
if (queue->blk_obj.obj_type != RHINO_QUEUE_OBJ_TYPE) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_KOBJ_TYPE_ERR;
|
||||
}
|
||||
|
||||
if (queue->mm_alloc_flag != K_OBJ_DYN_ALLOC) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_KOBJ_DEL_ERR;
|
||||
}
|
||||
|
||||
blk_list_head = &queue->blk_obj.blk_list;
|
||||
|
||||
queue->blk_obj.obj_type = RHINO_OBJ_TYPE_NONE;
|
||||
|
||||
/* all task blocked on this queue is waken up */
|
||||
while (!is_klist_empty(blk_list_head)) {
|
||||
pend_task_rm(krhino_list_entry(blk_list_head->next, ktask_t, task_list));
|
||||
}
|
||||
|
||||
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
|
||||
klist_rm(&queue->queue_item);
|
||||
#endif
|
||||
|
||||
ringbuf_reset(&queue->ringbuf);
|
||||
|
||||
RHINO_CRITICAL_EXIT_SCHED();
|
||||
|
||||
krhino_mm_free(queue->msg_q.queue_start);
|
||||
krhino_mm_free(queue);
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
static kstat_t msg_send(kqueue_t *p_q, void *p_void, uint8_t opt_wake_all)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
klist_t *blk_list_head;
|
||||
|
||||
NULL_PARA_CHK(p_q);
|
||||
|
||||
/* this is only needed when system zero interrupt feature is enabled */
|
||||
#if (RHINO_CONFIG_INTRPT_GUARD > 0)
|
||||
soc_intrpt_guard();
|
||||
#endif
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
|
||||
if (p_q->blk_obj.obj_type != RHINO_QUEUE_OBJ_TYPE) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_KOBJ_TYPE_ERR;
|
||||
}
|
||||
|
||||
if (p_q->msg_q.cur_num >= p_q->msg_q.size) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_QUEUE_FULL;
|
||||
}
|
||||
|
||||
blk_list_head = &p_q->blk_obj.blk_list;
|
||||
|
||||
/* queue is not full here, if there is no blocked receive task */
|
||||
if (is_klist_empty(blk_list_head)) {
|
||||
p_q->msg_q.cur_num++;
|
||||
|
||||
/* update peak_num for debug */
|
||||
if (p_q->msg_q.cur_num > p_q->msg_q.peak_num) {
|
||||
p_q->msg_q.peak_num = p_q->msg_q.cur_num;
|
||||
}
|
||||
|
||||
ringbuf_push(&p_q->ringbuf, &p_void, sizeof(void *));
|
||||
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
/* wake all the task blocked on this queue */
|
||||
if (opt_wake_all) {
|
||||
while (!is_klist_empty(blk_list_head)) {
|
||||
task_msg_recv(krhino_list_entry(blk_list_head->next, ktask_t, task_list),
|
||||
p_void);
|
||||
}
|
||||
} else {
|
||||
task_msg_recv(krhino_list_entry(blk_list_head->next, ktask_t, task_list),
|
||||
p_void);
|
||||
}
|
||||
|
||||
RHINO_CRITICAL_EXIT_SCHED();
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
kstat_t krhino_queue_back_send(kqueue_t *queue, void *msg)
|
||||
{
|
||||
return msg_send(queue, msg, WAKE_ONE_TASK);
|
||||
}
|
||||
|
||||
kstat_t krhino_queue_all_send(kqueue_t *queue, void *msg)
|
||||
{
|
||||
return msg_send(queue, msg, WAKE_ALL_TASK);
|
||||
}
|
||||
|
||||
kstat_t krhino_queue_recv(kqueue_t *queue, tick_t ticks, void **msg)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
kstat_t ret;
|
||||
uint8_t cur_cpu_num;
|
||||
|
||||
NULL_PARA_CHK(queue);
|
||||
NULL_PARA_CHK(msg);
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
|
||||
cur_cpu_num = cpu_cur_get();
|
||||
|
||||
if ((g_intrpt_nested_level[cur_cpu_num] > 0u) && (ticks != RHINO_NO_WAIT)) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_NOT_CALLED_BY_INTRPT;
|
||||
}
|
||||
|
||||
if (queue->blk_obj.obj_type != RHINO_QUEUE_OBJ_TYPE) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_KOBJ_TYPE_ERR;
|
||||
}
|
||||
|
||||
/* if queue has msgs, just receive it */
|
||||
if (queue->msg_q.cur_num > 0u) {
|
||||
|
||||
ringbuf_pop(&queue->ringbuf, msg, NULL);
|
||||
|
||||
queue->msg_q.cur_num--;
|
||||
|
||||
RHINO_CRITICAL_EXIT();
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
if (ticks == RHINO_NO_WAIT) {
|
||||
*msg = NULL;
|
||||
RHINO_CRITICAL_EXIT();
|
||||
|
||||
return RHINO_NO_PEND_WAIT;
|
||||
}
|
||||
|
||||
/* if system is locked, block operation is not allowed */
|
||||
if (g_sched_lock[cur_cpu_num] > 0u) {
|
||||
*msg = NULL;
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_SCHED_DISABLE;
|
||||
}
|
||||
|
||||
pend_to_blk_obj((blk_obj_t *)queue, g_active_task[cur_cpu_num], ticks);
|
||||
|
||||
RHINO_CRITICAL_EXIT_SCHED();
|
||||
|
||||
RHINO_CPU_INTRPT_DISABLE();
|
||||
|
||||
cur_cpu_num = cpu_cur_get();
|
||||
|
||||
ret = pend_state_end_proc(g_active_task[cur_cpu_num]);
|
||||
|
||||
switch (ret) {
|
||||
case RHINO_SUCCESS:
|
||||
*msg = g_active_task[cur_cpu_num]->msg;
|
||||
break;
|
||||
default:
|
||||
*msg = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
RHINO_CPU_INTRPT_ENABLE();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
kstat_t krhino_queue_is_full(kqueue_t *queue)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
kstat_t ret;
|
||||
|
||||
NULL_PARA_CHK(queue);
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
|
||||
if (queue->blk_obj.obj_type != RHINO_QUEUE_OBJ_TYPE) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_KOBJ_TYPE_ERR;
|
||||
}
|
||||
|
||||
if (queue->msg_q.cur_num >= queue->msg_q.size) {
|
||||
ret = RHINO_QUEUE_FULL;
|
||||
} else {
|
||||
ret = RHINO_QUEUE_NOT_FULL;
|
||||
}
|
||||
|
||||
RHINO_CRITICAL_EXIT();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
kstat_t krhino_queue_flush(kqueue_t *queue)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
NULL_PARA_CHK(queue);
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
|
||||
INTRPT_NESTED_LEVEL_CHK();
|
||||
|
||||
if (queue->blk_obj.obj_type != RHINO_QUEUE_OBJ_TYPE) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_KOBJ_TYPE_ERR;
|
||||
}
|
||||
|
||||
queue->msg_q.cur_num = 0u;
|
||||
ringbuf_reset(&queue->ringbuf);
|
||||
|
||||
RHINO_CRITICAL_EXIT();
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
kstat_t krhino_queue_info_get(kqueue_t *queue, msg_info_t *info)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
klist_t *blk_list_head;
|
||||
|
||||
if (queue == NULL) {
|
||||
return RHINO_NULL_PTR;
|
||||
}
|
||||
|
||||
if (info == NULL) {
|
||||
return RHINO_NULL_PTR;
|
||||
}
|
||||
|
||||
NULL_PARA_CHK(queue);
|
||||
NULL_PARA_CHK(info);
|
||||
|
||||
RHINO_CPU_INTRPT_DISABLE();
|
||||
|
||||
if (queue->blk_obj.obj_type != RHINO_QUEUE_OBJ_TYPE) {
|
||||
RHINO_CPU_INTRPT_ENABLE();
|
||||
return RHINO_KOBJ_TYPE_ERR;
|
||||
}
|
||||
|
||||
blk_list_head = &queue->blk_obj.blk_list;
|
||||
|
||||
info->msg_q.peak_num = queue->msg_q.peak_num;
|
||||
info->msg_q.cur_num = queue->msg_q.cur_num;
|
||||
info->msg_q.queue_start = queue->msg_q.queue_start;
|
||||
info->msg_q.size = queue->msg_q.size;
|
||||
info->pend_entry = blk_list_head->next;
|
||||
|
||||
RHINO_CPU_INTRPT_ENABLE();
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
367
Living_SDK/kernel/rhino/core/k_ringbuf.c
Executable file
367
Living_SDK/kernel/rhino/core/k_ringbuf.c
Executable file
|
|
@ -0,0 +1,367 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
|
||||
kstat_t ringbuf_init(k_ringbuf_t *p_ringbuf, void *buf, size_t len, size_t type,
|
||||
size_t block_size)
|
||||
{
|
||||
p_ringbuf->type = type;
|
||||
p_ringbuf->buf = buf;
|
||||
p_ringbuf->end = (uint8_t *)buf + len;
|
||||
p_ringbuf->blk_size = block_size;
|
||||
|
||||
ringbuf_reset(p_ringbuf);
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
|
||||
}
|
||||
static size_t ringbuf_headlen_compress(size_t head_len, uint8_t *cmp_buf)
|
||||
{
|
||||
size_t len_bytes = 0;
|
||||
uint8_t *p_len = NULL;
|
||||
uint32_t be_len = 0;
|
||||
|
||||
be_len = krhino_ntohl(head_len);
|
||||
p_len = (uint8_t *)&be_len;
|
||||
len_bytes = COMPRESS_LEN(head_len);
|
||||
|
||||
if (len_bytes == 1) {
|
||||
cmp_buf[0] = RINGBUF_LEN_1BYTE_MAXVALUE & p_len[3];
|
||||
} else if (len_bytes == 2) {
|
||||
cmp_buf[0] = RINGBUF_LEN_VLE_2BYTES | p_len[2];
|
||||
cmp_buf[1] = p_len[3];
|
||||
} else if (len_bytes == 3) {
|
||||
cmp_buf[0] = RINGBUF_LEN_VLE_3BYTES | p_len[1];
|
||||
cmp_buf[1] = p_len[2];
|
||||
cmp_buf[2] = p_len[3];
|
||||
}
|
||||
|
||||
return len_bytes;
|
||||
}
|
||||
|
||||
static size_t ringbuf_headlen_decompress(size_t buf_len, uint8_t *cmp_buf)
|
||||
{
|
||||
size_t data_len = 0;
|
||||
uint32_t be_len = 0;
|
||||
uint8_t *len_buf = (uint8_t *)&be_len;
|
||||
|
||||
memcpy(&len_buf[sizeof(uint32_t) - buf_len], cmp_buf, buf_len);
|
||||
|
||||
if (buf_len > 1) {
|
||||
len_buf[sizeof(uint32_t) - buf_len] &= RINGBUF_LEN_MASK_CLEAN_TWOBIT;
|
||||
}
|
||||
|
||||
data_len = krhino_ntohl(be_len);
|
||||
|
||||
return data_len;
|
||||
}
|
||||
|
||||
kstat_t ringbuf_push(k_ringbuf_t *p_ringbuf, void *data, size_t len)
|
||||
{
|
||||
size_t len_bytes = 0;
|
||||
size_t split_len = 0;
|
||||
uint8_t c_len[RINGBUF_LEN_MAX_SIZE] = {0};
|
||||
|
||||
if (ringbuf_is_full(p_ringbuf)) {
|
||||
return RHINO_RINGBUF_FULL;
|
||||
}
|
||||
|
||||
if (p_ringbuf->type == RINGBUF_TYPE_FIX) {
|
||||
if (p_ringbuf->tail == p_ringbuf->end) {
|
||||
p_ringbuf->tail = p_ringbuf->buf;
|
||||
}
|
||||
|
||||
memcpy(p_ringbuf->tail, data, p_ringbuf->blk_size);
|
||||
p_ringbuf->tail += p_ringbuf->blk_size;
|
||||
p_ringbuf->freesize -= p_ringbuf->blk_size;
|
||||
} else {
|
||||
len_bytes = ringbuf_headlen_compress(len, c_len);
|
||||
if (len_bytes == 0 || len_bytes > RINGBUF_LEN_MAX_SIZE ) {
|
||||
return RHINO_INV_PARAM;
|
||||
}
|
||||
|
||||
/* for dynamic length ringbuf */
|
||||
if (p_ringbuf->freesize < len_bytes + len ) {
|
||||
return RHINO_RINGBUF_FULL;
|
||||
}
|
||||
|
||||
if (p_ringbuf->tail == p_ringbuf->end) {
|
||||
p_ringbuf->tail = p_ringbuf->buf;
|
||||
}
|
||||
|
||||
/* copy length data to buffer */
|
||||
if (p_ringbuf->tail >= p_ringbuf->head &&
|
||||
(split_len = p_ringbuf->end - p_ringbuf->tail) < len_bytes && split_len > 0) {
|
||||
memcpy(p_ringbuf->tail, &c_len[0], split_len);
|
||||
len_bytes -= split_len;
|
||||
p_ringbuf->tail = p_ringbuf->buf;
|
||||
p_ringbuf->freesize -= split_len;
|
||||
} else {
|
||||
split_len = 0;
|
||||
}
|
||||
|
||||
if (len_bytes > 0) {
|
||||
memcpy(p_ringbuf->tail, &c_len[split_len], len_bytes);
|
||||
p_ringbuf->freesize -= len_bytes;
|
||||
p_ringbuf->tail += len_bytes;
|
||||
}
|
||||
|
||||
/* copy data to ringbuf, if break by buffer end, split data and copy to buffer head*/
|
||||
split_len = 0;
|
||||
|
||||
if (p_ringbuf->tail == p_ringbuf->end) {
|
||||
p_ringbuf->tail = p_ringbuf->buf;
|
||||
}
|
||||
|
||||
if (p_ringbuf->tail >= p_ringbuf->head &&
|
||||
((split_len = p_ringbuf->end - p_ringbuf->tail) < len) &&
|
||||
split_len > 0) {
|
||||
memcpy(p_ringbuf->tail, data, split_len);
|
||||
data = (uint8_t *)data + split_len;
|
||||
len -= split_len;
|
||||
p_ringbuf->tail = p_ringbuf->buf;
|
||||
p_ringbuf->freesize -= split_len;
|
||||
}
|
||||
|
||||
memcpy(p_ringbuf->tail, data, len);
|
||||
p_ringbuf->tail += len;
|
||||
p_ringbuf->freesize -= len;
|
||||
}
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
kstat_t ringbuf_pop(k_ringbuf_t *p_ringbuf, void *pdata, size_t *plen)
|
||||
{
|
||||
size_t split_len = 0;
|
||||
uint8_t *data = pdata;
|
||||
size_t len = 0;
|
||||
uint8_t c_len[RINGBUF_LEN_MAX_SIZE] = {0};
|
||||
size_t len_bytes = 0;
|
||||
|
||||
if (ringbuf_is_empty(p_ringbuf)) {
|
||||
return RHINO_RINGBUF_EMPTY;
|
||||
}
|
||||
|
||||
if (p_ringbuf->type == RINGBUF_TYPE_FIX) {
|
||||
if (p_ringbuf->head == p_ringbuf->end) {
|
||||
p_ringbuf->head = p_ringbuf->buf;
|
||||
}
|
||||
|
||||
memcpy(pdata, p_ringbuf->head, p_ringbuf->blk_size);
|
||||
p_ringbuf->head += p_ringbuf->blk_size;
|
||||
p_ringbuf->freesize += p_ringbuf->blk_size;
|
||||
|
||||
if (plen != NULL) {
|
||||
*plen = p_ringbuf->blk_size;
|
||||
}
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
} else {
|
||||
if (p_ringbuf->head == p_ringbuf->end) {
|
||||
p_ringbuf->head = p_ringbuf->buf;
|
||||
}
|
||||
|
||||
/*decode length */
|
||||
if ((*p_ringbuf->head & RINGBUF_LEN_MASK_ONEBIT) == 0 ) {
|
||||
/*length use one byte*/
|
||||
len_bytes = 1;
|
||||
} else if ((*p_ringbuf->head & RINGBUF_LEN_MASK_TWOBIT) ==
|
||||
RINGBUF_LEN_VLE_2BYTES) {
|
||||
/*length use 2 bytes*/
|
||||
len_bytes = 2;
|
||||
} else if ((*p_ringbuf->head & RINGBUF_LEN_MASK_TWOBIT) ==
|
||||
RINGBUF_LEN_VLE_3BYTES) {
|
||||
/*length use 3 bytes*/
|
||||
len_bytes = 3;
|
||||
} else {
|
||||
return RHINO_INV_PARAM;
|
||||
}
|
||||
|
||||
|
||||
if (((split_len = p_ringbuf->end - p_ringbuf->head) < len_bytes) &&
|
||||
split_len > 0) {
|
||||
|
||||
memcpy(&c_len[0], p_ringbuf->head, split_len);
|
||||
|
||||
p_ringbuf->head = p_ringbuf->buf;
|
||||
p_ringbuf->freesize += split_len;
|
||||
} else {
|
||||
split_len = 0;
|
||||
}
|
||||
|
||||
if (len_bytes - split_len > 0) {
|
||||
memcpy(&c_len[split_len], p_ringbuf->head, (len_bytes - split_len));
|
||||
p_ringbuf->head += (len_bytes - split_len);
|
||||
p_ringbuf->freesize += (len_bytes - split_len);
|
||||
}
|
||||
|
||||
*plen = len = ringbuf_headlen_decompress(len_bytes, c_len);
|
||||
|
||||
if (p_ringbuf->head == p_ringbuf->end) {
|
||||
p_ringbuf->head = p_ringbuf->buf;
|
||||
}
|
||||
|
||||
if (p_ringbuf->head > p_ringbuf->tail &&
|
||||
(split_len = p_ringbuf->end - p_ringbuf->head) < len) {
|
||||
memcpy(pdata, p_ringbuf->head, split_len);
|
||||
data = (uint8_t *)pdata + split_len;
|
||||
len -= split_len;
|
||||
p_ringbuf->head = p_ringbuf->buf;
|
||||
p_ringbuf->freesize += split_len;
|
||||
}
|
||||
|
||||
memcpy(data, p_ringbuf->head, len);
|
||||
p_ringbuf->head += len;
|
||||
p_ringbuf->freesize += len;
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t ringbuf_is_full(k_ringbuf_t *p_ringbuf)
|
||||
{
|
||||
if (p_ringbuf->type == RINGBUF_TYPE_DYN && p_ringbuf->freesize < 2) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (p_ringbuf->type == RINGBUF_TYPE_FIX &&
|
||||
p_ringbuf->freesize < p_ringbuf->blk_size) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t ringbuf_is_empty(k_ringbuf_t *p_ringbuf)
|
||||
{
|
||||
if (p_ringbuf->freesize == (size_t)(p_ringbuf->end - p_ringbuf->buf)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*external api*/
|
||||
|
||||
kstat_t ringbuf_reset(k_ringbuf_t *p_ringbuf)
|
||||
{
|
||||
p_ringbuf->head = p_ringbuf->buf;
|
||||
p_ringbuf->tail = p_ringbuf->buf;
|
||||
p_ringbuf->freesize = p_ringbuf->end - p_ringbuf->buf;
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
#if (RHINO_CONFIG_RINGBUF_VENDOR > 0)
|
||||
|
||||
kstat_t krhino_ringbuf_reset(k_ringbuf_t *p_ringbuf)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
kstat_t err;
|
||||
|
||||
NULL_PARA_CHK(p_ringbuf);
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
err = ringbuf_reset(p_ringbuf);
|
||||
RHINO_CRITICAL_EXIT();
|
||||
|
||||
return err;
|
||||
}
|
||||
kstat_t krhino_ringbuf_init(k_ringbuf_t *p_ringbuf, void *buf, size_t len,
|
||||
size_t type, size_t block_size)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
kstat_t err;
|
||||
|
||||
NULL_PARA_CHK(p_ringbuf);
|
||||
NULL_PARA_CHK(buf);
|
||||
|
||||
if (len == 0 || (type != RINGBUF_TYPE_DYN && type != RINGBUF_TYPE_FIX)) {
|
||||
return RHINO_INV_PARAM;
|
||||
}
|
||||
|
||||
if (type == RINGBUF_TYPE_FIX) {
|
||||
if (len == 0 || block_size == 0 || len % block_size) {
|
||||
return RHINO_INV_PARAM;
|
||||
}
|
||||
}
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
err = ringbuf_init(p_ringbuf, buf, len, type, block_size);
|
||||
RHINO_CRITICAL_EXIT();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
kstat_t krhino_ringbuf_push(k_ringbuf_t *p_ringbuf, void *data, size_t len)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
kstat_t err;
|
||||
|
||||
NULL_PARA_CHK(p_ringbuf);
|
||||
NULL_PARA_CHK(data);
|
||||
|
||||
if (len <= 0 || len > RINGBUF_LEN_3BYTES_MAXVALUE ||
|
||||
(p_ringbuf->type == RINGBUF_TYPE_FIX && len != p_ringbuf->blk_size) ) {
|
||||
|
||||
return RHINO_INV_PARAM;
|
||||
}
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
err = ringbuf_push(p_ringbuf, data, len);
|
||||
RHINO_CRITICAL_EXIT();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
kstat_t krhino_ringbuf_pop(k_ringbuf_t *p_ringbuf, void *pdata, size_t *plen)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
kstat_t err;
|
||||
|
||||
NULL_PARA_CHK(p_ringbuf);
|
||||
NULL_PARA_CHK(pdata);
|
||||
|
||||
if (p_ringbuf->type == RINGBUF_TYPE_DYN && plen == NULL) {
|
||||
return RHINO_INV_PARAM;
|
||||
}
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
err = ringbuf_pop(p_ringbuf, pdata, plen);
|
||||
RHINO_CRITICAL_EXIT();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
uint8_t krhino_ringbuf_is_empty(k_ringbuf_t *p_ringbuf)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
uint8_t empty;
|
||||
|
||||
NULL_PARA_CHK(p_ringbuf);
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
empty = ringbuf_is_empty(p_ringbuf);
|
||||
RHINO_CRITICAL_EXIT();
|
||||
|
||||
return empty;
|
||||
}
|
||||
|
||||
uint8_t krhino_ringbuf_is_full(k_ringbuf_t *p_ringbuf)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
uint8_t full;
|
||||
|
||||
NULL_PARA_CHK(p_ringbuf);
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
full = ringbuf_is_full(p_ringbuf);
|
||||
RHINO_CRITICAL_EXIT();
|
||||
|
||||
return full;
|
||||
}
|
||||
#endif
|
||||
|
||||
487
Living_SDK/kernel/rhino/core/k_sched.c
Executable file
487
Living_SDK/kernel/rhino/core/k_sched.c
Executable file
|
|
@ -0,0 +1,487 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
|
||||
#if (RHINO_CONFIG_DISABLE_SCHED_STATS > 0)
|
||||
static void sched_disable_measure_start(void)
|
||||
{
|
||||
/* start measure system lock time */
|
||||
if (g_sched_lock[cpu_cur_get()] == 0u) {
|
||||
g_sched_disable_time_start = HR_COUNT_GET();
|
||||
}
|
||||
}
|
||||
|
||||
static void sched_disable_measure_stop(void)
|
||||
{
|
||||
hr_timer_t diff;
|
||||
|
||||
/* stop measure system lock time, g_sched_lock is always zero here */
|
||||
diff = HR_COUNT_GET() - g_sched_disable_time_start;
|
||||
|
||||
if (g_sched_disable_max_time < diff) {
|
||||
g_sched_disable_max_time = diff;
|
||||
}
|
||||
|
||||
if (g_cur_sched_disable_max_time < diff) {
|
||||
g_cur_sched_disable_max_time = diff;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
kstat_t krhino_sched_disable(void)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
|
||||
INTRPT_NESTED_LEVEL_CHK();
|
||||
|
||||
if (g_sched_lock[cpu_cur_get()] >= SCHED_MAX_LOCK_COUNT) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_SCHED_LOCK_COUNT_OVF;
|
||||
}
|
||||
|
||||
#if (RHINO_CONFIG_DISABLE_SCHED_STATS > 0)
|
||||
sched_disable_measure_start();
|
||||
#endif
|
||||
|
||||
g_sched_lock[cpu_cur_get()]++;
|
||||
|
||||
RHINO_CRITICAL_EXIT();
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
kstat_t krhino_sched_enable(void)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
|
||||
INTRPT_NESTED_LEVEL_CHK();
|
||||
|
||||
if (g_sched_lock[cpu_cur_get()] == 0u) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_SCHED_ALREADY_ENABLED;
|
||||
}
|
||||
|
||||
g_sched_lock[cpu_cur_get()]--;
|
||||
|
||||
if (g_sched_lock[cpu_cur_get()] > 0u) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_SCHED_DISABLE;
|
||||
}
|
||||
|
||||
#if (RHINO_CONFIG_DISABLE_SCHED_STATS > 0)
|
||||
sched_disable_measure_stop();
|
||||
#endif
|
||||
|
||||
RHINO_CRITICAL_EXIT_SCHED();
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
#if (RHINO_CONFIG_CPU_NUM > 1)
|
||||
void core_sched(void)
|
||||
{
|
||||
uint8_t cur_cpu_num;
|
||||
|
||||
cur_cpu_num = cpu_cur_get();
|
||||
|
||||
if (g_intrpt_nested_level[cur_cpu_num] > 0u) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_sched_lock[cur_cpu_num] > 0u) {
|
||||
return;
|
||||
}
|
||||
|
||||
preferred_cpu_ready_task_get(&g_ready_queue, cur_cpu_num);
|
||||
|
||||
/* if preferred task is currently task, then no need to do switch and just return */
|
||||
if (g_preferred_ready_task[cur_cpu_num] == g_active_task[cur_cpu_num]) {
|
||||
return;
|
||||
}
|
||||
|
||||
TRACE_TASK_SWITCH(g_active_task[cur_cpu_num], g_preferred_ready_task[cur_cpu_num]);
|
||||
|
||||
#if (RHINO_CONFIG_USER_HOOK > 0)
|
||||
krhino_task_switch_hook(g_active_task[cur_cpu_num], g_preferred_ready_task[cur_cpu_num]);
|
||||
#endif
|
||||
|
||||
g_active_task[cur_cpu_num]->cur_exc = 0;
|
||||
|
||||
cpu_task_switch();
|
||||
|
||||
}
|
||||
#else
|
||||
void core_sched(void)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
uint8_t cur_cpu_num;
|
||||
|
||||
RHINO_CPU_INTRPT_DISABLE();
|
||||
|
||||
cur_cpu_num = cpu_cur_get();
|
||||
|
||||
if (g_intrpt_nested_level[cur_cpu_num] > 0u) {
|
||||
RHINO_CPU_INTRPT_ENABLE();
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_sched_lock[cur_cpu_num] > 0u) {
|
||||
RHINO_CPU_INTRPT_ENABLE();
|
||||
return;
|
||||
}
|
||||
|
||||
preferred_cpu_ready_task_get(&g_ready_queue, cur_cpu_num);
|
||||
|
||||
/* if preferred task is currently task, then no need to do switch and just return */
|
||||
if (g_preferred_ready_task[cur_cpu_num] == g_active_task[cur_cpu_num]) {
|
||||
RHINO_CPU_INTRPT_ENABLE();
|
||||
return;
|
||||
}
|
||||
|
||||
TRACE_TASK_SWITCH(g_active_task[cur_cpu_num], g_preferred_ready_task[cur_cpu_num]);
|
||||
|
||||
#if (RHINO_CONFIG_USER_HOOK > 0)
|
||||
krhino_task_switch_hook(g_active_task[cur_cpu_num], g_preferred_ready_task[cur_cpu_num]);
|
||||
#endif
|
||||
|
||||
cpu_task_switch();
|
||||
|
||||
RHINO_CPU_INTRPT_ENABLE();
|
||||
}
|
||||
#endif
|
||||
|
||||
void runqueue_init(runqueue_t *rq)
|
||||
{
|
||||
uint8_t prio;
|
||||
|
||||
rq->highest_pri = RHINO_CONFIG_PRI_MAX;
|
||||
|
||||
for (prio = 0; prio < RHINO_CONFIG_PRI_MAX; prio++) {
|
||||
rq->cur_list_item[prio] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
RHINO_INLINE void ready_list_init(runqueue_t *rq, ktask_t *task)
|
||||
{
|
||||
rq->cur_list_item[task->prio] = &task->task_list;
|
||||
klist_init(rq->cur_list_item[task->prio]);
|
||||
krhino_bitmap_set(rq->task_bit_map, task->prio);
|
||||
|
||||
if ((task->prio) < (rq->highest_pri)) {
|
||||
rq->highest_pri = task->prio;
|
||||
}
|
||||
}
|
||||
|
||||
RHINO_INLINE uint8_t is_ready_list_empty(uint8_t prio)
|
||||
{
|
||||
return (g_ready_queue.cur_list_item[prio] == NULL);
|
||||
}
|
||||
|
||||
RHINO_INLINE void _ready_list_add_tail(runqueue_t *rq, ktask_t *task)
|
||||
{
|
||||
if (is_ready_list_empty(task->prio)) {
|
||||
ready_list_init(rq, task);
|
||||
return;
|
||||
}
|
||||
|
||||
klist_insert(rq->cur_list_item[task->prio], &task->task_list);
|
||||
}
|
||||
|
||||
RHINO_INLINE void _ready_list_add_head(runqueue_t *rq, ktask_t *task)
|
||||
{
|
||||
if (is_ready_list_empty(task->prio)) {
|
||||
ready_list_init(rq, task);
|
||||
return;
|
||||
}
|
||||
|
||||
klist_insert(rq->cur_list_item[task->prio], &task->task_list);
|
||||
rq->cur_list_item[task->prio] = &task->task_list;
|
||||
}
|
||||
|
||||
#if (RHINO_CONFIG_CPU_NUM > 1)
|
||||
static void task_sched_to_cpu(runqueue_t *rq, ktask_t *task, uint8_t cur_cpu_num)
|
||||
{
|
||||
uint8_t i;
|
||||
uint8_t low_pri;
|
||||
|
||||
(void)rq;
|
||||
|
||||
if (g_sys_stat == RHINO_RUNNING) {
|
||||
if (task->cpu_binded == 1) {
|
||||
if (task->cpu_num != cur_cpu_num) {
|
||||
if (task->prio <= g_active_task[task->cpu_num]->prio) {
|
||||
cpu_signal(task->cpu_num);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* find the lowest pri */
|
||||
low_pri = g_active_task[0]->prio;
|
||||
for (i = 0; i < RHINO_CONFIG_CPU_NUM - 1; i++) {
|
||||
if (low_pri < g_active_task[i + 1]->prio) {
|
||||
low_pri = g_active_task[i + 1]->prio;
|
||||
}
|
||||
}
|
||||
|
||||
/* which cpu run the lowest pri, just notify it */
|
||||
for (i = 0; i < RHINO_CONFIG_CPU_NUM; i++) {
|
||||
if (low_pri == g_active_task[i]->prio) {
|
||||
if (i != cur_cpu_num) {
|
||||
cpu_signal(i);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ready_list_add_head(runqueue_t *rq, ktask_t *task)
|
||||
{
|
||||
_ready_list_add_head(rq, task);
|
||||
task_sched_to_cpu(rq, task, cpu_cur_get());
|
||||
}
|
||||
|
||||
void ready_list_add_tail(runqueue_t *rq, ktask_t *task)
|
||||
{
|
||||
_ready_list_add_tail(rq, task);
|
||||
task_sched_to_cpu(rq, task, cpu_cur_get());
|
||||
}
|
||||
|
||||
#else
|
||||
void ready_list_add_head(runqueue_t *rq, ktask_t *task)
|
||||
{
|
||||
_ready_list_add_head(rq, task);
|
||||
}
|
||||
|
||||
void ready_list_add_tail(runqueue_t *rq, ktask_t *task)
|
||||
{
|
||||
_ready_list_add_tail(rq, task);
|
||||
}
|
||||
#endif
|
||||
|
||||
void ready_list_add(runqueue_t *rq, ktask_t *task)
|
||||
{
|
||||
/* if task prio is equal current task prio then add to the end */
|
||||
if (task->prio == g_active_task[cpu_cur_get()]->prio) {
|
||||
ready_list_add_tail(rq, task);
|
||||
} else {
|
||||
ready_list_add_head(rq, task);
|
||||
}
|
||||
}
|
||||
|
||||
void ready_list_rm(runqueue_t *rq, ktask_t *task)
|
||||
{
|
||||
int32_t i;
|
||||
uint8_t pri = task->prio;
|
||||
|
||||
/* if the ready list is not only one, we do not need to update the highest prio */
|
||||
if ((rq->cur_list_item[pri]) != (rq->cur_list_item[pri]->next)) {
|
||||
if (rq->cur_list_item[pri] == &task->task_list) {
|
||||
rq->cur_list_item[pri] = rq->cur_list_item[pri]->next;
|
||||
}
|
||||
|
||||
klist_rm(&task->task_list);
|
||||
return;
|
||||
}
|
||||
|
||||
/* only one item,just set cur item ptr to NULL */
|
||||
rq->cur_list_item[pri] = NULL;
|
||||
|
||||
krhino_bitmap_clear(rq->task_bit_map, pri);
|
||||
|
||||
/* if task prio not equal to the highest prio, then we do not need to update the highest prio */
|
||||
/* this condition happens when a current high prio task to suspend a low priotity task */
|
||||
if (pri != rq->highest_pri) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* find the highest ready task */
|
||||
i = krhino_find_first_bit(rq->task_bit_map);
|
||||
|
||||
/* update the next highest prio task */
|
||||
if (i >= 0) {
|
||||
rq->highest_pri = i;
|
||||
} else {
|
||||
k_err_proc(RHINO_SYS_FATAL_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
void ready_list_head_to_tail(runqueue_t *rq, ktask_t *task)
|
||||
{
|
||||
rq->cur_list_item[task->prio] = rq->cur_list_item[task->prio]->next;
|
||||
}
|
||||
|
||||
#if (RHINO_CONFIG_CPU_NUM > 1)
|
||||
void preferred_cpu_ready_task_get(runqueue_t *rq, uint8_t cpu_num)
|
||||
{
|
||||
klist_t *iter;
|
||||
ktask_t *task;
|
||||
uint32_t task_bit_map[NUM_WORDS];
|
||||
klist_t *node;
|
||||
uint8_t flag;
|
||||
uint8_t highest_pri = rq->highest_pri;
|
||||
|
||||
node = rq->cur_list_item[highest_pri];
|
||||
iter = node;
|
||||
memcpy(task_bit_map, rq->task_bit_map, NUM_WORDS * sizeof(uint32_t));
|
||||
|
||||
while (1) {
|
||||
|
||||
task = krhino_list_entry(iter, ktask_t, task_list);
|
||||
|
||||
if (g_active_task[cpu_num] == task) {
|
||||
break;
|
||||
}
|
||||
|
||||
flag = ((task->cur_exc == 0) && (task->cpu_binded == 0))
|
||||
|| ((task->cur_exc == 0) && (task->cpu_binded == 1) && (task->cpu_num == cpu_num));
|
||||
|
||||
if (flag > 0) {
|
||||
task->cpu_num = cpu_num;
|
||||
task->cur_exc = 1;
|
||||
g_preferred_ready_task[cpu_num] = task;
|
||||
break;
|
||||
}
|
||||
|
||||
if (iter->next == rq->cur_list_item[highest_pri]) {
|
||||
task_bit_map[highest_pri >> 5] &= ~(1u << (31u - (highest_pri & 31u)));
|
||||
highest_pri = krhino_find_first_bit(task_bit_map);
|
||||
iter = rq->cur_list_item[highest_pri];
|
||||
} else {
|
||||
iter = iter->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
void preferred_cpu_ready_task_get(runqueue_t *rq, uint8_t cpu_num)
|
||||
{
|
||||
klist_t *node = rq->cur_list_item[rq->highest_pri];
|
||||
/* get the highest prio task object */
|
||||
g_preferred_ready_task[cpu_num] = krhino_list_entry(node, ktask_t, task_list);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_SCHED_RR > 0)
|
||||
|
||||
#if (RHINO_CONFIG_CPU_NUM > 1)
|
||||
|
||||
static void _time_slice_update(ktask_t *task, uint8_t i)
|
||||
{
|
||||
klist_t *head;
|
||||
|
||||
head = g_ready_queue.cur_list_item[task->prio];
|
||||
|
||||
/* if ready list is empty then just return because nothing is to be caculated */
|
||||
if (is_ready_list_empty(task->prio)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (task->sched_policy == KSCHED_FIFO) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* there is only one task on this ready list, so do not need to caculate time slice */
|
||||
/* idle task must satisfy this condition */
|
||||
if (head->next == head) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (task->time_slice > 0u) {
|
||||
task->time_slice--;
|
||||
}
|
||||
|
||||
/* if current active task has time_slice, just return */
|
||||
if (task->time_slice > 0u) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* move current active task to the end of ready list for the same prio */
|
||||
ready_list_head_to_tail(&g_ready_queue, task);
|
||||
|
||||
/* restore the task time slice */
|
||||
task->time_slice = task->time_total;
|
||||
|
||||
if (i != cpu_cur_get()) {
|
||||
cpu_signal(i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void time_slice_update(void)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
uint8_t i;
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
|
||||
for (i = 0; i < RHINO_CONFIG_CPU_NUM; i++) {
|
||||
_time_slice_update(g_active_task[i], i);
|
||||
}
|
||||
|
||||
RHINO_CRITICAL_EXIT();
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
void time_slice_update(void)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
ktask_t *task;
|
||||
klist_t *head;
|
||||
uint8_t task_pri;
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
task_pri = g_active_task[cpu_cur_get()]->prio;
|
||||
|
||||
head = g_ready_queue.cur_list_item[task_pri];
|
||||
|
||||
/* if ready list is empty then just return because nothing is to be caculated */
|
||||
if (is_ready_list_empty(task_pri)) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Always look at the first task on the ready list */
|
||||
task = krhino_list_entry(head, ktask_t, task_list);
|
||||
|
||||
if (task->sched_policy == KSCHED_FIFO) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return;
|
||||
}
|
||||
|
||||
/* there is only one task on this ready list, so do not need to caculate time slice */
|
||||
/* idle task must satisfy this condition */
|
||||
if (head->next == head) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return;
|
||||
}
|
||||
|
||||
if (task->time_slice > 0u) {
|
||||
task->time_slice--;
|
||||
}
|
||||
|
||||
/* if current active task has time_slice, just return */
|
||||
if (task->time_slice > 0u) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return;
|
||||
}
|
||||
|
||||
/* move current active task to the end of ready list for the same prio */
|
||||
ready_list_head_to_tail(&g_ready_queue, task);
|
||||
|
||||
/* restore the task time slice */
|
||||
task->time_slice = task->time_total;
|
||||
|
||||
RHINO_CRITICAL_EXIT();
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
349
Living_SDK/kernel/rhino/core/k_sem.c
Executable file
349
Living_SDK/kernel/rhino/core/k_sem.c
Executable file
|
|
@ -0,0 +1,349 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
|
||||
#if (RHINO_CONFIG_SEM > 0)
|
||||
static kstat_t sem_create(ksem_t *sem, const name_t *name, sem_count_t count,
|
||||
uint8_t mm_alloc_flag)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
NULL_PARA_CHK(sem);
|
||||
NULL_PARA_CHK(name);
|
||||
|
||||
/* init the list */
|
||||
klist_init(&sem->blk_obj.blk_list);
|
||||
|
||||
/* init resource */
|
||||
sem->count = count;
|
||||
sem->peak_count = count;
|
||||
sem->blk_obj.name = name;
|
||||
sem->blk_obj.blk_policy = BLK_POLICY_PRI;
|
||||
sem->mm_alloc_flag = mm_alloc_flag;
|
||||
|
||||
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
|
||||
RHINO_CRITICAL_ENTER();
|
||||
klist_insert(&(g_kobj_list.sem_head), &sem->sem_item);
|
||||
RHINO_CRITICAL_EXIT();
|
||||
#endif
|
||||
|
||||
sem->blk_obj.obj_type = RHINO_SEM_OBJ_TYPE;
|
||||
|
||||
TRACE_SEM_CREATE(krhino_cur_task_get(), sem);
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
kstat_t krhino_sem_create(ksem_t *sem, const name_t *name, sem_count_t count)
|
||||
{
|
||||
return sem_create(sem, name, count, K_OBJ_STATIC_ALLOC);
|
||||
}
|
||||
|
||||
kstat_t krhino_sem_del(ksem_t *sem)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
klist_t *blk_list_head;
|
||||
|
||||
NULL_PARA_CHK(sem);
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
|
||||
INTRPT_NESTED_LEVEL_CHK();
|
||||
|
||||
if (sem->blk_obj.obj_type != RHINO_SEM_OBJ_TYPE) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_KOBJ_TYPE_ERR;
|
||||
}
|
||||
|
||||
if (sem->mm_alloc_flag != K_OBJ_STATIC_ALLOC) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_KOBJ_DEL_ERR;
|
||||
}
|
||||
|
||||
blk_list_head = &sem->blk_obj.blk_list;
|
||||
sem->blk_obj.obj_type = RHINO_OBJ_TYPE_NONE;
|
||||
|
||||
/* all task blocked on this queue is waken up */
|
||||
while (!is_klist_empty(blk_list_head)) {
|
||||
pend_task_rm(krhino_list_entry(blk_list_head->next, ktask_t, task_list));
|
||||
}
|
||||
|
||||
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
|
||||
klist_rm(&sem->sem_item);
|
||||
#endif
|
||||
|
||||
TRACE_SEM_DEL(g_active_task[cpu_cur_get()], sem);
|
||||
RHINO_CRITICAL_EXIT_SCHED();
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
#if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0)
|
||||
kstat_t krhino_sem_dyn_create(ksem_t **sem, const name_t *name,
|
||||
sem_count_t count)
|
||||
{
|
||||
kstat_t stat;
|
||||
ksem_t *sem_obj;
|
||||
|
||||
NULL_PARA_CHK(sem);
|
||||
|
||||
sem_obj = krhino_mm_alloc(sizeof(ksem_t));
|
||||
|
||||
if (sem_obj == NULL) {
|
||||
return RHINO_NO_MEM;
|
||||
}
|
||||
|
||||
stat = sem_create(sem_obj, name, count, K_OBJ_DYN_ALLOC);
|
||||
|
||||
if (stat != RHINO_SUCCESS) {
|
||||
krhino_mm_free(sem_obj);
|
||||
return stat;
|
||||
}
|
||||
|
||||
*sem = sem_obj;
|
||||
|
||||
return stat;
|
||||
}
|
||||
|
||||
kstat_t krhino_sem_dyn_del(ksem_t *sem)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
klist_t *blk_list_head;
|
||||
|
||||
NULL_PARA_CHK(sem);
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
|
||||
INTRPT_NESTED_LEVEL_CHK();
|
||||
|
||||
if (sem->blk_obj.obj_type != RHINO_SEM_OBJ_TYPE) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_KOBJ_TYPE_ERR;
|
||||
}
|
||||
|
||||
if (sem->mm_alloc_flag != K_OBJ_DYN_ALLOC) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_KOBJ_DEL_ERR;
|
||||
}
|
||||
|
||||
blk_list_head = &sem->blk_obj.blk_list;
|
||||
sem->blk_obj.obj_type = RHINO_OBJ_TYPE_NONE;
|
||||
|
||||
/* all task blocked on this queue is waken up */
|
||||
while (!is_klist_empty(blk_list_head)) {
|
||||
pend_task_rm(krhino_list_entry(blk_list_head->next, ktask_t, task_list));
|
||||
}
|
||||
|
||||
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
|
||||
klist_rm(&sem->sem_item);
|
||||
#endif
|
||||
|
||||
TRACE_SEM_DEL(g_active_task[cpu_cur_get()], sem);
|
||||
RHINO_CRITICAL_EXIT_SCHED();
|
||||
|
||||
krhino_mm_free(sem);
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static kstat_t sem_give(ksem_t *sem, uint8_t opt_wake_all)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
uint8_t cur_cpu_num;
|
||||
klist_t *blk_list_head;
|
||||
|
||||
/* this is only needed when system zero interrupt feature is enabled */
|
||||
#if (RHINO_CONFIG_INTRPT_GUARD > 0)
|
||||
soc_intrpt_guard();
|
||||
#endif
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
|
||||
if (sem->blk_obj.obj_type != RHINO_SEM_OBJ_TYPE) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_KOBJ_TYPE_ERR;
|
||||
}
|
||||
|
||||
cur_cpu_num = cpu_cur_get();
|
||||
(void)cur_cpu_num;
|
||||
|
||||
blk_list_head = &sem->blk_obj.blk_list;
|
||||
|
||||
if (is_klist_empty(blk_list_head)) {
|
||||
if (sem->count == (sem_count_t)-1) {
|
||||
|
||||
TRACE_SEM_OVERFLOW(g_active_task[cur_cpu_num], sem);
|
||||
RHINO_CRITICAL_EXIT();
|
||||
|
||||
return RHINO_SEM_OVF;
|
||||
}
|
||||
|
||||
/* increase resource */
|
||||
sem->count++;
|
||||
|
||||
if (sem->count > sem->peak_count) {
|
||||
sem->peak_count = sem->count;
|
||||
}
|
||||
|
||||
TRACE_SEM_CNT_INCREASE(g_active_task[cur_cpu_num], sem);
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
/* wake all the task blocked on this semaphore */
|
||||
if (opt_wake_all) {
|
||||
while (!is_klist_empty(blk_list_head)) {
|
||||
TRACE_SEM_TASK_WAKE(g_active_task[cur_cpu_num], krhino_list_entry(blk_list_head->next,
|
||||
ktask_t, task_list),
|
||||
sem, opt_wake_all);
|
||||
|
||||
pend_task_wakeup(krhino_list_entry(blk_list_head->next, ktask_t, task_list));
|
||||
}
|
||||
|
||||
} else {
|
||||
TRACE_SEM_TASK_WAKE(g_active_task[cur_cpu_num], krhino_list_entry(blk_list_head->next,
|
||||
ktask_t, task_list),
|
||||
sem, opt_wake_all);
|
||||
|
||||
/* wake up the highest prio task block on the semaphore */
|
||||
pend_task_wakeup(krhino_list_entry(blk_list_head->next, ktask_t, task_list));
|
||||
}
|
||||
|
||||
RHINO_CRITICAL_EXIT_SCHED();
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
kstat_t krhino_sem_give(ksem_t *sem)
|
||||
{
|
||||
NULL_PARA_CHK(sem);
|
||||
|
||||
return sem_give(sem, WAKE_ONE_SEM);
|
||||
}
|
||||
|
||||
kstat_t krhino_sem_give_all(ksem_t *sem)
|
||||
{
|
||||
NULL_PARA_CHK(sem);
|
||||
|
||||
return sem_give(sem, WAKE_ALL_SEM);
|
||||
}
|
||||
|
||||
kstat_t krhino_sem_take(ksem_t *sem, tick_t ticks)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
uint8_t cur_cpu_num;
|
||||
kstat_t stat;
|
||||
|
||||
NULL_PARA_CHK(sem);
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
|
||||
INTRPT_NESTED_LEVEL_CHK();
|
||||
|
||||
if (sem->blk_obj.obj_type != RHINO_SEM_OBJ_TYPE) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_KOBJ_TYPE_ERR;
|
||||
}
|
||||
|
||||
cur_cpu_num = cpu_cur_get();
|
||||
|
||||
if (sem->count > 0u) {
|
||||
sem->count--;
|
||||
|
||||
TRACE_SEM_GET_SUCCESS(g_active_task[cur_cpu_num], sem);
|
||||
RHINO_CRITICAL_EXIT();
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
/* can't get semphore, and return immediately if wait_option is RHINO_NO_WAIT */
|
||||
if (ticks == RHINO_NO_WAIT) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_NO_PEND_WAIT;
|
||||
}
|
||||
|
||||
if (g_sched_lock[cur_cpu_num] > 0u) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_SCHED_DISABLE;
|
||||
}
|
||||
|
||||
pend_to_blk_obj((blk_obj_t *)sem, g_active_task[cur_cpu_num], ticks);
|
||||
|
||||
TRACE_SEM_GET_BLK(g_active_task[cur_cpu_num], sem, ticks);
|
||||
|
||||
RHINO_CRITICAL_EXIT_SCHED();
|
||||
|
||||
RHINO_CPU_INTRPT_DISABLE();
|
||||
|
||||
stat = pend_state_end_proc(g_active_task[cpu_cur_get()]);
|
||||
|
||||
RHINO_CPU_INTRPT_ENABLE();
|
||||
|
||||
return stat;
|
||||
}
|
||||
|
||||
kstat_t krhino_sem_count_set(ksem_t *sem, sem_count_t sem_count)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
klist_t *blk_list_head;
|
||||
|
||||
NULL_PARA_CHK(sem);
|
||||
|
||||
blk_list_head = &sem->blk_obj.blk_list;
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
|
||||
INTRPT_NESTED_LEVEL_CHK();
|
||||
|
||||
if (sem->blk_obj.obj_type != RHINO_SEM_OBJ_TYPE) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_KOBJ_TYPE_ERR;
|
||||
}
|
||||
|
||||
/* set new count */
|
||||
if (sem->count > 0u) {
|
||||
sem->count = sem_count;
|
||||
} else {
|
||||
if (is_klist_empty(blk_list_head)) {
|
||||
sem->count = sem_count;
|
||||
} else {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_SEM_TASK_WAITING;
|
||||
}
|
||||
}
|
||||
|
||||
/* update sem peak count if need */
|
||||
if (sem->count > sem->peak_count) {
|
||||
sem->peak_count = sem->count;
|
||||
}
|
||||
|
||||
RHINO_CRITICAL_EXIT();
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
kstat_t krhino_sem_count_get(ksem_t *sem, sem_count_t *count)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
NULL_PARA_CHK(sem);
|
||||
NULL_PARA_CHK(count);
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
*count = sem->count;
|
||||
RHINO_CRITICAL_EXIT();
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
#endif /* RHINO_CONFIG_SEM */
|
||||
|
||||
224
Living_SDK/kernel/rhino/core/k_stats.c
Normal file
224
Living_SDK/kernel/rhino/core/k_stats.c
Normal file
|
|
@ -0,0 +1,224 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
|
||||
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
|
||||
void kobj_list_init(void)
|
||||
{
|
||||
klist_init(&(g_kobj_list.task_head));
|
||||
klist_init(&(g_kobj_list.mutex_head));
|
||||
|
||||
#if (RHINO_CONFIG_MM_BLK > 0)
|
||||
klist_init(&(g_kobj_list.mblkpool_head));
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_SEM > 0)
|
||||
klist_init(&(g_kobj_list.sem_head));
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_QUEUE > 0)
|
||||
klist_init(&(g_kobj_list.queue_head));
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_BUF_QUEUE > 0)
|
||||
klist_init(&(g_kobj_list.buf_queue_head));
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_EVENT_FLAG > 0)
|
||||
klist_init(&(g_kobj_list.event_head));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_TASK_STACK_OVF_CHECK > 0)
|
||||
#if (RHINO_CONFIG_CPU_STACK_DOWN > 0)
|
||||
void krhino_stack_ovf_check(void)
|
||||
{
|
||||
cpu_stack_t *stack_start;
|
||||
|
||||
stack_start = g_active_task[cpu_cur_get()]->task_stack_base;
|
||||
|
||||
if (*stack_start != RHINO_TASK_STACK_OVF_MAGIC) {
|
||||
k_err_proc(RHINO_TASK_STACK_OVF);
|
||||
}
|
||||
|
||||
if ((cpu_stack_t *)(g_active_task[cpu_cur_get()]->task_stack) < stack_start) {
|
||||
k_err_proc(RHINO_TASK_STACK_OVF);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void krhino_stack_ovf_check(void)
|
||||
{
|
||||
cpu_stack_t *stack_start;
|
||||
cpu_stack_t *stack_end;
|
||||
|
||||
stack_start = g_active_task[cpu_cur_get()]->task_stack_base;
|
||||
stack_end = stack_start + g_active_task[cpu_cur_get()]->stack_size;
|
||||
|
||||
if (*(stack_end - 1) != RHINO_TASK_STACK_OVF_MAGIC) {
|
||||
k_err_proc(RHINO_TASK_STACK_OVF);
|
||||
}
|
||||
|
||||
if ((cpu_stack_t *)(g_active_task[cpu_cur_get()]->task_stack) > stack_end) {
|
||||
k_err_proc(RHINO_TASK_STACK_OVF);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_TASK_SCHED_STATS > 0)
|
||||
void krhino_task_sched_stats_reset(void)
|
||||
{
|
||||
lr_timer_t cur_time;
|
||||
|
||||
#if (RHINO_CONFIG_DISABLE_INTRPT_STATS > 0)
|
||||
g_cur_intrpt_disable_max_time = 0;
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_DISABLE_SCHED_STATS > 0)
|
||||
g_cur_sched_disable_max_time = 0;
|
||||
#endif
|
||||
|
||||
/* system first task starting time should be measured otherwise not correct */
|
||||
cur_time = (lr_timer_t)LR_COUNT_GET();
|
||||
g_preferred_ready_task->task_time_start = cur_time;
|
||||
}
|
||||
|
||||
void krhino_task_sched_stats_get(void)
|
||||
{
|
||||
lr_timer_t cur_time;
|
||||
lr_timer_t exec_time;
|
||||
|
||||
#if (RHINO_CONFIG_DISABLE_INTRPT_STATS > 0)
|
||||
hr_timer_t intrpt_disable_time;
|
||||
|
||||
if (g_cur_intrpt_disable_max_time > g_sys_measure_waste) {
|
||||
intrpt_disable_time = g_cur_intrpt_disable_max_time - g_sys_measure_waste;
|
||||
} else {
|
||||
intrpt_disable_time = 0;
|
||||
}
|
||||
|
||||
if (g_active_task[cpu_cur_get()]->task_intrpt_disable_time_max < intrpt_disable_time) {
|
||||
g_active_task[cpu_cur_get()]->task_intrpt_disable_time_max = intrpt_disable_time;
|
||||
}
|
||||
|
||||
g_cur_intrpt_disable_max_time = 0;
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_DISABLE_SCHED_STATS > 0)
|
||||
|
||||
if (g_active_task[cpu_cur_get()]->task_sched_disable_time_max < g_cur_sched_disable_max_time) {
|
||||
g_active_task[cpu_cur_get()]->task_sched_disable_time_max = g_cur_sched_disable_max_time;
|
||||
}
|
||||
|
||||
g_cur_sched_disable_max_time = 0;
|
||||
#endif
|
||||
|
||||
/* Keep track of new task and total system context switch times */
|
||||
g_preferred_ready_task[cpu_cur_get()]->task_ctx_switch_times++;
|
||||
g_sys_ctx_switch_times++;
|
||||
|
||||
cur_time = (lr_timer_t)LR_COUNT_GET();
|
||||
exec_time = cur_time - g_active_task[cpu_cur_get()]->task_time_start;
|
||||
|
||||
g_active_task[cpu_cur_get()]->task_time_total_run += (sys_time_t)exec_time;
|
||||
|
||||
g_preferred_ready_task[cpu_cur_get()]->task_time_start = cur_time;
|
||||
}
|
||||
#endif /* RHINO_CONFIG_TASK_SCHED_STATS */
|
||||
|
||||
#if (RHINO_CONFIG_DISABLE_INTRPT_STATS > 0)
|
||||
void intrpt_disable_measure_start(void)
|
||||
{
|
||||
g_intrpt_disable_times++;
|
||||
|
||||
/* start measure interrupt disable time */
|
||||
if (g_intrpt_disable_times == 1u) {
|
||||
g_intrpt_disable_time_start = HR_COUNT_GET();
|
||||
}
|
||||
}
|
||||
|
||||
void intrpt_disable_measure_stop(void)
|
||||
{
|
||||
hr_timer_t diff;
|
||||
|
||||
g_intrpt_disable_times--;
|
||||
|
||||
if (g_intrpt_disable_times == 0u) {
|
||||
diff = HR_COUNT_GET() - g_intrpt_disable_time_start;
|
||||
|
||||
if (g_intrpt_disable_max_time < diff) {
|
||||
g_intrpt_disable_max_time = diff;
|
||||
}
|
||||
|
||||
if (g_cur_intrpt_disable_max_time < diff) {
|
||||
g_cur_intrpt_disable_max_time = diff;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_HW_COUNT > 0)
|
||||
void krhino_overhead_measure(void)
|
||||
{
|
||||
hr_timer_t diff;
|
||||
hr_timer_t m1;
|
||||
hr_timer_t m2;
|
||||
|
||||
m1 = HR_COUNT_GET();
|
||||
|
||||
HR_COUNT_GET();
|
||||
HR_COUNT_GET();
|
||||
|
||||
m2 = HR_COUNT_GET();
|
||||
|
||||
diff = m2 - m1;
|
||||
|
||||
/* measure time overhead */
|
||||
g_sys_measure_waste = diff;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*it should be called in cpu_stats task*/
|
||||
#if (RHINO_CONFIG_CPU_USAGE_STATS > 0)
|
||||
static void cpu_usage_task_entry(void *arg)
|
||||
{
|
||||
idle_count_t idle_count;
|
||||
|
||||
(void)arg;
|
||||
|
||||
while (1) {
|
||||
idle_count_set(0u);
|
||||
|
||||
krhino_task_sleep(RHINO_CONFIG_TICKS_PER_SECOND / 2);
|
||||
|
||||
idle_count = idle_count_get();
|
||||
|
||||
if (idle_count > g_idle_count_max) {
|
||||
g_idle_count_max = idle_count;
|
||||
}
|
||||
|
||||
if (idle_count < g_idle_count_max) {
|
||||
/* use 64bit for cpu_task_idle_count to avoid overflow quickly */
|
||||
g_cpu_usage = 10000 - (uint32_t)((idle_count * 10000) / g_idle_count_max);
|
||||
}
|
||||
else {
|
||||
g_cpu_usage = 10000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cpu_usage_stats_start(void)
|
||||
{
|
||||
/* create a statistic task to calculate cpu usage */
|
||||
krhino_task_create(&g_cpu_usage_task, "cpu_stats", 0,
|
||||
RHINO_CONFIG_CPU_USAGE_TASK_PRI,
|
||||
0, g_cpu_task_stack, RHINO_CONFIG_CPU_USAGE_TASK_STACK, cpu_usage_task_entry,
|
||||
1);
|
||||
}
|
||||
#endif /* RHINO_CONFIG_CPU_USAGE_STATS */
|
||||
|
||||
239
Living_SDK/kernel/rhino/core/k_sys.c
Executable file
239
Living_SDK/kernel/rhino/core/k_sys.c
Executable file
|
|
@ -0,0 +1,239 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
|
||||
RHINO_INLINE void rhino_stack_check_init(void)
|
||||
{
|
||||
#if (RHINO_CONFIG_INTRPT_STACK_OVF_CHECK > 0)
|
||||
#if (RHINO_CONFIG_CPU_STACK_DOWN > 0)
|
||||
*g_intrpt_stack_bottom = RHINO_INTRPT_STACK_OVF_MAGIC;
|
||||
#else
|
||||
*g_intrpt_stack_top = RHINO_INTRPT_STACK_OVF_MAGIC;
|
||||
#endif
|
||||
#endif /* RHINO_CONFIG_INTRPT_STACK_OVF_CHECK */
|
||||
|
||||
#if (RHINO_CONFIG_STACK_OVF_CHECK_HW != 0)
|
||||
cpu_intrpt_stack_protect();
|
||||
#endif
|
||||
}
|
||||
|
||||
kstat_t krhino_init(void)
|
||||
{
|
||||
g_sys_stat = RHINO_STOPPED;
|
||||
|
||||
#if (RHINO_CONFIG_USER_HOOK > 0)
|
||||
krhino_init_hook();
|
||||
#endif
|
||||
|
||||
runqueue_init(&g_ready_queue);
|
||||
|
||||
tick_list_init();
|
||||
|
||||
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
|
||||
kobj_list_init();
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_MM_TLF > 0)
|
||||
k_mm_init();
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0)
|
||||
klist_init(&g_res_list);
|
||||
krhino_sem_create(&g_res_sem, "res_sem", 0);
|
||||
dyn_mem_proc_task_start();
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_CPU_NUM > 1)
|
||||
for (uint8_t i = 0; i < RHINO_CONFIG_CPU_NUM; i++) {
|
||||
krhino_task_cpu_create(&g_idle_task[i], "idle_task", NULL, RHINO_IDLE_PRI, 0,
|
||||
&g_idle_task_stack[i][0], RHINO_CONFIG_IDLE_TASK_STACK_SIZE,
|
||||
idle_task, i, 1u);
|
||||
}
|
||||
#else
|
||||
krhino_task_create(&g_idle_task[0], "idle_task", NULL, RHINO_IDLE_PRI, 0,
|
||||
&g_idle_task_stack[0][0], RHINO_CONFIG_IDLE_TASK_STACK_SIZE,
|
||||
idle_task, 1u);
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_WORKQUEUE > 0)
|
||||
workqueue_init();
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_TIMER > 0)
|
||||
ktimer_init();
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_CPU_USAGE_STATS > 0)
|
||||
cpu_usage_stats_start();
|
||||
#endif
|
||||
|
||||
rhino_stack_check_init();
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
kstat_t krhino_start(void)
|
||||
{
|
||||
if (g_sys_stat == RHINO_STOPPED) {
|
||||
#if (RHINO_CONFIG_CPU_NUM > 1)
|
||||
for (uint8_t i = 0; i < RHINO_CONFIG_CPU_NUM; i++) {
|
||||
preferred_cpu_ready_task_get(&g_ready_queue, i);
|
||||
g_active_task[i] = g_preferred_ready_task[i];
|
||||
g_active_task[i]->cur_exc = 1;
|
||||
}
|
||||
#else
|
||||
preferred_cpu_ready_task_get(&g_ready_queue, 0);
|
||||
g_active_task[0] = g_preferred_ready_task[0];
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_USER_HOOK > 0)
|
||||
krhino_start_hook();
|
||||
#endif
|
||||
|
||||
g_sys_stat = RHINO_RUNNING;
|
||||
cpu_first_task_start();
|
||||
|
||||
/* should not be here */
|
||||
return RHINO_SYS_FATAL_ERR;
|
||||
}
|
||||
|
||||
return RHINO_RUNNING;
|
||||
}
|
||||
|
||||
|
||||
#if (RHINO_CONFIG_INTRPT_STACK_OVF_CHECK > 0)
|
||||
#if (RHINO_CONFIG_CPU_STACK_DOWN > 0)
|
||||
void krhino_intrpt_stack_ovf_check(void)
|
||||
{
|
||||
if (*g_intrpt_stack_bottom != RHINO_INTRPT_STACK_OVF_MAGIC) {
|
||||
k_err_proc(RHINO_INTRPT_STACK_OVF);
|
||||
}
|
||||
}
|
||||
#else
|
||||
void krhino_intrpt_stack_ovf_check(void)
|
||||
{
|
||||
if (*g_intrpt_stack_top != RHINO_INTRPT_STACK_OVF_MAGIC) {
|
||||
k_err_proc(RHINO_INTRPT_STACK_OVF);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* RHINO_CONFIG_INTRPT_STACK_OVF_CHECK */
|
||||
|
||||
kstat_t krhino_intrpt_enter(void)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
#if (RHINO_CONFIG_INTRPT_STACK_OVF_CHECK > 0)
|
||||
krhino_intrpt_stack_ovf_check();
|
||||
#endif
|
||||
|
||||
RHINO_CPU_INTRPT_DISABLE();
|
||||
|
||||
#if (RHINO_CONFIG_CPU_PWR_MGMT > 0)
|
||||
cpu_pwr_up();
|
||||
#endif
|
||||
|
||||
g_intrpt_nested_level[cpu_cur_get()]++;
|
||||
|
||||
RHINO_CPU_INTRPT_ENABLE();
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
void krhino_intrpt_exit(void)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
uint8_t cur_cpu_num;
|
||||
|
||||
#if (RHINO_CONFIG_INTRPT_STACK_OVF_CHECK > 0)
|
||||
krhino_intrpt_stack_ovf_check();
|
||||
#endif
|
||||
|
||||
RHINO_CPU_INTRPT_DISABLE();
|
||||
|
||||
cur_cpu_num = cpu_cur_get();
|
||||
|
||||
g_intrpt_nested_level[cur_cpu_num]--;
|
||||
|
||||
if (g_intrpt_nested_level[cur_cpu_num] > 0u) {
|
||||
RHINO_CPU_INTRPT_ENABLE();
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_sched_lock[cur_cpu_num] > 0u) {
|
||||
RHINO_CPU_INTRPT_ENABLE();
|
||||
return;
|
||||
}
|
||||
|
||||
preferred_cpu_ready_task_get(&g_ready_queue, cur_cpu_num);
|
||||
|
||||
if (g_preferred_ready_task[cur_cpu_num] == g_active_task[cur_cpu_num]) {
|
||||
RHINO_CPU_INTRPT_ENABLE();
|
||||
return;
|
||||
}
|
||||
|
||||
TRACE_INTRPT_TASK_SWITCH(g_active_task[cur_cpu_num], g_preferred_ready_task[cur_cpu_num]);
|
||||
|
||||
#if (RHINO_CONFIG_CPU_NUM > 1)
|
||||
g_active_task[cur_cpu_num]->cur_exc = 0;
|
||||
#endif
|
||||
|
||||
cpu_intrpt_switch();
|
||||
|
||||
RHINO_CPU_INTRPT_ENABLE();
|
||||
}
|
||||
|
||||
tick_t krhino_next_sleep_ticks_get(void)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
klist_t *tick_head;
|
||||
ktask_t *tcb;
|
||||
klist_t *iter;
|
||||
tick_t ticks;
|
||||
|
||||
tick_head = &g_tick_head;
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
if (tick_head->next == &g_tick_head) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_WAIT_FOREVER;
|
||||
}
|
||||
|
||||
iter = tick_head->next;
|
||||
tcb = krhino_list_entry(iter, ktask_t, tick_list);
|
||||
ticks = tcb->tick_match - g_tick_count;
|
||||
RHINO_CRITICAL_EXIT();
|
||||
|
||||
return ticks;
|
||||
}
|
||||
|
||||
size_t krhino_global_space_get(void)
|
||||
{
|
||||
size_t mem;
|
||||
|
||||
mem = sizeof(g_sys_stat) + sizeof(g_idle_task_spawned) + sizeof(g_ready_queue)
|
||||
+ sizeof(g_sched_lock) + sizeof(g_intrpt_nested_level) + sizeof(g_preferred_ready_task)
|
||||
+ sizeof(g_active_task) + sizeof(g_idle_task) + sizeof(g_idle_task_stack)
|
||||
+ sizeof(g_tick_head) + sizeof(g_tick_count) + sizeof(g_idle_count);
|
||||
|
||||
#if (RHINO_CONFIG_TIMER > 0)
|
||||
mem += sizeof(g_timer_head) + sizeof(g_timer_count)
|
||||
+ sizeof(g_timer_task) + sizeof(g_timer_task_stack)
|
||||
+ sizeof(g_timer_queue) + sizeof(timer_queue_cb);
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
|
||||
mem += sizeof(g_kobj_list);
|
||||
#endif
|
||||
|
||||
return mem;
|
||||
}
|
||||
|
||||
uint32_t krhino_version_get(void)
|
||||
{
|
||||
return RHINO_VERSION;
|
||||
}
|
||||
|
||||
1060
Living_SDK/kernel/rhino/core/k_task.c
Normal file
1060
Living_SDK/kernel/rhino/core/k_task.c
Normal file
File diff suppressed because it is too large
Load diff
62
Living_SDK/kernel/rhino/core/k_task_sem.c
Normal file
62
Living_SDK/kernel/rhino/core/k_task_sem.c
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
|
||||
#if (RHINO_CONFIG_TASK_SEM > 0)
|
||||
kstat_t krhino_task_sem_create(ktask_t *task, ksem_t *sem, const name_t *name,
|
||||
size_t count)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
if (task == NULL) {
|
||||
return RHINO_NULL_PTR;
|
||||
}
|
||||
|
||||
NULL_PARA_CHK(task);
|
||||
|
||||
ret = krhino_sem_create(sem, name, count);
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
task->task_sem_obj = sem;
|
||||
} else {
|
||||
task->task_sem_obj = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
kstat_t krhino_task_sem_del(ktask_t *task)
|
||||
{
|
||||
NULL_PARA_CHK(task);
|
||||
|
||||
return krhino_sem_del(task->task_sem_obj);
|
||||
}
|
||||
|
||||
kstat_t krhino_task_sem_give(ktask_t *task)
|
||||
{
|
||||
NULL_PARA_CHK(task);
|
||||
|
||||
return krhino_sem_give(task->task_sem_obj);
|
||||
}
|
||||
|
||||
kstat_t krhino_task_sem_take(tick_t ticks)
|
||||
{
|
||||
return krhino_sem_take(krhino_cur_task_get()->task_sem_obj, ticks);
|
||||
}
|
||||
|
||||
kstat_t krhino_task_sem_count_set(ktask_t *task, sem_count_t count)
|
||||
{
|
||||
NULL_PARA_CHK(task);
|
||||
|
||||
return krhino_sem_count_set(task->task_sem_obj, count);
|
||||
}
|
||||
|
||||
kstat_t krhino_task_sem_count_get(ktask_t *task, sem_count_t *count)
|
||||
{
|
||||
NULL_PARA_CHK(task);
|
||||
|
||||
return krhino_sem_count_get(task->task_sem_obj, count);
|
||||
}
|
||||
#endif
|
||||
|
||||
129
Living_SDK/kernel/rhino/core/k_tick.c
Normal file
129
Living_SDK/kernel/rhino/core/k_tick.c
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
|
||||
void tick_list_init(void)
|
||||
{
|
||||
klist_init(&g_tick_head);
|
||||
}
|
||||
|
||||
RHINO_INLINE void tick_list_pri_insert(klist_t *head, ktask_t *task)
|
||||
{
|
||||
tick_t val;
|
||||
klist_t *q;
|
||||
klist_t *list_start;
|
||||
klist_t *list_end;
|
||||
ktask_t *task_iter_temp;
|
||||
|
||||
list_start = list_end = head;
|
||||
val = task->tick_remain;
|
||||
|
||||
for (q = list_start->next; q != list_end; q = q->next) {
|
||||
task_iter_temp = krhino_list_entry(q, ktask_t, tick_list);
|
||||
if ((task_iter_temp->tick_match - g_tick_count) > val) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
klist_insert(q, &task->tick_list);
|
||||
}
|
||||
|
||||
void tick_list_insert(ktask_t *task, tick_t time)
|
||||
{
|
||||
klist_t *tick_head_ptr;
|
||||
|
||||
if (time > 0u) {
|
||||
task->tick_match = g_tick_count + time;
|
||||
task->tick_remain = time;
|
||||
|
||||
tick_head_ptr = &g_tick_head;
|
||||
tick_list_pri_insert(tick_head_ptr, task);
|
||||
task->tick_head = tick_head_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
void tick_list_rm(ktask_t *task)
|
||||
{
|
||||
klist_t *tick_head_ptr = task->tick_head;
|
||||
|
||||
if (tick_head_ptr != NULL) {
|
||||
klist_rm(&task->tick_list);
|
||||
task->tick_head = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void tick_list_update(tick_i_t ticks)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
klist_t *tick_head_ptr;
|
||||
ktask_t *p_tcb;
|
||||
klist_t *iter;
|
||||
klist_t *iter_temp;
|
||||
tick_i_t delta;
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
|
||||
g_tick_count += ticks;
|
||||
|
||||
tick_head_ptr = &g_tick_head;
|
||||
iter = tick_head_ptr->next;
|
||||
|
||||
while (RHINO_TRUE) {
|
||||
/* search all the time list if possible */
|
||||
if (iter != tick_head_ptr) {
|
||||
iter_temp = iter->next;
|
||||
p_tcb = krhino_list_entry(iter, ktask_t, tick_list);
|
||||
delta = (tick_i_t)p_tcb->tick_match - (tick_i_t)g_tick_count;
|
||||
/* since time list is sorted by remain time, so just campare the absolute time */
|
||||
if (delta <= 0) {
|
||||
switch (p_tcb->task_state) {
|
||||
case K_SLEEP:
|
||||
p_tcb->blk_state = BLK_FINISH;
|
||||
p_tcb->task_state = K_RDY;
|
||||
tick_list_rm(p_tcb);
|
||||
ready_list_add(&g_ready_queue, p_tcb);
|
||||
break;
|
||||
case K_PEND:
|
||||
tick_list_rm(p_tcb);
|
||||
/* remove task on the block list because task is timeout */
|
||||
klist_rm(&p_tcb->task_list);
|
||||
ready_list_add(&g_ready_queue, p_tcb);
|
||||
p_tcb->blk_state = BLK_TIMEOUT;
|
||||
p_tcb->task_state = K_RDY;
|
||||
mutex_task_pri_reset(p_tcb);
|
||||
p_tcb->blk_obj = NULL;
|
||||
break;
|
||||
case K_PEND_SUSPENDED:
|
||||
tick_list_rm(p_tcb);
|
||||
/* remove task on the block list because task is timeout */
|
||||
klist_rm(&p_tcb->task_list);
|
||||
p_tcb->blk_state = BLK_TIMEOUT;
|
||||
p_tcb->task_state = K_SUSPENDED;
|
||||
mutex_task_pri_reset(p_tcb);
|
||||
p_tcb->blk_obj = NULL;
|
||||
break;
|
||||
case K_SLEEP_SUSPENDED:
|
||||
p_tcb->task_state = K_SUSPENDED;
|
||||
p_tcb->blk_state = BLK_FINISH;
|
||||
tick_list_rm(p_tcb);
|
||||
break;
|
||||
default:
|
||||
k_err_proc(RHINO_SYS_FATAL_ERR);
|
||||
break;
|
||||
}
|
||||
|
||||
iter = iter_temp;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
RHINO_CRITICAL_EXIT();
|
||||
}
|
||||
|
||||
73
Living_SDK/kernel/rhino/core/k_time.c
Executable file
73
Living_SDK/kernel/rhino/core/k_time.c
Executable file
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
|
||||
void krhino_tick_proc(void)
|
||||
{
|
||||
#if (RHINO_CONFIG_INTRPT_GUARD > 0)
|
||||
soc_intrpt_guard();
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_USER_HOOK > 0)
|
||||
krhino_tick_hook();
|
||||
#endif
|
||||
|
||||
tick_list_update(1);
|
||||
|
||||
#if (RHINO_CONFIG_SCHED_RR > 0)
|
||||
time_slice_update();
|
||||
#endif
|
||||
}
|
||||
|
||||
sys_time_t krhino_sys_tick_get(void)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
sys_time_t tick_tmp;
|
||||
|
||||
RHINO_CPU_INTRPT_DISABLE();
|
||||
tick_tmp = g_tick_count;
|
||||
RHINO_CPU_INTRPT_ENABLE();
|
||||
|
||||
return tick_tmp;
|
||||
}
|
||||
|
||||
sys_time_t krhino_sys_time_get(void)
|
||||
{
|
||||
return (sys_time_t)(krhino_sys_tick_get() * 1000 / RHINO_CONFIG_TICKS_PER_SECOND);
|
||||
}
|
||||
|
||||
tick_t krhino_ms_to_ticks(sys_time_t ms)
|
||||
{
|
||||
uint16_t padding;
|
||||
uint16_t surplus;
|
||||
tick_t ticks;
|
||||
|
||||
surplus = ms % 1000;
|
||||
ticks = (ms / 1000) * RHINO_CONFIG_TICKS_PER_SECOND;
|
||||
padding = 1000 / RHINO_CONFIG_TICKS_PER_SECOND;
|
||||
padding = (padding > 0) ? (padding - 1) : 0;
|
||||
|
||||
ticks += ((surplus + padding) * RHINO_CONFIG_TICKS_PER_SECOND) / 1000;
|
||||
|
||||
return ticks;
|
||||
}
|
||||
|
||||
sys_time_t krhino_ticks_to_ms(tick_t ticks)
|
||||
{
|
||||
uint32_t padding;
|
||||
uint32_t surplus;
|
||||
sys_time_t time;
|
||||
|
||||
surplus = ticks % RHINO_CONFIG_TICKS_PER_SECOND;
|
||||
time = (ticks / RHINO_CONFIG_TICKS_PER_SECOND) * 1000;
|
||||
padding = RHINO_CONFIG_TICKS_PER_SECOND / 1000;
|
||||
padding = (padding > 0) ? (padding - 1) : 0;
|
||||
|
||||
time += ((surplus + padding) * 1000) / RHINO_CONFIG_TICKS_PER_SECOND;
|
||||
|
||||
return time;
|
||||
}
|
||||
|
||||
438
Living_SDK/kernel/rhino/core/k_timer.c
Executable file
438
Living_SDK/kernel/rhino/core/k_timer.c
Executable file
|
|
@ -0,0 +1,438 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
|
||||
#if (RHINO_CONFIG_TIMER > 0)
|
||||
static void timer_list_pri_insert(klist_t *head, ktimer_t *timer)
|
||||
{
|
||||
sys_time_t val;
|
||||
klist_t *q;
|
||||
klist_t *start;
|
||||
klist_t *end;
|
||||
ktimer_t *task_iter_temp;
|
||||
|
||||
start = end = head;
|
||||
val = timer->remain;
|
||||
|
||||
for (q = start->next; q != end; q = q->next) {
|
||||
task_iter_temp = krhino_list_entry(q, ktimer_t, timer_list);
|
||||
if ((task_iter_temp->match - g_timer_count) > val) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
klist_insert(q, &timer->timer_list);
|
||||
}
|
||||
|
||||
static void timer_list_rm(ktimer_t *timer)
|
||||
{
|
||||
klist_t *head;
|
||||
|
||||
head = timer->to_head;
|
||||
if (head != NULL) {
|
||||
klist_rm(&timer->timer_list);
|
||||
timer->to_head = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static kstat_t timer_create(ktimer_t *timer, const name_t *name, timer_cb_t cb,
|
||||
sys_time_t first, sys_time_t round, void *arg, uint8_t auto_run,
|
||||
uint8_t mm_alloc_flag)
|
||||
{
|
||||
kstat_t err = RHINO_SUCCESS;
|
||||
|
||||
NULL_PARA_CHK(timer);
|
||||
NULL_PARA_CHK(name);
|
||||
NULL_PARA_CHK(cb);
|
||||
|
||||
if (first == 0u) {
|
||||
return RHINO_INV_PARAM;
|
||||
}
|
||||
|
||||
if (first >= MAX_TIMER_TICKS) {
|
||||
return RHINO_INV_PARAM;
|
||||
}
|
||||
|
||||
if (round >= MAX_TIMER_TICKS) {
|
||||
return RHINO_INV_PARAM;
|
||||
}
|
||||
|
||||
timer->name = name;
|
||||
timer->cb = cb;
|
||||
timer->init_count = first;
|
||||
timer->round_ticks = round;
|
||||
timer->remain = 0u;
|
||||
timer->match = 0u;
|
||||
timer->timer_state = TIMER_DEACTIVE;
|
||||
timer->to_head = NULL;
|
||||
timer->mm_alloc_flag = mm_alloc_flag;
|
||||
timer->timer_cb_arg = arg;
|
||||
klist_init(&timer->timer_list);
|
||||
|
||||
timer->obj_type = RHINO_TIMER_OBJ_TYPE;
|
||||
|
||||
if (auto_run > 0u) {
|
||||
err = krhino_timer_start(timer);
|
||||
}
|
||||
|
||||
TRACE_TIMER_CREATE(krhino_cur_task_get(), timer);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
kstat_t krhino_timer_create(ktimer_t *timer, const name_t *name, timer_cb_t cb,
|
||||
sys_time_t first, sys_time_t round, void *arg, uint8_t auto_run)
|
||||
{
|
||||
return timer_create(timer, name, cb, first, round, arg, auto_run,
|
||||
K_OBJ_STATIC_ALLOC);
|
||||
}
|
||||
|
||||
kstat_t krhino_timer_del(ktimer_t *timer)
|
||||
{
|
||||
k_timer_queue_cb cb;
|
||||
kstat_t err;
|
||||
|
||||
NULL_PARA_CHK(timer);
|
||||
|
||||
cb.timer = timer;
|
||||
cb.cb_num = TIMER_CMD_DEL;
|
||||
err = krhino_buf_queue_send(&g_timer_queue, &cb, sizeof(k_timer_queue_cb));
|
||||
return err;
|
||||
}
|
||||
|
||||
#if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0)
|
||||
kstat_t krhino_timer_dyn_create(ktimer_t **timer, const name_t *name,
|
||||
timer_cb_t cb,
|
||||
sys_time_t first, sys_time_t round, void *arg, uint8_t auto_run)
|
||||
{
|
||||
kstat_t ret;
|
||||
ktimer_t *timer_obj;
|
||||
|
||||
NULL_PARA_CHK(timer);
|
||||
|
||||
timer_obj = krhino_mm_alloc(sizeof(ktimer_t));
|
||||
if (timer_obj == NULL) {
|
||||
return RHINO_NO_MEM;
|
||||
}
|
||||
|
||||
ret = timer_create(timer_obj, name, cb, first, round, arg, auto_run,
|
||||
K_OBJ_DYN_ALLOC);
|
||||
if (ret != RHINO_SUCCESS) {
|
||||
krhino_mm_free(timer_obj);
|
||||
return ret;
|
||||
}
|
||||
|
||||
*timer = timer_obj;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
kstat_t krhino_timer_dyn_del(ktimer_t *timer)
|
||||
{
|
||||
k_timer_queue_cb cb;
|
||||
kstat_t err;
|
||||
|
||||
NULL_PARA_CHK(timer);
|
||||
|
||||
cb.timer = timer;
|
||||
cb.cb_num = TIMER_CMD_DYN_DEL;
|
||||
err = krhino_buf_queue_send(&g_timer_queue, &cb, sizeof(k_timer_queue_cb));
|
||||
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
kstat_t krhino_timer_start(ktimer_t *timer)
|
||||
{
|
||||
k_timer_queue_cb cb;
|
||||
kstat_t err;
|
||||
|
||||
NULL_PARA_CHK(timer);
|
||||
|
||||
cb.timer = timer;
|
||||
cb.cb_num = TIMER_CMD_START;
|
||||
err = krhino_buf_queue_send(&g_timer_queue, &cb, sizeof(k_timer_queue_cb));
|
||||
return err;
|
||||
}
|
||||
|
||||
kstat_t krhino_timer_stop(ktimer_t *timer)
|
||||
{
|
||||
k_timer_queue_cb cb;
|
||||
kstat_t err;
|
||||
|
||||
NULL_PARA_CHK(timer);
|
||||
|
||||
cb.timer = timer;
|
||||
cb.cb_num = TIMER_CMD_STOP;
|
||||
err = krhino_buf_queue_send(&g_timer_queue, &cb, sizeof(k_timer_queue_cb));
|
||||
return err;
|
||||
}
|
||||
|
||||
kstat_t krhino_timer_change(ktimer_t *timer, sys_time_t first, sys_time_t round)
|
||||
{
|
||||
k_timer_queue_cb cb;
|
||||
kstat_t err;
|
||||
|
||||
NULL_PARA_CHK(timer);
|
||||
|
||||
if (first == 0u) {
|
||||
return RHINO_INV_PARAM;
|
||||
}
|
||||
|
||||
if (first >= MAX_TIMER_TICKS) {
|
||||
return RHINO_INV_PARAM;
|
||||
}
|
||||
|
||||
if (round >= MAX_TIMER_TICKS) {
|
||||
return RHINO_INV_PARAM;
|
||||
}
|
||||
|
||||
cb.timer = timer;
|
||||
cb.first = first;
|
||||
cb.u.round = round;
|
||||
cb.cb_num = TIMER_CMD_CHG;
|
||||
err = krhino_buf_queue_send(&g_timer_queue, &cb, sizeof(k_timer_queue_cb));
|
||||
return err;
|
||||
}
|
||||
|
||||
kstat_t krhino_timer_arg_change(ktimer_t *timer, void *arg)
|
||||
{
|
||||
k_timer_queue_cb cb;
|
||||
kstat_t err;
|
||||
|
||||
NULL_PARA_CHK(timer);
|
||||
|
||||
cb.timer = timer;
|
||||
cb.u.arg = arg;
|
||||
cb.cb_num = TIMER_ARG_CHG;
|
||||
err = krhino_buf_queue_send(&g_timer_queue, &cb, sizeof(k_timer_queue_cb));
|
||||
return err;
|
||||
}
|
||||
|
||||
kstat_t krhino_timer_arg_change_auto(ktimer_t *timer, void *arg)
|
||||
{
|
||||
k_timer_queue_cb cb;
|
||||
kstat_t err;
|
||||
|
||||
NULL_PARA_CHK(timer);
|
||||
|
||||
cb.timer = timer;
|
||||
cb.u.arg = arg;
|
||||
cb.cb_num = TIMER_ARG_CHG_AUTO;
|
||||
|
||||
err = krhino_buf_queue_send(&g_timer_queue, &cb, sizeof(k_timer_queue_cb));
|
||||
return err;
|
||||
}
|
||||
|
||||
static void timer_cb_proc(void)
|
||||
{
|
||||
klist_t *q;
|
||||
klist_t *start;
|
||||
klist_t *end;
|
||||
ktimer_t *timer;
|
||||
sys_time_i_t delta;
|
||||
|
||||
start = end = &g_timer_head;
|
||||
|
||||
for (q = start->next; q != end; q = q->next) {
|
||||
timer = krhino_list_entry(q, ktimer_t, timer_list);
|
||||
delta = (sys_time_i_t)timer->match - (sys_time_i_t)g_timer_count;
|
||||
|
||||
if (delta <= 0) {
|
||||
timer->cb(timer, timer->timer_cb_arg);
|
||||
timer_list_rm(timer);
|
||||
|
||||
if (timer->round_ticks > 0u) {
|
||||
timer->remain = timer->round_ticks;
|
||||
timer->match = g_timer_count + timer->remain;
|
||||
timer->to_head = &g_timer_head;
|
||||
timer_list_pri_insert(&g_timer_head, timer);
|
||||
} else {
|
||||
timer->timer_state = TIMER_DEACTIVE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void cmd_proc(k_timer_queue_cb *cb, uint8_t cmd)
|
||||
{
|
||||
ktimer_t *timer;
|
||||
timer = cb->timer;
|
||||
|
||||
switch (cmd) {
|
||||
case TIMER_CMD_START:
|
||||
if (timer->obj_type != RHINO_TIMER_OBJ_TYPE) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (timer->timer_state == TIMER_ACTIVE) {
|
||||
break;
|
||||
}
|
||||
|
||||
timer->match = g_timer_count + timer->init_count;
|
||||
/* sort by remain time */
|
||||
timer->remain = timer->init_count;
|
||||
/* used by timer delete */
|
||||
timer->to_head = &g_timer_head;
|
||||
timer_list_pri_insert(&g_timer_head, timer);
|
||||
timer->timer_state = TIMER_ACTIVE;
|
||||
break;
|
||||
case TIMER_CMD_STOP:
|
||||
if (timer->obj_type != RHINO_TIMER_OBJ_TYPE) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (timer->timer_state == TIMER_DEACTIVE) {
|
||||
break;
|
||||
}
|
||||
timer_list_rm(timer);
|
||||
timer->timer_state = TIMER_DEACTIVE;
|
||||
break;
|
||||
case TIMER_CMD_CHG:
|
||||
if (cb->first == 0u) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (timer->obj_type != RHINO_TIMER_OBJ_TYPE) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (timer->timer_state != TIMER_DEACTIVE) {
|
||||
break;
|
||||
}
|
||||
|
||||
timer->init_count = cb->first;
|
||||
timer->round_ticks = cb->u.round;
|
||||
break;
|
||||
case TIMER_ARG_CHG:
|
||||
if (timer->obj_type != RHINO_TIMER_OBJ_TYPE) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (timer->timer_state != TIMER_DEACTIVE) {
|
||||
break;
|
||||
}
|
||||
|
||||
timer->timer_cb_arg = cb->u.arg;
|
||||
break;
|
||||
case TIMER_CMD_DEL:
|
||||
if (timer->obj_type != RHINO_TIMER_OBJ_TYPE) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (timer->timer_state != TIMER_DEACTIVE) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (timer->mm_alloc_flag != K_OBJ_STATIC_ALLOC) {
|
||||
break;
|
||||
}
|
||||
|
||||
timer->obj_type = RHINO_OBJ_TYPE_NONE;
|
||||
TRACE_TIMER_DEL(krhino_cur_task_get(), timer);
|
||||
break;
|
||||
#if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0)
|
||||
case TIMER_CMD_DYN_DEL:
|
||||
if (timer->obj_type != RHINO_TIMER_OBJ_TYPE) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (timer->timer_state != TIMER_DEACTIVE) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (timer->mm_alloc_flag != K_OBJ_DYN_ALLOC) {
|
||||
break;
|
||||
}
|
||||
|
||||
timer->obj_type = RHINO_OBJ_TYPE_NONE;
|
||||
TRACE_TIMER_DEL(krhino_cur_task_get(), timer);
|
||||
krhino_mm_free(timer);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
k_err_proc(RHINO_SYS_FATAL_ERR);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void timer_cmd_proc(k_timer_queue_cb *cb)
|
||||
{
|
||||
if (cb->cb_num == TIMER_ARG_CHG_AUTO) {
|
||||
cmd_proc(cb, TIMER_CMD_STOP);
|
||||
cmd_proc(cb, TIMER_ARG_CHG);
|
||||
cmd_proc(cb, TIMER_CMD_START);
|
||||
}
|
||||
else {
|
||||
cmd_proc(cb, cb->cb_num);
|
||||
}
|
||||
}
|
||||
|
||||
static void timer_task(void *pa)
|
||||
{
|
||||
ktimer_t *timer;
|
||||
k_timer_queue_cb cb_msg;
|
||||
kstat_t err;
|
||||
sys_time_t tick_start;
|
||||
sys_time_t tick_end;
|
||||
sys_time_i_t delta;
|
||||
size_t msg_size;
|
||||
(void)pa;
|
||||
|
||||
while (RHINO_TRUE) {
|
||||
err = krhino_buf_queue_recv(&g_timer_queue, RHINO_WAIT_FOREVER, &cb_msg, &msg_size);
|
||||
tick_end = krhino_sys_tick_get();
|
||||
|
||||
if (err == RHINO_SUCCESS) {
|
||||
g_timer_count = tick_end;
|
||||
}
|
||||
else {
|
||||
k_err_proc(RHINO_SYS_FATAL_ERR);
|
||||
}
|
||||
|
||||
timer_cmd_proc(&cb_msg);
|
||||
|
||||
while (!is_klist_empty(&g_timer_head)) {
|
||||
timer = krhino_list_entry(g_timer_head.next, ktimer_t, timer_list);
|
||||
tick_start = krhino_sys_tick_get();
|
||||
delta = (sys_time_i_t)timer->match - (sys_time_i_t)tick_start;
|
||||
if (delta > 0) {
|
||||
err = krhino_buf_queue_recv(&g_timer_queue, (tick_t)delta, &cb_msg, &msg_size);
|
||||
tick_end = krhino_sys_tick_get();
|
||||
if (err == RHINO_BLK_TIMEOUT) {
|
||||
g_timer_count = tick_end;
|
||||
}
|
||||
else if (err == RHINO_SUCCESS) {
|
||||
g_timer_count = tick_end;
|
||||
timer_cmd_proc(&cb_msg);
|
||||
}
|
||||
else {
|
||||
k_err_proc(RHINO_SYS_FATAL_ERR);
|
||||
}
|
||||
}
|
||||
else {
|
||||
g_timer_count = tick_start;
|
||||
}
|
||||
timer_cb_proc();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ktimer_init(void)
|
||||
{
|
||||
klist_init(&g_timer_head);
|
||||
|
||||
krhino_fix_buf_queue_create(&g_timer_queue, "timer_queue",
|
||||
timer_queue_cb, sizeof(k_timer_queue_cb), RHINO_CONFIG_TIMER_MSG_NUM);
|
||||
krhino_task_create(&g_timer_task, "timer_task", NULL,
|
||||
RHINO_CONFIG_TIMER_TASK_PRI, 0u, g_timer_task_stack,
|
||||
RHINO_CONFIG_TIMER_TASK_STACK_SIZE, timer_task, 1u);
|
||||
}
|
||||
#endif /* RHINO_CONFIG_TIMER */
|
||||
|
||||
282
Living_SDK/kernel/rhino/core/k_workqueue.c
Executable file
282
Living_SDK/kernel/rhino/core/k_workqueue.c
Executable file
|
|
@ -0,0 +1,282 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
|
||||
#if (RHINO_CONFIG_WORKQUEUE > 0)
|
||||
static kstat_t workqueue_is_exist(kworkqueue_t *workqueue)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
kworkqueue_t *pos;
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
|
||||
for (pos = krhino_list_entry(g_workqueue_list_head.next, kworkqueue_t, workqueue_node);
|
||||
&pos->workqueue_node != &g_workqueue_list_head;
|
||||
pos = krhino_list_entry(pos->workqueue_node.next, kworkqueue_t, workqueue_node)) {
|
||||
if (pos == workqueue) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_WORKQUEUE_EXIST;
|
||||
}
|
||||
}
|
||||
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_WORKQUEUE_NOT_EXIST;
|
||||
}
|
||||
|
||||
static void worker_task(void *arg)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
kstat_t ret;
|
||||
kwork_t *work = NULL;
|
||||
kworkqueue_t *queue = (kworkqueue_t *)arg;
|
||||
|
||||
while (1) {
|
||||
|
||||
ret = krhino_sem_take(&(queue->sem), RHINO_WAIT_FOREVER);
|
||||
if (ret != RHINO_SUCCESS) {
|
||||
k_err_proc(ret);
|
||||
}
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
|
||||
/* have work to do. */
|
||||
work = krhino_list_entry(queue->work_list.next, kwork_t, work_node);
|
||||
klist_rm_init(&(work->work_node));
|
||||
queue->work_current = work;
|
||||
work->work_exit = 0;
|
||||
RHINO_CRITICAL_EXIT();
|
||||
|
||||
/* do work */
|
||||
work->handle(work->arg);
|
||||
RHINO_CRITICAL_ENTER();
|
||||
/* clean current work */
|
||||
queue->work_current = NULL;
|
||||
|
||||
RHINO_CRITICAL_EXIT();
|
||||
}
|
||||
}
|
||||
|
||||
kstat_t krhino_workqueue_create(kworkqueue_t *workqueue, const name_t *name,
|
||||
uint8_t pri, cpu_stack_t *stack_buf, size_t stack_size)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
kstat_t ret;
|
||||
|
||||
NULL_PARA_CHK(workqueue);
|
||||
NULL_PARA_CHK(name);
|
||||
NULL_PARA_CHK(stack_buf);
|
||||
|
||||
if (pri >= RHINO_CONFIG_PRI_MAX) {
|
||||
return RHINO_BEYOND_MAX_PRI;
|
||||
}
|
||||
|
||||
if (stack_size == 0u) {
|
||||
return RHINO_TASK_INV_STACK_SIZE;
|
||||
}
|
||||
|
||||
ret = workqueue_is_exist(workqueue);
|
||||
if (ret == RHINO_WORKQUEUE_EXIST) {
|
||||
return RHINO_WORKQUEUE_EXIST;
|
||||
}
|
||||
|
||||
klist_init(&(workqueue->workqueue_node));
|
||||
klist_init(&(workqueue->work_list));
|
||||
workqueue->work_current = NULL;
|
||||
workqueue->name = name;
|
||||
|
||||
ret = krhino_sem_create(&(workqueue->sem), "WORKQUEUE-SEM", 0);
|
||||
if (ret != RHINO_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
klist_insert(&g_workqueue_list_head, &(workqueue->workqueue_node));
|
||||
RHINO_CRITICAL_EXIT();
|
||||
|
||||
ret = krhino_task_create(&(workqueue->worker), name, (void *)workqueue, pri,
|
||||
0, stack_buf, stack_size, worker_task, 1);
|
||||
if (ret != RHINO_SUCCESS) {
|
||||
RHINO_CRITICAL_ENTER();
|
||||
klist_rm_init(&(workqueue->workqueue_node));
|
||||
RHINO_CRITICAL_EXIT();
|
||||
krhino_sem_del(&(workqueue->sem));
|
||||
return ret;
|
||||
}
|
||||
|
||||
TRACE_WORKQUEUE_CREATE(krhino_cur_task_get(), workqueue);
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
static void work_timer_cb(void *timer, void *arg)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
kstat_t ret;
|
||||
kwork_t *work = ((ktimer_t *)timer)->priv;
|
||||
|
||||
kworkqueue_t *wq = (kworkqueue_t *)arg;
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
if (wq->work_current == work) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return;
|
||||
}
|
||||
|
||||
if (work->work_exit == 1) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return;
|
||||
}
|
||||
|
||||
/* NOTE: the work MUST be initialized firstly */
|
||||
klist_rm_init(&(work->work_node));
|
||||
klist_insert(&(wq->work_list), &(work->work_node));
|
||||
|
||||
work->wq = wq;
|
||||
work->work_exit = 1;
|
||||
RHINO_CRITICAL_EXIT();
|
||||
|
||||
ret = krhino_sem_give(&(wq->sem));
|
||||
if (ret != RHINO_SUCCESS) {
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
kstat_t krhino_work_init(kwork_t *work, work_handle_t handle, void *arg,
|
||||
tick_t dly)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
if (work == NULL) {
|
||||
return RHINO_NULL_PTR;
|
||||
}
|
||||
|
||||
if (handle == NULL) {
|
||||
return RHINO_NULL_PTR;
|
||||
}
|
||||
|
||||
NULL_PARA_CHK(work);
|
||||
NULL_PARA_CHK(handle);
|
||||
|
||||
memset(work, 0, sizeof(kwork_t));
|
||||
|
||||
klist_init(&(work->work_node));
|
||||
work->handle = handle;
|
||||
work->arg = arg;
|
||||
work->dly = dly;
|
||||
work->wq = NULL;
|
||||
|
||||
if (dly > 0) {
|
||||
ret = krhino_timer_dyn_create((ktimer_t **)(&work->timer), "WORK-TIMER", work_timer_cb,
|
||||
work->dly, 0, (void *)work, 0);
|
||||
if (ret != RHINO_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
TRACE_WORK_INIT(krhino_cur_task_get(), work);
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
kstat_t krhino_work_run(kworkqueue_t *workqueue, kwork_t *work)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
|
||||
kstat_t ret;
|
||||
|
||||
NULL_PARA_CHK(workqueue);
|
||||
NULL_PARA_CHK(work);
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
|
||||
if (work->dly == 0) {
|
||||
if (workqueue->work_current == work) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_WORKQUEUE_WORK_RUNNING;
|
||||
}
|
||||
|
||||
if (work->work_exit == 1) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_WORKQUEUE_WORK_EXIST;
|
||||
}
|
||||
|
||||
/* NOTE: the work MUST be initialized firstly */
|
||||
klist_rm_init(&(work->work_node));
|
||||
klist_insert(&(workqueue->work_list), &(work->work_node));
|
||||
|
||||
work->wq = workqueue;
|
||||
work->work_exit = 1;
|
||||
|
||||
RHINO_CRITICAL_EXIT();
|
||||
ret = krhino_sem_give(&(workqueue->sem));
|
||||
if (ret != RHINO_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
} else {
|
||||
work->timer->priv = work;
|
||||
RHINO_CRITICAL_EXIT();
|
||||
ret = krhino_timer_arg_change_auto(work->timer, (void *)workqueue);
|
||||
if (ret != RHINO_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
kstat_t krhino_work_sched(kwork_t *work)
|
||||
{
|
||||
return krhino_work_run(&g_workqueue_default, work);
|
||||
}
|
||||
|
||||
kstat_t krhino_work_cancel(kwork_t *work)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
kworkqueue_t *wq;
|
||||
|
||||
NULL_PARA_CHK(work);
|
||||
|
||||
wq = (kworkqueue_t *)work->wq;
|
||||
|
||||
if (wq == NULL) {
|
||||
if (work->dly > 0) {
|
||||
krhino_timer_stop(work->timer);
|
||||
}
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
if (wq->work_current == work) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_WORKQUEUE_WORK_RUNNING;
|
||||
}
|
||||
|
||||
if (work->work_exit == 1) {
|
||||
RHINO_CRITICAL_EXIT();
|
||||
return RHINO_WORKQUEUE_WORK_EXIST;
|
||||
}
|
||||
|
||||
klist_rm_init(&(work->work_node));
|
||||
work->wq = NULL;
|
||||
RHINO_CRITICAL_EXIT();
|
||||
|
||||
return RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
void workqueue_init(void)
|
||||
{
|
||||
klist_init(&g_workqueue_list_head);
|
||||
|
||||
krhino_workqueue_create(&g_workqueue_default, "DEFAULT-WORKQUEUE",
|
||||
RHINO_CONFIG_WORKQUEUE_TASK_PRIO, g_workqueue_stack,
|
||||
RHINO_CONFIG_WORKQUEUE_STACK_SIZE);
|
||||
}
|
||||
#endif
|
||||
|
||||
27
Living_SDK/kernel/rhino/debug/include/k_backtrace.h
Executable file
27
Living_SDK/kernel/rhino/debug/include/k_backtrace.h
Executable file
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef K_BACKTRACE_H
|
||||
#define K_BACKTRACE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_BACKTRACE > 0)
|
||||
|
||||
/* show backtrace now */
|
||||
void krhino_backtrace_now(void);
|
||||
|
||||
/* show backtrace for the task */
|
||||
void krhino_backtrace_task(char *taskname);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* K_BACKTRACE_H */
|
||||
25
Living_SDK/kernel/rhino/debug/include/k_dbg_api.h
Executable file
25
Living_SDK/kernel/rhino/debug/include/k_dbg_api.h
Executable file
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef K_DBG_API_H
|
||||
#define K_DBG_API_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include "k_api.h"
|
||||
#include "k_dftdbg_config.h"
|
||||
#include "k_infoget.h"
|
||||
#include "k_overview.h"
|
||||
#include "k_panic.h"
|
||||
#include "k_backtrace.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* K_DBG_API_H */
|
||||
33
Living_SDK/kernel/rhino/debug/include/k_dftdbg_config.h
Executable file
33
Living_SDK/kernel/rhino/debug/include/k_dftdbg_config.h
Executable file
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef K_DFTDBG_CONFIG_H
|
||||
#define K_DFTDBG_CONFIG_H
|
||||
|
||||
#ifndef RHINO_CONFIG_BACKTRACE
|
||||
#define RHINO_CONFIG_BACKTRACE 1
|
||||
#endif
|
||||
|
||||
/* If AliOS task over the Exception/Fatal Error */
|
||||
#ifndef RHINO_CONFIG_PANIC
|
||||
#define RHINO_CONFIG_PANIC 1
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_PANIC > 0)
|
||||
/* If the mcu printf depends on isr */
|
||||
#ifndef RHINO_CONFIG_PANIC_PRT_INT
|
||||
#define RHINO_CONFIG_PANIC_PRT_INT 1
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_PANIC_OVERVIEW
|
||||
#define RHINO_CONFIG_PANIC_OVERVIEW 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_NORMAL_PRT
|
||||
#define RHINO_CONFIG_NORMAL_PRT 1
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* K_DFTDBG_CONFIG_H */
|
||||
39
Living_SDK/kernel/rhino/debug/include/k_infoget.h
Executable file
39
Living_SDK/kernel/rhino/debug/include/k_infoget.h
Executable file
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef K_INFOGET_H
|
||||
#define K_INFOGET_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This function will get task handle by its name.
|
||||
*/
|
||||
ktask_t *krhino_task_find(char *name);
|
||||
|
||||
/**
|
||||
* This function will return true if task is ready.
|
||||
*/
|
||||
int krhino_is_task_ready(ktask_t *task);
|
||||
|
||||
/**
|
||||
* This function will return true if task is running.
|
||||
*/
|
||||
int krhino_task_is_running(ktask_t *task);
|
||||
|
||||
/**
|
||||
* This function will get the bottom of task stack
|
||||
* @param[in] task NULL for active task
|
||||
* @return the bottom of stack
|
||||
*/
|
||||
void *krhino_task_stack_bottom(ktask_t *task);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* K_INFOGET_H */
|
||||
69
Living_SDK/kernel/rhino/debug/include/k_overview.h
Executable file
69
Living_SDK/kernel/rhino/debug/include/k_overview.h
Executable file
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef K_OVERVIEW_H
|
||||
#define K_OVERVIEW_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/**
|
||||
* convert int to ascii(HEX)
|
||||
* while using format % in libc, malloc/free is involved.
|
||||
* this function avoid using malloc/free. so it works when heap corrupt.
|
||||
* @param[in] num number
|
||||
* @param[in] str fix 8 character str
|
||||
* @return str
|
||||
*/
|
||||
char *k_int2str(int num, char *str);
|
||||
|
||||
/**
|
||||
* This function print the overview of heap
|
||||
* @param[in] print_func function to output information, NULL for
|
||||
* "printf"
|
||||
*/
|
||||
void krhino_mm_overview(int (*print_func)(const char *fmt, ...));
|
||||
|
||||
/**
|
||||
* This function print the overview of tasks
|
||||
* @param[in] print_func function to output information, NULL for
|
||||
* "printf"
|
||||
*/
|
||||
void krhino_task_overview(int (*print_func)(const char *fmt, ...));
|
||||
|
||||
/**
|
||||
* This function print the overview of buf_queues
|
||||
* @param[in] print_func function to output information, NULL for
|
||||
* "printf"
|
||||
*/
|
||||
void krhino_buf_queue_overview(int (*print_func)(const char *fmt, ...));
|
||||
|
||||
/**
|
||||
* This function print the overview of queues
|
||||
* @param[in] print_func function to output information, NULL for
|
||||
* "printf"
|
||||
*/
|
||||
void krhino_queue_overview(int (*print_func)(const char *fmt, ...));
|
||||
|
||||
/**
|
||||
* This function print the overview of sems
|
||||
* @param[in] print_func function to output information, NULL for
|
||||
* "printf"
|
||||
*/
|
||||
void krhino_sem_overview(int (*print_func)(const char *fmt, ...));
|
||||
|
||||
/**
|
||||
* This function print the overview of all
|
||||
* @param[in] print_func function to output information, NULL for
|
||||
* "printf"
|
||||
*/
|
||||
void krhino_overview();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* K_OVERVIEW_H */
|
||||
24
Living_SDK/kernel/rhino/debug/include/k_panic.h
Executable file
24
Living_SDK/kernel/rhino/debug/include/k_panic.h
Executable file
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef K_PANIC_H
|
||||
#define K_PANIC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_PANIC > 0)
|
||||
/* fault/exception entry
|
||||
notice: this function maybe reentried by double exception */
|
||||
void panicHandler(void *context);
|
||||
void debug_fatal_error(kstat_t err, char *file, int line);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* K_PANIC_H */
|
||||
23
Living_SDK/kernel/rhino/debug/k_backtrace.c
Executable file
23
Living_SDK/kernel/rhino/debug/k_backtrace.c
Executable file
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include "k_dbg_api.h"
|
||||
|
||||
#if (RHINO_CONFIG_BACKTRACE > 0)
|
||||
|
||||
/* follow functions should defined by arch\...\backtrace.c */
|
||||
extern int backtrace_now(int (*print_func)(const char *fmt, ...));
|
||||
extern int backtrace_task(char *taskname, int (*print_func)(const char *fmt, ...));
|
||||
|
||||
void krhino_backtrace_now()
|
||||
{
|
||||
backtrace_now(printf);
|
||||
}
|
||||
|
||||
void krhino_backtrace_task(char *taskname)
|
||||
{
|
||||
backtrace_task(taskname, printf);
|
||||
}
|
||||
|
||||
#endif
|
||||
57
Living_SDK/kernel/rhino/debug/k_infoget.c
Executable file
57
Living_SDK/kernel/rhino/debug/k_infoget.c
Executable file
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include "k_dbg_api.h"
|
||||
|
||||
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
|
||||
ktask_t *krhino_task_find(char *name)
|
||||
{
|
||||
klist_t *listnode;
|
||||
ktask_t *task;
|
||||
|
||||
for (listnode = g_kobj_list.task_head.next;
|
||||
listnode != &g_kobj_list.task_head; listnode = listnode->next) {
|
||||
task = krhino_list_entry(listnode, ktask_t, task_stats_item);
|
||||
if (0 == strcmp(name, task->task_name)) {
|
||||
return task;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
int krhino_task_is_running(ktask_t *task)
|
||||
{
|
||||
if ( g_active_task[cpu_cur_get()] == task
|
||||
&& g_intrpt_nested_level[cpu_cur_get()] == 0 ) {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int krhino_is_task_ready(ktask_t *task)
|
||||
{
|
||||
return (task->task_state == K_RDY);
|
||||
}
|
||||
|
||||
void *krhino_task_stack_bottom(ktask_t *task)
|
||||
{
|
||||
if (task == NULL) {
|
||||
task = g_active_task[cpu_cur_get()];
|
||||
}
|
||||
|
||||
if (task->task_state == K_DELETED) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if (RHINO_CONFIG_CPU_STACK_DOWN > 0)
|
||||
return task->task_stack_base + task->stack_size;
|
||||
#else
|
||||
return task->task_stack_base;
|
||||
#endif
|
||||
}
|
||||
|
||||
420
Living_SDK/kernel/rhino/debug/k_overview.c
Executable file
420
Living_SDK/kernel/rhino/debug/k_overview.c
Executable file
|
|
@ -0,0 +1,420 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include "k_dbg_api.h"
|
||||
|
||||
/* convert int to ascii(HEX)
|
||||
while using format % in libc, malloc/free is involved.
|
||||
this function avoid using malloc/free. so it works when heap corrupt. */
|
||||
char *k_int2str(int num, char *str)
|
||||
{
|
||||
char index[] = "0123456789ABCDEF";
|
||||
unsigned int usnum = (unsigned int)num;
|
||||
|
||||
str[7] = index[usnum % 16];
|
||||
usnum /= 16;
|
||||
str[6] = index[usnum % 16];
|
||||
usnum /= 16;
|
||||
str[5] = index[usnum % 16];
|
||||
usnum /= 16;
|
||||
str[4] = index[usnum % 16];
|
||||
usnum /= 16;
|
||||
str[3] = index[usnum % 16];
|
||||
usnum /= 16;
|
||||
str[2] = index[usnum % 16];
|
||||
usnum /= 16;
|
||||
str[1] = index[usnum % 16];
|
||||
usnum /= 16;
|
||||
str[0] = index[usnum % 16];
|
||||
usnum /= 16;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
#if (K_MM_STATISTIC > 0)
|
||||
void krhino_mm_overview(int (*print_func)(const char *fmt, ...))
|
||||
{
|
||||
#if (RHINO_CONFIG_MM_BLK > 0)
|
||||
mblk_pool_t *mm_pool;
|
||||
#endif
|
||||
char s_heap_overview[] =
|
||||
" | 0x | 0x | 0x | 0x |\r\n";
|
||||
|
||||
if (print_func == NULL) {
|
||||
print_func = printf;
|
||||
}
|
||||
|
||||
print_func(
|
||||
"-----------------------------------------------------------\r\n");
|
||||
print_func(
|
||||
"[HEAP]| TotalSz | FreeSz | UsedSz | MinFreeSz |\r\n");
|
||||
|
||||
k_int2str((int)(g_kmm_head->free_size + g_kmm_head->used_size),
|
||||
&s_heap_overview[10]);
|
||||
k_int2str((int)g_kmm_head->free_size, &s_heap_overview[23]);
|
||||
k_int2str((int)g_kmm_head->used_size, &s_heap_overview[36]);
|
||||
k_int2str((int)(g_kmm_head->free_size + g_kmm_head->used_size -
|
||||
g_kmm_head->maxused_size),
|
||||
&s_heap_overview[49]);
|
||||
print_func(s_heap_overview);
|
||||
|
||||
print_func(
|
||||
"-----------------------------------------------------------\r\n");
|
||||
|
||||
#if (RHINO_CONFIG_MM_BLK > 0)
|
||||
print_func(
|
||||
"[POOL]| PoolSz | FreeSz | UsedSz | BlkSz |\r\n");
|
||||
/* little blk, try to get from mm_pool */
|
||||
if (g_kmm_head->fix_pool != NULL) {
|
||||
mm_pool = (mblk_pool_t *)g_kmm_head->fix_pool;
|
||||
k_int2str((int)mm_pool->blk_whole * mm_pool->blk_size,
|
||||
&s_heap_overview[10]);
|
||||
k_int2str((int)mm_pool->blk_avail * mm_pool->blk_size,
|
||||
&s_heap_overview[23]);
|
||||
k_int2str((int)(mm_pool->blk_whole - mm_pool->blk_avail) *
|
||||
mm_pool->blk_size,
|
||||
&s_heap_overview[36]);
|
||||
k_int2str((int)mm_pool->blk_size, &s_heap_overview[49]);
|
||||
print_func(s_heap_overview);
|
||||
}
|
||||
|
||||
print_func(
|
||||
"-----------------------------------------------------------\r\n");
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
void krhino_mm_overview(int (*print_func)(const char *fmt, ...))
|
||||
{
|
||||
if (print_func == NULL) {
|
||||
print_func = printf;
|
||||
}
|
||||
print_func("K_MM_STATISTIC in k_config.h is closed!\r\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
|
||||
void krhino_task_overview(int (*print_func)(const char *fmt, ...))
|
||||
{
|
||||
size_t free_size;
|
||||
klist_t *listnode;
|
||||
ktask_t *task;
|
||||
int stat_idx;
|
||||
int i;
|
||||
char *cpu_stat[] = { "UNK", "RDY", "PEND", "SUS",
|
||||
"PEND_SUS", "SLP", "SLP_SUS", "DEL" };
|
||||
const name_t *task_name;
|
||||
char s_task_overview[] = " 0x 0x "
|
||||
" 0x (0x )\r\n";
|
||||
|
||||
if (print_func == NULL) {
|
||||
print_func = printf;
|
||||
}
|
||||
|
||||
print_func("---------------------------------------------------------------"
|
||||
"-----------\r\n");
|
||||
print_func("TaskName State Prio Stack StackSize "
|
||||
"(MinFree)\r\n");
|
||||
print_func("---------------------------------------------------------------"
|
||||
"-----------\r\n");
|
||||
|
||||
for (listnode = g_kobj_list.task_head.next;
|
||||
listnode != &g_kobj_list.task_head; listnode = listnode->next) {
|
||||
task = krhino_list_entry(listnode, ktask_t, task_stats_item);
|
||||
|
||||
if (krhino_task_stack_min_free(task, &free_size) != RHINO_SUCCESS) {
|
||||
free_size = 0;
|
||||
}
|
||||
free_size *= sizeof(cpu_stack_t);
|
||||
|
||||
/* set name */
|
||||
task_name = task->task_name == NULL ? "anonym" : task->task_name;
|
||||
for (i = 0; i < 20; i++) {
|
||||
s_task_overview[i] = ' ';
|
||||
}
|
||||
for (i = 0; i < 20; i++) {
|
||||
if (task_name[i] == '\0') {
|
||||
break;
|
||||
}
|
||||
s_task_overview[i] = task_name[i];
|
||||
}
|
||||
|
||||
/* set state */
|
||||
stat_idx = task->task_state >= sizeof(cpu_stat) / sizeof(char *)
|
||||
? 0
|
||||
: task->task_state;
|
||||
for (i = 21; i < 29; i++) {
|
||||
s_task_overview[i] = ' ';
|
||||
}
|
||||
for (i = 21; i < 29; i++) {
|
||||
if (cpu_stat[stat_idx][i - 21] == '\0') {
|
||||
break;
|
||||
}
|
||||
s_task_overview[i] = cpu_stat[stat_idx][i - 21];
|
||||
}
|
||||
|
||||
/* set stack priority */
|
||||
k_int2str(task->prio, &s_task_overview[32]);
|
||||
|
||||
/* set stack info */
|
||||
k_int2str((int)task->task_stack_base, &s_task_overview[43]);
|
||||
k_int2str((int)task->stack_size * sizeof(cpu_stack_t),
|
||||
&s_task_overview[54]);
|
||||
k_int2str((int)free_size, &s_task_overview[65]);
|
||||
|
||||
/* print */
|
||||
print_func(s_task_overview);
|
||||
}
|
||||
}
|
||||
#else
|
||||
void krhino_task_overview(int (*print_func)(const char *fmt, ...))
|
||||
{
|
||||
if (print_func == NULL) {
|
||||
print_func = printf;
|
||||
}
|
||||
|
||||
print_func("RHINO_CONFIG_SYSTEM_STATS in k_config.h is closed!\r\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_BUF_QUEUE > 0)
|
||||
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
|
||||
void krhino_buf_queue_overview(int (*print_func)(const char *fmt, ...))
|
||||
{
|
||||
int i;
|
||||
klist_t *listnode;
|
||||
klist_t *blk_list_head;
|
||||
ktask_t *task;
|
||||
kbuf_queue_t *buf_queue;
|
||||
const name_t *task_name;
|
||||
char s_buf_queue_overview[] = "0x 0x 0x 0x "
|
||||
"0x \r\n";
|
||||
|
||||
if (print_func == NULL) {
|
||||
print_func = printf;
|
||||
}
|
||||
|
||||
print_func(
|
||||
"------------------------------------------------------------------\r\n");
|
||||
print_func(
|
||||
"BufQueAddr TotalSize PeakNum CurrNum MinFreeSz TaskWaiting\r\n");
|
||||
print_func(
|
||||
"------------------------------------------------------------------\r\n");
|
||||
for (listnode = g_kobj_list.buf_queue_head.next;
|
||||
listnode != &g_kobj_list.buf_queue_head; listnode = listnode->next) {
|
||||
|
||||
buf_queue = krhino_list_entry(listnode, kbuf_queue_t, buf_queue_item);
|
||||
if (buf_queue->blk_obj.obj_type != RHINO_BUF_QUEUE_OBJ_TYPE) {
|
||||
print_func("BufQueue Type error!\r\n");
|
||||
break;
|
||||
}
|
||||
|
||||
/* set buf_queue information */
|
||||
k_int2str((int)buf_queue->buf, &s_buf_queue_overview[2]);
|
||||
k_int2str((int)(buf_queue->ringbuf.end - buf_queue->ringbuf.buf),
|
||||
&s_buf_queue_overview[13]);
|
||||
k_int2str((int)buf_queue->peak_num, &s_buf_queue_overview[24]);
|
||||
k_int2str((int)buf_queue->cur_num, &s_buf_queue_overview[35]);
|
||||
k_int2str((int)buf_queue->min_free_buf_size, &s_buf_queue_overview[46]);
|
||||
|
||||
/* set pending task name */
|
||||
blk_list_head = &buf_queue->blk_obj.blk_list;
|
||||
if (is_klist_empty(blk_list_head)) {
|
||||
task_name = " ";
|
||||
} else {
|
||||
task = krhino_list_entry(blk_list_head->next, ktask_t, task_list);
|
||||
task_name = task->task_name == NULL ? "anonym" : task->task_name;
|
||||
}
|
||||
|
||||
for (i = 0; i < 20; i++) {
|
||||
s_buf_queue_overview[55 + i] = ' ';
|
||||
}
|
||||
for (i = 0; i < 20; i++) {
|
||||
if (task_name[i] == '\0') {
|
||||
break;
|
||||
}
|
||||
s_buf_queue_overview[55 + i] = task_name[i];
|
||||
}
|
||||
|
||||
/* print */
|
||||
print_func(s_buf_queue_overview);
|
||||
}
|
||||
}
|
||||
#else
|
||||
void krhino_buf_queue_overview(int (*print_func)(const char *fmt, ...))
|
||||
{
|
||||
if (print_func == NULL) {
|
||||
print_func = printf;
|
||||
}
|
||||
|
||||
print_func("RHINO_CONFIG_SYSTEM_STATS in k_config.h is closed!\r\n");
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_QUEUE > 0)
|
||||
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
|
||||
void krhino_queue_overview(int (*print_func)(const char *fmt, ...))
|
||||
{
|
||||
int i;
|
||||
klist_t *listnode;
|
||||
klist_t *blk_list_head;
|
||||
ktask_t *task;
|
||||
kqueue_t *queue;
|
||||
const name_t *task_name;
|
||||
char s_queue_overview[] =
|
||||
"0x 0x 0x 0x \r\n";
|
||||
|
||||
if (print_func == NULL) {
|
||||
print_func = printf;
|
||||
}
|
||||
|
||||
print_func("-------------------------------------------------------\r\n");
|
||||
print_func("QueAddr TotalSize PeakNum CurrNum TaskWaiting\r\n");
|
||||
print_func("-------------------------------------------------------\r\n");
|
||||
|
||||
for (listnode = g_kobj_list.queue_head.next;
|
||||
listnode != &g_kobj_list.queue_head; listnode = listnode->next) {
|
||||
|
||||
queue = krhino_list_entry(listnode, kqueue_t, queue_item);
|
||||
if (queue->blk_obj.obj_type != RHINO_QUEUE_OBJ_TYPE) {
|
||||
print_func("Queue Type error!\r\n");
|
||||
break;
|
||||
}
|
||||
|
||||
/* set queue information */
|
||||
k_int2str((int)queue->msg_q.queue_start, &s_queue_overview[2]);
|
||||
k_int2str((int)queue->msg_q.size, &s_queue_overview[13]);
|
||||
k_int2str((int)queue->msg_q.peak_num, &s_queue_overview[24]);
|
||||
k_int2str((int)queue->msg_q.cur_num, &s_queue_overview[35]);
|
||||
|
||||
/* set pending task name */
|
||||
blk_list_head = &queue->blk_obj.blk_list;
|
||||
if (is_klist_empty(blk_list_head)) {
|
||||
task_name = " ";
|
||||
} else {
|
||||
task = krhino_list_entry(blk_list_head->next, ktask_t, task_list);
|
||||
task_name = task->task_name == NULL ? "anonym" : task->task_name;
|
||||
}
|
||||
|
||||
for (i = 0; i < 20; i++) {
|
||||
s_queue_overview[44 + i] = ' ';
|
||||
}
|
||||
for (i = 0; i < 20; i++) {
|
||||
if (task_name[i] == '\0') {
|
||||
break;
|
||||
}
|
||||
s_queue_overview[44 + i] = task_name[i];
|
||||
}
|
||||
|
||||
/* print */
|
||||
print_func(s_queue_overview);
|
||||
}
|
||||
}
|
||||
#else
|
||||
void krhino_queue_overview(int (*print_func)(const char *fmt, ...))
|
||||
{
|
||||
if (print_func == NULL) {
|
||||
print_func = printf;
|
||||
}
|
||||
|
||||
print_func("RHINO_CONFIG_SYSTEM_STATS in k_config.h is closed!\r\n");
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_SEM > 0)
|
||||
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
|
||||
void krhino_sem_overview(int (*print_func)(const char *fmt, ...))
|
||||
{
|
||||
int i;
|
||||
ksem_t *sem;
|
||||
ktask_t *task;
|
||||
klist_t *listnode;
|
||||
klist_t *blk_list_head;
|
||||
const name_t *task_name;
|
||||
char s_sem_overview[] =
|
||||
"0x 0x 0x \r\n";
|
||||
|
||||
if (print_func == NULL) {
|
||||
print_func = printf;
|
||||
}
|
||||
|
||||
print_func("--------------------------------------------\r\n");
|
||||
print_func("SemAddr Count PeakCount TaskWaiting\r\n");
|
||||
print_func("--------------------------------------------\r\n");
|
||||
|
||||
for (listnode = g_kobj_list.sem_head.next;
|
||||
listnode != &g_kobj_list.sem_head; listnode = listnode->next) {
|
||||
|
||||
sem = krhino_list_entry(listnode, ksem_t, sem_item);
|
||||
if (sem->blk_obj.obj_type != RHINO_SEM_OBJ_TYPE) {
|
||||
print_func("Sem Type error!\r\n");
|
||||
break;
|
||||
}
|
||||
|
||||
/* set sem information */
|
||||
k_int2str((int)sem, &s_sem_overview[2]);
|
||||
k_int2str((int)sem->count, &s_sem_overview[13]);
|
||||
k_int2str((int)sem->peak_count, &s_sem_overview[24]);
|
||||
|
||||
/* set pending task name */
|
||||
blk_list_head = &sem->blk_obj.blk_list;
|
||||
if (is_klist_empty(blk_list_head)) {
|
||||
task_name = " ";
|
||||
} else {
|
||||
task = krhino_list_entry(blk_list_head->next, ktask_t, task_list);
|
||||
task_name = task->task_name == NULL ? "anonym" : task->task_name;
|
||||
}
|
||||
|
||||
for (i = 0; i < 20; i++) {
|
||||
s_sem_overview[33 + i] = ' ';
|
||||
}
|
||||
for (i = 0; i < 20; i++) {
|
||||
if (task_name[i] == '\0') {
|
||||
break;
|
||||
}
|
||||
s_sem_overview[33 + i] = task_name[i];
|
||||
}
|
||||
|
||||
/* print */
|
||||
print_func(s_sem_overview);
|
||||
}
|
||||
}
|
||||
#else
|
||||
void krhino_sem_overview(int (*print_func)(const char *fmt, ...))
|
||||
{
|
||||
if (print_func == NULL) {
|
||||
print_func = printf;
|
||||
}
|
||||
|
||||
print_func("RHINO_CONFIG_SYSTEM_STATS in k_config.h is closed!\r\n");
|
||||
}
|
||||
#endif
|
||||
#endif /* RHINO_CONFIG_SEM */
|
||||
|
||||
void krhino_overview()
|
||||
{
|
||||
int (*print_func)(const char *fmt, ...);
|
||||
|
||||
print_func = printf;
|
||||
|
||||
#if (RHINO_CONFIG_MM_TLF > 0)
|
||||
print_func("========== Heap Info ==========\r\n");
|
||||
krhino_mm_overview(print_func);
|
||||
#endif
|
||||
print_func("========== Task Info ==========\r\n");
|
||||
krhino_task_overview(print_func);
|
||||
#if (RHINO_CONFIG_QUEUE > 0)
|
||||
print_func("========== Queue Info ==========\r\n");
|
||||
krhino_queue_overview(print_func);
|
||||
#endif
|
||||
#if (RHINO_CONFIG_BUF_QUEUE > 0)
|
||||
print_func("======== Buf Queue Info ========\r\n");
|
||||
krhino_buf_queue_overview(print_func);
|
||||
#endif
|
||||
#if (RHINO_CONFIG_SEM > 0)
|
||||
print_func("=========== Sem Info ===========\r\n");
|
||||
krhino_sem_overview(print_func);
|
||||
#endif
|
||||
}
|
||||
266
Living_SDK/kernel/rhino/debug/k_panic.c
Normal file
266
Living_SDK/kernel/rhino/debug/k_panic.c
Normal file
|
|
@ -0,0 +1,266 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include "k_dbg_api.h"
|
||||
#include "aos/cli.h"
|
||||
#include "aos/kernel.h"
|
||||
#if (RHINO_CONFIG_PANIC > 0)
|
||||
#include "k_compiler.h"
|
||||
#endif
|
||||
|
||||
#define DEBUG_PANIC_STEP_MAX 32
|
||||
|
||||
/* ARMCC and ICCARM do not use heap when printf a string, but gcc dose*/
|
||||
#if defined(__CC_ARM)
|
||||
#define print_str printf
|
||||
#elif defined(__ICCARM__)
|
||||
#define print_str printf
|
||||
#elif defined(__GNUC__)
|
||||
__attribute__((weak)) int print_str(const char *fmt, ...)
|
||||
{
|
||||
int ret;
|
||||
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
ret = vprintf(fmt, args);
|
||||
va_end(args);
|
||||
|
||||
fflush(stdout);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* on some platform, the libc printf use the heap, while the heap maybe corrupt
|
||||
when panic.
|
||||
Redefining a new print_str without using heap is advised on these platform.
|
||||
*/
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_PANIC > 0)
|
||||
|
||||
/* follow functions should defined by arch\...\panic_c.c */
|
||||
extern void panicShowRegs(void *context,
|
||||
int (*print_func)(const char *fmt, ...));
|
||||
extern void panicGetCtx(void *context, char **pPC, char **pLR, int **pSP);
|
||||
extern int panicBacktraceCaller(char *PC, int *SP,
|
||||
int (*print_func)(const char *fmt, ...));
|
||||
extern int panicBacktraceCallee(char *PC, int *SP, char *LR,
|
||||
int (*print_func)(const char *fmt, ...));
|
||||
|
||||
/* how many steps has finished when crash */
|
||||
volatile uint32_t g_crash_steps = 0;
|
||||
|
||||
static void panic_goto_cli(void)
|
||||
{
|
||||
#if 0 /* (defined (CONFIG_AOS_CLI) && (RHINO_CONFIG_SYSTEM_STATS > 0)) */
|
||||
klist_t *listnode;
|
||||
ktask_t *task;
|
||||
|
||||
for (listnode = g_kobj_list.task_head.next;
|
||||
listnode != &g_kobj_list.task_head; listnode = listnode->next) {
|
||||
task = krhino_list_entry(listnode, ktask_t, task_stats_item);
|
||||
if (0 != strcmp("cli", task->task_name)) {
|
||||
krhino_task_suspend(task);
|
||||
}
|
||||
}
|
||||
|
||||
krhino_sched_enable();
|
||||
|
||||
krhino_task_overview(print_str);
|
||||
|
||||
/*suspend current task*/
|
||||
task = g_active_task[cpu_cur_get()];
|
||||
if (0 != strcmp("cli", task->task_name)) {
|
||||
krhino_task_suspend(task);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* should exeception be restored?
|
||||
reture 1 YES, 0 NO*/
|
||||
int panicRestoreCheck(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* fault/exception entry
|
||||
notice: this function maybe reentried by double exception
|
||||
first exception, input context
|
||||
second exception, input NULL */
|
||||
void panicHandler(void *context)
|
||||
{
|
||||
char prt_stack[] =
|
||||
"stack(0x ): 0x 0x 0x 0x \r\n";
|
||||
int x;
|
||||
#if (RHINO_CONFIG_BACKTRACE > 0)
|
||||
int lvl;
|
||||
#endif
|
||||
static int *SP = NULL;
|
||||
static char *PC = NULL;
|
||||
static char *LR = NULL;
|
||||
CPSR_ALLOC();
|
||||
|
||||
krhino_sched_disable();
|
||||
|
||||
/* g_crash_steps++ before panicHandler */
|
||||
if (g_crash_steps > 1 && g_crash_steps < DEBUG_PANIC_STEP_MAX) {
|
||||
print_str("......\r\n");
|
||||
}
|
||||
|
||||
switch (g_crash_steps) {
|
||||
case 1:
|
||||
print_str("!!!!!!!!!! Exception !!!!!!!!!!\r\n");
|
||||
if (context != NULL) {
|
||||
panicGetCtx(context, &PC, &LR, &SP);
|
||||
}
|
||||
panicShowRegs(context, print_str);
|
||||
g_crash_steps++;
|
||||
case 2:
|
||||
if (SP != NULL) {
|
||||
print_str("========== Stack info ==========\r\n");
|
||||
for (x = 0; x < 16; x++) {
|
||||
k_int2str((int)&SP[x * 4], &prt_stack[8]);
|
||||
k_int2str(SP[x * 4 + 0], &prt_stack[21]);
|
||||
k_int2str(SP[x * 4 + 1], &prt_stack[32]);
|
||||
k_int2str(SP[x * 4 + 2], &prt_stack[43]);
|
||||
k_int2str(SP[x * 4 + 3], &prt_stack[54]);
|
||||
print_str(prt_stack);
|
||||
}
|
||||
}
|
||||
g_crash_steps++;
|
||||
#if (RHINO_CONFIG_BACKTRACE > 0)
|
||||
/* 3 steps, 3 ways to try backtrace */
|
||||
case 3:
|
||||
/* Backtrace 1st try: assume ReturnAddr is saved in stack when exception */
|
||||
if (SP != NULL) {
|
||||
print_str("========== Call stack ==========\r\n");
|
||||
lvl = panicBacktraceCaller(PC, SP, print_str);
|
||||
if (lvl > 0) {
|
||||
/* backtrace success, do not try other way */
|
||||
g_crash_steps += 2;
|
||||
}
|
||||
/* else, backtrace fail, try another way */
|
||||
}
|
||||
g_crash_steps++;
|
||||
case 4:
|
||||
if (g_crash_steps == 4) {
|
||||
/* Backtrace 2nd try: assume ReturnAddr is saved in LR when exception */
|
||||
if (SP != NULL) {
|
||||
lvl = panicBacktraceCallee(PC, SP, LR, print_str);
|
||||
if (lvl > 0) {
|
||||
/* backtrace success, do not try other way */
|
||||
g_crash_steps += 1;
|
||||
}
|
||||
/* else, backtrace fail, try another way */
|
||||
}
|
||||
g_crash_steps++;
|
||||
}
|
||||
case 5:
|
||||
if (g_crash_steps == 5) {
|
||||
/* Backtrace 3rd try: assume PC is invalalb, backtrace from LR */
|
||||
if (SP != NULL) {
|
||||
(void)panicBacktraceCaller(LR, SP, print_str);
|
||||
}
|
||||
g_crash_steps++;
|
||||
}
|
||||
#else
|
||||
g_crash_steps = 6;
|
||||
#endif
|
||||
#if (RHINO_CONFIG_PANIC_OVERVIEW > 0)
|
||||
case 6:
|
||||
#if (RHINO_CONFIG_MM_TLF > 0)
|
||||
print_str("========== Heap Info ==========\r\n");
|
||||
krhino_mm_overview(print_str);
|
||||
#endif
|
||||
g_crash_steps++;
|
||||
case 7:
|
||||
print_str("========== Task Info ==========\r\n");
|
||||
krhino_task_overview(print_str);
|
||||
g_crash_steps++;
|
||||
case 8:
|
||||
#if (RHINO_CONFIG_QUEUE > 0)
|
||||
print_str("========== Queue Info ==========\r\n");
|
||||
krhino_queue_overview(print_str);
|
||||
#endif
|
||||
g_crash_steps++;
|
||||
case 9:
|
||||
#if (RHINO_CONFIG_BUF_QUEUE > 0)
|
||||
print_str("======== Buf Queue Info ========\r\n");
|
||||
krhino_buf_queue_overview(print_str);
|
||||
#endif
|
||||
g_crash_steps++;
|
||||
case 10:
|
||||
#if (RHINO_CONFIG_SEM > 0)
|
||||
print_str("=========== Sem Info ===========\r\n");
|
||||
krhino_sem_overview(print_str);
|
||||
#endif
|
||||
g_crash_steps++;
|
||||
#else
|
||||
g_crash_steps = 11;
|
||||
#endif
|
||||
case 11:
|
||||
print_str("!!!!!!!!!! dump end !!!!!!!!!!\r\n");
|
||||
g_crash_steps++;
|
||||
/* for debug version, last step is CLI */
|
||||
case 12:
|
||||
panic_goto_cli();
|
||||
g_crash_steps++;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
RHINO_CPU_INTRPT_DISABLE();
|
||||
while (1) {
|
||||
/* aos_reboot(); */
|
||||
}
|
||||
RHINO_CPU_INTRPT_ENABLE();
|
||||
}
|
||||
|
||||
|
||||
void debug_fatal_error(kstat_t err, char *file, int line)
|
||||
{
|
||||
char prt_stack[] =
|
||||
"stack(0x ): 0x 0x 0x 0x \r\n";
|
||||
int x;
|
||||
int *SP = (int *)RHINO_GET_SP();
|
||||
CPSR_ALLOC();
|
||||
|
||||
krhino_sched_disable();
|
||||
|
||||
printf("!!!!!!!!!! Fatal Error !!!!!!!!!!\r\n");
|
||||
printf("errno:%d , file:%s, line:%d\r\n", err, file, line);
|
||||
|
||||
if ( SP != NULL ) {
|
||||
print_str("========== Stack info ==========\r\n");
|
||||
for (x = 0; x < 16; x++) {
|
||||
k_int2str((int)&SP[x * 4], &prt_stack[8]);
|
||||
k_int2str(SP[x * 4 + 0], &prt_stack[21]);
|
||||
k_int2str(SP[x * 4 + 1], &prt_stack[32]);
|
||||
k_int2str(SP[x * 4 + 2], &prt_stack[43]);
|
||||
k_int2str(SP[x * 4 + 3], &prt_stack[54]);
|
||||
print_str(prt_stack);
|
||||
}
|
||||
}
|
||||
|
||||
print_str("========== Heap Info ==========\r\n");
|
||||
krhino_mm_overview(print_str);
|
||||
|
||||
print_str("========== Task Info ==========\r\n");
|
||||
krhino_task_overview(print_str);
|
||||
|
||||
#if (RHINO_CONFIG_BACKTRACE > 0)
|
||||
krhino_backtrace_now();
|
||||
#endif
|
||||
|
||||
panic_goto_cli();
|
||||
|
||||
RHINO_CPU_INTRPT_DISABLE();
|
||||
while (1) {
|
||||
/* aos_reboot(); */
|
||||
}
|
||||
RHINO_CPU_INTRPT_ENABLE();
|
||||
}
|
||||
#endif
|
||||
50
Living_SDK/kernel/rhino/rhino.mk
Executable file
50
Living_SDK/kernel/rhino/rhino.mk
Executable file
|
|
@ -0,0 +1,50 @@
|
|||
NAME := rhino
|
||||
|
||||
$(NAME)_TYPE := kernel
|
||||
$(NAME)_MBINS_TYPE := kernel
|
||||
|
||||
$(NAME)_COMPONENTS += rhino
|
||||
|
||||
GLOBAL_INCLUDES += core/include uspace/include debug/include hal/soc ./
|
||||
|
||||
#default gcc
|
||||
ifeq ($(COMPILER),)
|
||||
$(NAME)_CFLAGS += -Wall -Werror
|
||||
else ifeq ($(COMPILER),gcc)
|
||||
$(NAME)_CFLAGS += -Wall -Werror
|
||||
endif
|
||||
|
||||
CONFIG_SYSINFO_KERNEL_VERSION = AOS-R-1.3.4
|
||||
GLOBAL_CFLAGS += -DSYSINFO_KERNEL_VERSION=\"$(CONFIG_SYSINFO_KERNEL_VERSION)\"
|
||||
$(info kernel_version:${CONFIG_SYSINFO_KERNEL_VERSION})
|
||||
|
||||
$(NAME)_SOURCES := core/k_err.c \
|
||||
core/k_mm.c \
|
||||
core/k_mm_debug.c \
|
||||
core/k_ringbuf.c \
|
||||
core/k_stats.c \
|
||||
core/k_task_sem.c \
|
||||
core/k_timer.c \
|
||||
core/k_buf_queue.c \
|
||||
core/k_event.c \
|
||||
core/k_mm_blk.c \
|
||||
core/k_mutex.c \
|
||||
core/k_pend.c \
|
||||
core/k_sched.c \
|
||||
core/k_sys.c \
|
||||
core/k_tick.c \
|
||||
core/k_workqueue.c \
|
||||
core/k_dyn_mem_proc.c \
|
||||
core/k_idle.c \
|
||||
core/k_obj.c \
|
||||
core/k_queue.c \
|
||||
core/k_sem.c \
|
||||
core/k_task.c \
|
||||
core/k_time.c \
|
||||
common/k_fifo.c \
|
||||
common/k_trace.c \
|
||||
debug/k_overview.c \
|
||||
debug/k_panic.c \
|
||||
debug/k_backtrace.c \
|
||||
debug/k_infoget.c
|
||||
|
||||
96
Living_SDK/kernel/rhino/test/core/buf_queue/buf_queue_del.c
Normal file
96
Living_SDK/kernel/rhino/test/core/buf_queue/buf_queue_del.c
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <k_api.h>
|
||||
#include <test_fw.h>
|
||||
|
||||
#include "buf_queue_test.h"
|
||||
|
||||
#define TEST_BUFQUEUE_MSG0_SIZE 8
|
||||
#define TEST_BUFQUEUE_BUF0_SIZE 16
|
||||
#define TEST_BUFQUEUE_MSG_MAX 8
|
||||
|
||||
static ktask_t *task_0_test;
|
||||
static char g_test_recv_msg0[TEST_BUFQUEUE_MSG0_SIZE];
|
||||
static char g_test_bufqueue_buf0[TEST_BUFQUEUE_MSG0_SIZE];
|
||||
static kbuf_queue_t g_test_bufqueue0;
|
||||
|
||||
static void buf_queue_create_param_test(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
ret = krhino_buf_queue_create(NULL, "test_bufqueue0", g_test_bufqueue_buf0,
|
||||
TEST_BUFQUEUE_BUF0_SIZE, TEST_BUFQUEUE_MSG_MAX);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_NULL_PTR);
|
||||
|
||||
ret = krhino_buf_queue_create(&g_test_bufqueue0, NULL, g_test_bufqueue_buf0,
|
||||
TEST_BUFQUEUE_BUF0_SIZE, TEST_BUFQUEUE_MSG_MAX);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_NULL_PTR);
|
||||
|
||||
ret = krhino_buf_queue_create(&g_test_bufqueue0, "test_bufqueue0", NULL,
|
||||
TEST_BUFQUEUE_BUF0_SIZE, TEST_BUFQUEUE_MSG_MAX);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_NULL_PTR);
|
||||
|
||||
ret = krhino_buf_queue_create(&g_test_bufqueue0, "test_bufqueue0",
|
||||
g_test_bufqueue_buf0,
|
||||
0, TEST_BUFQUEUE_MSG_MAX);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_BUF_QUEUE_SIZE_ZERO);
|
||||
}
|
||||
|
||||
static void buf_queue_del_param_test(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
ksem_t sem;
|
||||
|
||||
ret = krhino_buf_queue_del(NULL);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_NULL_PTR);
|
||||
|
||||
krhino_sem_create(& sem, "test_sem ", 0);
|
||||
ret = krhino_buf_queue_del((kbuf_queue_t *)&sem);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_KOBJ_TYPE_ERR);
|
||||
krhino_sem_del(&sem);
|
||||
|
||||
ret = krhino_buf_queue_dyn_del(&g_test_bufqueue0);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_KOBJ_DEL_ERR);
|
||||
}
|
||||
|
||||
static void task_queue0_entry(void *arg)
|
||||
{
|
||||
kstat_t ret;
|
||||
size_t size;
|
||||
|
||||
while (1) {
|
||||
ret = krhino_buf_queue_create(&g_test_bufqueue0, "test_bufqueue0",
|
||||
(void **)&g_test_bufqueue_buf0,
|
||||
TEST_BUFQUEUE_BUF0_SIZE, TEST_BUFQUEUE_MSG_MAX);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_SUCCESS);
|
||||
|
||||
/* check krhino_buf_queue_create param */
|
||||
buf_queue_create_param_test();
|
||||
|
||||
/* check krhino_buf_queue_del param */
|
||||
buf_queue_del_param_test();
|
||||
|
||||
ret = krhino_buf_queue_del(&g_test_bufqueue0);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_SUCCESS);
|
||||
|
||||
next_test_case_notify();
|
||||
|
||||
krhino_task_dyn_del(task_0_test);
|
||||
}
|
||||
}
|
||||
|
||||
kstat_t task_buf_queue_del_test(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
test_case_check_err = 0;
|
||||
|
||||
ret = krhino_task_dyn_create(&task_0_test, "task_bufqueue0_test", 0, 10,
|
||||
0, TASK_TEST_STACK_SIZE, task_queue0_entry, 1);
|
||||
BUFQUEUE_VAL_CHK((ret == RHINO_SUCCESS) || (ret == RHINO_STOPPED));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <k_api.h>
|
||||
#include <test_fw.h>
|
||||
|
||||
#include "buf_queue_test.h"
|
||||
|
||||
#define TEST_BUFQUEUE_MSG_MAX 4
|
||||
#define TEST_BUFQUEUE_MAX_NUM 10
|
||||
#define TEST_BUFQUEUE_SIZE 100
|
||||
#define TEST_BUFQUEUE_MSG0_SIZE 10
|
||||
|
||||
static ktask_t *task_0_test;
|
||||
static ktask_t *task_1_test;
|
||||
static kbuf_queue_t *g_test_bufqueue0;
|
||||
static char g_test_recv_msg0[TEST_BUFQUEUE_MSG0_SIZE];
|
||||
|
||||
static void queue_dyn_create_param_test(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
ret = krhino_buf_queue_dyn_create(NULL, "test_bufqueue0", 0,
|
||||
TEST_BUFQUEUE_MSG_MAX);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_NULL_PTR);
|
||||
|
||||
ret = krhino_buf_queue_dyn_create(&g_test_bufqueue0, NULL, 4,
|
||||
TEST_BUFQUEUE_MSG_MAX);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_NULL_PTR);
|
||||
|
||||
ret = krhino_buf_queue_dyn_create(&g_test_bufqueue0, NULL, 0,
|
||||
TEST_BUFQUEUE_MSG_MAX);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_BUF_QUEUE_SIZE_ZERO);
|
||||
}
|
||||
|
||||
static void queue_dyn_del_param_test(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
ksem_t sem;
|
||||
ret = krhino_buf_queue_dyn_del(NULL);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_NULL_PTR);
|
||||
|
||||
ret = krhino_buf_queue_dyn_create(&g_test_bufqueue0, "test_bufqueue0",
|
||||
100, TEST_BUFQUEUE_MSG_MAX);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_SUCCESS);
|
||||
|
||||
ret = krhino_buf_queue_del(g_test_bufqueue0);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_KOBJ_DEL_ERR);
|
||||
|
||||
ret = krhino_buf_queue_dyn_del(g_test_bufqueue0);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_SUCCESS);
|
||||
|
||||
|
||||
krhino_sem_create(& sem, "test_sem ", 0);
|
||||
ret = krhino_buf_queue_dyn_del((kbuf_queue_t *)&sem);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_KOBJ_TYPE_ERR);
|
||||
krhino_sem_del(&sem);
|
||||
}
|
||||
|
||||
static void task_queue0_entry(void *arg)
|
||||
{
|
||||
int i;
|
||||
size_t size;
|
||||
kstat_t ret = 0;
|
||||
|
||||
while (1) {
|
||||
/* check krhino_buf_queue_dyn_create param */
|
||||
queue_dyn_create_param_test();
|
||||
|
||||
/* check krhino_buf_queue_del param */
|
||||
queue_dyn_del_param_test();
|
||||
|
||||
for (i = 1; i < TEST_BUFQUEUE_MAX_NUM; i++) {
|
||||
ret = krhino_buf_queue_dyn_create(&g_test_bufqueue0, "test_bufqueue0",
|
||||
i * 8, TEST_BUFQUEUE_MSG_MAX);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_SUCCESS);
|
||||
|
||||
ret = krhino_buf_queue_dyn_del(g_test_bufqueue0);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_SUCCESS);
|
||||
}
|
||||
|
||||
ret = krhino_buf_queue_dyn_create(&g_test_bufqueue0, "test_bufqueue0",
|
||||
TEST_BUFQUEUE_SIZE, TEST_BUFQUEUE_MSG_MAX);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_SUCCESS);
|
||||
|
||||
ret = krhino_buf_queue_recv(g_test_bufqueue0, RHINO_WAIT_FOREVER,
|
||||
g_test_recv_msg0, &size);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_BLK_DEL);
|
||||
|
||||
ret = krhino_buf_queue_dyn_del(g_test_bufqueue0);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_SUCCESS);
|
||||
|
||||
krhino_task_dyn_del(task_0_test);
|
||||
}
|
||||
}
|
||||
|
||||
static void task_queue1_entry(void *arg)
|
||||
{
|
||||
if (test_case_check_err == 0) {
|
||||
test_case_success++;
|
||||
PRINT_RESULT("buf queue dyn create&del", PASS);
|
||||
} else {
|
||||
test_case_check_err = 0;
|
||||
test_case_fail++;
|
||||
PRINT_RESULT("buf queue dyn create&del", FAIL);
|
||||
}
|
||||
|
||||
next_test_case_notify();
|
||||
krhino_task_dyn_del(task_1_test);
|
||||
}
|
||||
|
||||
kstat_t task_buf_queue_dyn_create_test(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
ret = krhino_task_dyn_create(&task_0_test, "task_bufqueue0_test", 0, 10,
|
||||
0, TASK_TEST_STACK_SIZE, task_queue0_entry, 1);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_SUCCESS);
|
||||
|
||||
ret = krhino_task_dyn_create(&task_1_test, "task_bufqueue0_test", 0, 11,
|
||||
0, TASK_TEST_STACK_SIZE, task_queue1_entry, 1);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_SUCCESS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <k_api.h>
|
||||
#include <test_fw.h>
|
||||
|
||||
#include "buf_queue_test.h"
|
||||
|
||||
#define TEST_BUFQUEUE_MSG0_SIZE 8
|
||||
#define TEST_BUFQUEUE_BUF0_SIZE 16
|
||||
#define TEST_BUFQUEUE_MSG_MAX 8
|
||||
|
||||
static ktask_t *task_0_test;
|
||||
static char g_test_send_msg0[TEST_BUFQUEUE_MSG0_SIZE] = {0};
|
||||
static char g_test_bufqueue_buf0[TEST_BUFQUEUE_MSG0_SIZE] = {0};
|
||||
static kbuf_queue_t g_test_bufqueue0;
|
||||
|
||||
static void buf_queue_flush_param_test(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
ksem_t sem;
|
||||
|
||||
ret = krhino_buf_queue_flush(NULL);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_NULL_PTR);
|
||||
|
||||
krhino_sem_create(& sem, "test_sem ", 0);
|
||||
ret = krhino_buf_queue_flush((kbuf_queue_t *)&sem);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_KOBJ_TYPE_ERR);
|
||||
krhino_sem_del(&sem);
|
||||
}
|
||||
|
||||
static void task_queue0_entry(void *arg)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
while (1) {
|
||||
ret = krhino_buf_queue_create(&g_test_bufqueue0, "test_bufqueue0",
|
||||
g_test_bufqueue_buf0,
|
||||
TEST_BUFQUEUE_BUF0_SIZE, TEST_BUFQUEUE_MSG_MAX);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_SUCCESS);
|
||||
|
||||
/* check krhino_buf_queue_flush param */
|
||||
buf_queue_flush_param_test();
|
||||
|
||||
ret = krhino_buf_queue_send(&g_test_bufqueue0, g_test_send_msg0,
|
||||
TEST_BUFQUEUE_MSG_MAX);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_SUCCESS);
|
||||
|
||||
ret = krhino_buf_queue_send(&g_test_bufqueue0, g_test_send_msg0,
|
||||
TEST_BUFQUEUE_MSG_MAX);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_BUF_QUEUE_FULL);
|
||||
|
||||
ret = krhino_buf_queue_flush(&g_test_bufqueue0);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_SUCCESS);
|
||||
|
||||
ret = krhino_buf_queue_send(&g_test_bufqueue0, g_test_send_msg0,
|
||||
TEST_BUFQUEUE_MSG_MAX);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_SUCCESS);
|
||||
|
||||
ret = krhino_buf_queue_del(&g_test_bufqueue0);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_SUCCESS);
|
||||
|
||||
if (test_case_check_err == 0) {
|
||||
test_case_success++;
|
||||
PRINT_RESULT("buf queue flush", PASS);
|
||||
} else {
|
||||
test_case_check_err = 0;
|
||||
test_case_fail++;
|
||||
PRINT_RESULT("buf queue flush", FAIL);
|
||||
}
|
||||
|
||||
next_test_case_notify();
|
||||
krhino_task_dyn_del(task_0_test);
|
||||
}
|
||||
}
|
||||
|
||||
kstat_t task_buf_queue_flush_test(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
ret = krhino_task_dyn_create(&task_0_test, "task_bufqueue0_test", 0, 10,
|
||||
0, TASK_TEST_STACK_SIZE, task_queue0_entry, 1);
|
||||
BUFQUEUE_VAL_CHK((ret == RHINO_SUCCESS) || (ret == RHINO_STOPPED));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <k_api.h>
|
||||
#include <test_fw.h>
|
||||
|
||||
#include "buf_queue_test.h"
|
||||
|
||||
#define TEST_BUFQUEUE_MSG0_SIZE 8
|
||||
#define TEST_BUFQUEUE_BUF0_SIZE 16
|
||||
#define TEST_BUFQUEUE_MSG_MAX 8
|
||||
|
||||
static ktask_t *task_0_test;
|
||||
static char g_test_send_msg0[TEST_BUFQUEUE_MSG0_SIZE];
|
||||
static char g_test_bufqueue_buf0[TEST_BUFQUEUE_MSG0_SIZE];
|
||||
static kbuf_queue_t g_test_bufqueue0;
|
||||
|
||||
static void buf_queue_info_get_param_test(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
kbuf_queue_info_t info;
|
||||
ksem_t sem;
|
||||
|
||||
ret = krhino_buf_queue_info_get(NULL, &info);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_NULL_PTR);
|
||||
|
||||
ret = krhino_buf_queue_info_get(&g_test_bufqueue0, NULL);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_NULL_PTR);
|
||||
|
||||
krhino_sem_create(& sem, "test_sem ", 0);
|
||||
ret = krhino_buf_queue_info_get((kbuf_queue_t *)&sem, &info);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_KOBJ_TYPE_ERR);
|
||||
krhino_sem_del(&sem);
|
||||
}
|
||||
|
||||
static void task_queue0_entry(void *arg)
|
||||
{
|
||||
kstat_t ret;
|
||||
kbuf_queue_info_t info;
|
||||
|
||||
while (1) {
|
||||
ret = krhino_buf_queue_create(&g_test_bufqueue0, "test_bufqueue0",
|
||||
g_test_bufqueue_buf0,
|
||||
TEST_BUFQUEUE_BUF0_SIZE, TEST_BUFQUEUE_MSG_MAX);
|
||||
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_SUCCESS);
|
||||
|
||||
/* check krhino_buf_queue_info_get param */
|
||||
buf_queue_info_get_param_test();
|
||||
|
||||
ret = krhino_buf_queue_info_get(&g_test_bufqueue0, &info);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_SUCCESS);
|
||||
BUFQUEUE_VAL_CHK((info.free_buf_size == TEST_BUFQUEUE_BUF0_SIZE) &&
|
||||
(info.buf_size == TEST_BUFQUEUE_BUF0_SIZE));
|
||||
|
||||
ret = krhino_buf_queue_send(&g_test_bufqueue0, g_test_send_msg0,
|
||||
TEST_BUFQUEUE_MSG_MAX);
|
||||
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_SUCCESS);
|
||||
|
||||
|
||||
ret = krhino_buf_queue_info_get(&g_test_bufqueue0, &info);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_SUCCESS);
|
||||
|
||||
BUFQUEUE_VAL_CHK(info.free_buf_size == (TEST_BUFQUEUE_BUF0_SIZE -
|
||||
TEST_BUFQUEUE_MSG0_SIZE - 1) &&
|
||||
(info.buf_size == TEST_BUFQUEUE_BUF0_SIZE));
|
||||
|
||||
if (test_case_check_err == 0) {
|
||||
test_case_success++;
|
||||
PRINT_RESULT("buf queue info get", PASS);
|
||||
} else {
|
||||
test_case_check_err = 0;
|
||||
test_case_fail++;
|
||||
PRINT_RESULT("buf queue info get", FAIL);
|
||||
}
|
||||
|
||||
next_test_case_notify();
|
||||
krhino_task_dyn_del(task_0_test);
|
||||
}
|
||||
}
|
||||
|
||||
kstat_t task_buf_queue_info_get_test(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
ret = krhino_task_dyn_create(&task_0_test, "task_bufqueue0_test", 0, 10,
|
||||
0, TASK_TEST_STACK_SIZE, task_queue0_entry, 1);
|
||||
BUFQUEUE_VAL_CHK((ret == RHINO_SUCCESS) || (ret == RHINO_STOPPED));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
281
Living_SDK/kernel/rhino/test/core/buf_queue/buf_queue_recv.c
Normal file
281
Living_SDK/kernel/rhino/test/core/buf_queue/buf_queue_recv.c
Normal file
|
|
@ -0,0 +1,281 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <k_api.h>
|
||||
#include <test_fw.h>
|
||||
|
||||
#include "buf_queue_test.h"
|
||||
|
||||
#define TEST_BUFQUEUE_MSG0_SIZE TEST_BUFQUEUE_MSG_MAX+1u
|
||||
#define TEST_BUFQUEUE_BUF0_ERR_SIZE 43
|
||||
#define TEST_BUFQUEUE_BUF0_SIZE 48
|
||||
#define TEST_BUFQUEUE_MSG_NUM 3
|
||||
#define TEST_BUFQUEUE_MSG_MAX (TEST_BUFQUEUE_BUF0_SIZE/TEST_BUFQUEUE_MSG_NUM)-sizeof(size_t)
|
||||
/* four char here */
|
||||
static char send_char[TEST_BUFQUEUE_MSG_NUM + 1] = "aos";
|
||||
|
||||
#define TEST_BUFQUEUE_RCV_TASK_RPI 10
|
||||
#define TEST_BUFQUEUE_SND_TASK_HIGH_RPI 9
|
||||
#define TEST_BUFQUEUE_SND_TASK_LOW_RPI 11
|
||||
|
||||
static ktask_t *task_0_test;
|
||||
static ktask_t *task_1_test;
|
||||
static ktask_t *task_2_test;
|
||||
static char g_test_send_msg0[TEST_BUFQUEUE_MSG0_SIZE] = {0};
|
||||
static char g_test_send_msg1[TEST_BUFQUEUE_MSG0_SIZE] = {0};
|
||||
static char g_test_recv_msg0[TEST_BUFQUEUE_MSG0_SIZE] = {0};
|
||||
static char g_test_bufqueue_buf0[TEST_BUFQUEUE_BUF0_SIZE] = {0};
|
||||
static size_t g_test_bufqueue_buf1[2] = {0};
|
||||
|
||||
static kbuf_queue_t g_test_bufqueue0;
|
||||
static kbuf_queue_t g_test_bufqueue1;
|
||||
|
||||
static void buf_queue_recv_param_test(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
size_t size;
|
||||
ksem_t sem;
|
||||
|
||||
memset(&sem, 0, sizeof(ksem_t));
|
||||
|
||||
ret = krhino_buf_queue_recv(NULL, RHINO_WAIT_FOREVER, &g_test_recv_msg0, &size);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_NULL_PTR);
|
||||
|
||||
ret = krhino_buf_queue_recv(&g_test_bufqueue0, RHINO_WAIT_FOREVER, NULL, &size);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_NULL_PTR);
|
||||
|
||||
ret = krhino_buf_queue_recv(&g_test_bufqueue0, RHINO_WAIT_FOREVER,
|
||||
&g_test_recv_msg0, NULL);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_NULL_PTR);
|
||||
|
||||
krhino_sem_create(& sem, "test_sem ", 0);
|
||||
ret = krhino_buf_queue_recv((kbuf_queue_t *)&sem, RHINO_WAIT_FOREVER,
|
||||
&g_test_recv_msg0, &size);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_KOBJ_TYPE_ERR);
|
||||
krhino_sem_del(&sem);
|
||||
}
|
||||
|
||||
static void buf_queue_send_param_test(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
ksem_t sem;
|
||||
|
||||
memset(&sem, 0, sizeof(ksem_t));
|
||||
|
||||
ret = krhino_buf_queue_send(&g_test_bufqueue0, NULL, TEST_BUFQUEUE_MSG_MAX);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_NULL_PTR);
|
||||
|
||||
|
||||
ret = krhino_buf_queue_send(NULL, g_test_send_msg0, TEST_BUFQUEUE_MSG_MAX);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_NULL_PTR);
|
||||
|
||||
ret = krhino_buf_queue_send(&g_test_bufqueue0, g_test_send_msg0,
|
||||
TEST_BUFQUEUE_MSG_MAX + 1);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_BUF_QUEUE_MSG_SIZE_OVERFLOW);
|
||||
|
||||
|
||||
ret = krhino_sem_create(&sem, "test_sem ", 0);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_SUCCESS);
|
||||
|
||||
g_test_bufqueue0.blk_obj.obj_type = RHINO_OBJ_TYPE_NONE;
|
||||
ret = krhino_buf_queue_send(&g_test_bufqueue0, g_test_send_msg0,
|
||||
TEST_BUFQUEUE_MSG_MAX);
|
||||
g_test_bufqueue0.blk_obj.obj_type = RHINO_BUF_QUEUE_OBJ_TYPE;
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_KOBJ_TYPE_ERR);
|
||||
|
||||
ret = krhino_buf_queue_send((kbuf_queue_t *)&sem, g_test_send_msg0, 0);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_KOBJ_TYPE_ERR);
|
||||
krhino_sem_del(&sem);
|
||||
}
|
||||
|
||||
|
||||
static void task_queue1_entry(void *arg)
|
||||
{
|
||||
kstat_t ret;
|
||||
kbuf_queue_info_t info;
|
||||
|
||||
while (1) {
|
||||
memset(g_test_send_msg0, 'y', TEST_BUFQUEUE_MSG_MAX);
|
||||
ret = krhino_buf_queue_send(&g_test_bufqueue0, g_test_send_msg0,
|
||||
TEST_BUFQUEUE_MSG_MAX);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_SUCCESS);
|
||||
|
||||
memset(g_test_send_msg0, 'o', TEST_BUFQUEUE_MSG_MAX);
|
||||
ret = krhino_buf_queue_send(&g_test_bufqueue0, g_test_send_msg0,
|
||||
TEST_BUFQUEUE_MSG_MAX);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_SUCCESS);
|
||||
|
||||
memset(g_test_send_msg0, 's', TEST_BUFQUEUE_MSG_MAX);
|
||||
ret = krhino_buf_queue_send(&g_test_bufqueue0, g_test_send_msg0,
|
||||
TEST_BUFQUEUE_MSG_MAX);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_SUCCESS);
|
||||
|
||||
krhino_task_dyn_del(task_1_test);
|
||||
}
|
||||
}
|
||||
|
||||
static void task_queue2_entry(void *arg)
|
||||
{
|
||||
kstat_t ret;
|
||||
kbuf_queue_info_t info;
|
||||
size_t count = 0;
|
||||
|
||||
while (1) {
|
||||
|
||||
memset(g_test_send_msg1, 's', TEST_BUFQUEUE_MSG_MAX);
|
||||
ret = krhino_buf_queue_send(&g_test_bufqueue0, g_test_send_msg1,
|
||||
TEST_BUFQUEUE_MSG_MAX);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_SUCCESS);
|
||||
count++;
|
||||
|
||||
memset(g_test_send_msg1, 'o', TEST_BUFQUEUE_MSG_MAX);
|
||||
ret = krhino_buf_queue_send(&g_test_bufqueue0, g_test_send_msg1,
|
||||
TEST_BUFQUEUE_MSG_MAX);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_SUCCESS);
|
||||
count++;
|
||||
|
||||
|
||||
memset(g_test_send_msg1, 'y', TEST_BUFQUEUE_MSG_MAX);
|
||||
ret = krhino_buf_queue_send(&g_test_bufqueue0, g_test_send_msg1,
|
||||
TEST_BUFQUEUE_MSG_MAX);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_SUCCESS);
|
||||
count++;
|
||||
|
||||
|
||||
memset(g_test_send_msg1, 'w', TEST_BUFQUEUE_MSG_MAX);
|
||||
ret = krhino_buf_queue_send(&g_test_bufqueue0, g_test_send_msg1,
|
||||
TEST_BUFQUEUE_MSG_MAX);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_BUF_QUEUE_FULL);
|
||||
|
||||
krhino_buf_queue_info_get(&g_test_bufqueue0, &info);
|
||||
|
||||
BUFQUEUE_VAL_CHK(count == info.cur_num);
|
||||
krhino_task_dyn_del(task_2_test);
|
||||
}
|
||||
}
|
||||
|
||||
static void task_queue0_entry(void *arg)
|
||||
{
|
||||
kstat_t ret;
|
||||
size_t size;
|
||||
int count = 0;
|
||||
size_t msg;
|
||||
|
||||
/* err param test */
|
||||
ret = krhino_buf_queue_create(&g_test_bufqueue0, "test_bufqueue0",
|
||||
(void *)g_test_bufqueue_buf0,
|
||||
TEST_BUFQUEUE_BUF0_SIZE, 0);
|
||||
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_INV_PARAM);
|
||||
|
||||
ret = krhino_buf_queue_create(&g_test_bufqueue0, "test_bufqueue0",
|
||||
(void *)g_test_bufqueue_buf0,
|
||||
TEST_BUFQUEUE_BUF0_SIZE, TEST_BUFQUEUE_MSG_MAX);
|
||||
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_SUCCESS);
|
||||
|
||||
ret = krhino_fix_buf_queue_create(&g_test_bufqueue1, "test_bufqueue1",
|
||||
(void *)g_test_bufqueue_buf1, sizeof(size_t), 2);
|
||||
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_SUCCESS);
|
||||
|
||||
msg = 0x11;
|
||||
ret = krhino_buf_queue_send(&g_test_bufqueue1, &msg, sizeof(size_t));
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_SUCCESS);
|
||||
|
||||
ret = krhino_buf_queue_send(&g_test_bufqueue1, &msg, sizeof(size_t));
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_SUCCESS);
|
||||
|
||||
ret = krhino_buf_queue_send(&g_test_bufqueue1, &msg, sizeof(size_t));
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_BUF_QUEUE_FULL);
|
||||
|
||||
krhino_buf_queue_recv(&g_test_bufqueue1, RHINO_NO_WAIT, &msg, &size);
|
||||
krhino_buf_queue_recv(&g_test_bufqueue1, RHINO_NO_WAIT, &msg, &size);
|
||||
|
||||
ret = krhino_buf_queue_recv(&g_test_bufqueue1, 1, &msg, &size);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_BLK_TIMEOUT);
|
||||
|
||||
/* check krhino_buf_queue_recv */
|
||||
buf_queue_recv_param_test();
|
||||
|
||||
buf_queue_send_param_test();
|
||||
|
||||
/* check RHINO_NO_WAIT */
|
||||
ret = krhino_buf_queue_recv(&g_test_bufqueue0, RHINO_NO_WAIT, &g_test_recv_msg0,
|
||||
&size);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_NO_PEND_WAIT);
|
||||
|
||||
/* check sched disalbe */
|
||||
ret = krhino_sched_disable();
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_SUCCESS);
|
||||
ret = krhino_buf_queue_recv(&g_test_bufqueue0, RHINO_WAIT_FOREVER,
|
||||
&g_test_recv_msg0, &size);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_SCHED_DISABLE);
|
||||
ret = krhino_sched_enable();
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_SUCCESS);
|
||||
|
||||
ret = krhino_task_dyn_create(&task_1_test, "task_bufqueue1_test", 0,
|
||||
TEST_BUFQUEUE_SND_TASK_LOW_RPI,
|
||||
0, TASK_TEST_STACK_SIZE, task_queue1_entry, 1);
|
||||
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_SUCCESS);
|
||||
|
||||
do {
|
||||
ret = krhino_buf_queue_recv(&g_test_bufqueue0, RHINO_WAIT_FOREVER,
|
||||
g_test_recv_msg0, &size);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_SUCCESS);
|
||||
|
||||
memset(g_test_send_msg0, send_char[count], TEST_BUFQUEUE_MSG_MAX);
|
||||
ret = memcmp(g_test_send_msg0, g_test_recv_msg0, size);
|
||||
count ++;
|
||||
} while (count < TEST_BUFQUEUE_MSG_NUM);
|
||||
|
||||
|
||||
ret = krhino_task_dyn_create(&task_2_test, "task_bufqueue2_test", 0,
|
||||
TEST_BUFQUEUE_SND_TASK_HIGH_RPI,
|
||||
0, TASK_TEST_STACK_SIZE, task_queue2_entry, 1);
|
||||
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_SUCCESS);
|
||||
|
||||
krhino_task_sleep(RHINO_CONFIG_TICKS_PER_SECOND / 10);
|
||||
|
||||
count = 0;
|
||||
|
||||
do {
|
||||
ret = krhino_buf_queue_recv(&g_test_bufqueue0, RHINO_WAIT_FOREVER,
|
||||
g_test_recv_msg0, &size);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_SUCCESS);
|
||||
|
||||
memset(g_test_send_msg1, send_char[count], TEST_BUFQUEUE_MSG_MAX);
|
||||
ret = memcmp(g_test_send_msg1, g_test_recv_msg0, size);
|
||||
count ++;
|
||||
} while (count < TEST_BUFQUEUE_MSG_NUM);
|
||||
|
||||
|
||||
if (test_case_check_err == 0) {
|
||||
test_case_success++;
|
||||
PRINT_RESULT("buf queue recv", PASS);
|
||||
} else {
|
||||
test_case_check_err = 0;
|
||||
test_case_fail++;
|
||||
PRINT_RESULT("buf queue recv", FAIL);
|
||||
}
|
||||
|
||||
next_test_case_notify();
|
||||
krhino_task_dyn_del(task_0_test);
|
||||
}
|
||||
|
||||
kstat_t task_buf_queue_recv_test(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
test_case_check_err = 0;
|
||||
ret = krhino_task_dyn_create(&task_0_test, "task_bufqueue0_test", 0,
|
||||
TEST_BUFQUEUE_RCV_TASK_RPI,
|
||||
0, TASK_TEST_STACK_SIZE, task_queue0_entry, 1);
|
||||
BUFQUEUE_VAL_CHK(ret == RHINO_SUCCESS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
28
Living_SDK/kernel/rhino/test/core/buf_queue/buf_queue_test.c
Normal file
28
Living_SDK/kernel/rhino/test/core/buf_queue/buf_queue_test.c
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
#include <test_fw.h>
|
||||
|
||||
#include "buf_queue_test.h"
|
||||
|
||||
void buf_queue_test(void)
|
||||
{
|
||||
task_buf_queue_recv_test();
|
||||
next_test_case_wait();
|
||||
|
||||
task_buf_queue_del_test();
|
||||
next_test_case_wait();
|
||||
|
||||
task_buf_queue_flush_test();
|
||||
next_test_case_wait();
|
||||
|
||||
task_buf_queue_info_get_test();
|
||||
next_test_case_wait();
|
||||
|
||||
task_buf_queue_dyn_create_test();
|
||||
next_test_case_wait();
|
||||
|
||||
}
|
||||
|
||||
27
Living_SDK/kernel/rhino/test/core/buf_queue/buf_queue_test.h
Normal file
27
Living_SDK/kernel/rhino/test/core/buf_queue/buf_queue_test.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef BUF_QUEUE_TEST_H
|
||||
#define BUF_QUEUE_TEST_H
|
||||
|
||||
#define TASK_TEST_STACK_SIZE 256
|
||||
|
||||
#define BUFQUEUE_VAL_CHK(value) do {if ((int)(value) == 0) \
|
||||
{ \
|
||||
test_case_critical_enter(); \
|
||||
test_case_check_err++; \
|
||||
test_case_critical_exit(); \
|
||||
printf("buf queue test is [FAIL %d],file %s, func %s, line %d\n", \
|
||||
(int)++test_case_check_err, __FILE__, __FUNCTION__, __LINE__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
kstat_t task_buf_queue_send_test(void);
|
||||
kstat_t task_buf_queue_recv_test(void);
|
||||
kstat_t task_buf_queue_del_test(void);
|
||||
kstat_t task_buf_queue_flush_test(void);
|
||||
kstat_t task_buf_queue_info_get_test(void);
|
||||
kstat_t task_buf_queue_dyn_create_test(void);
|
||||
|
||||
#endif /* BUF_QUEUE_TEST_H */
|
||||
23
Living_SDK/kernel/rhino/test/core/combination/comb_test.c
Executable file
23
Living_SDK/kernel/rhino/test/core/combination/comb_test.c
Executable file
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
#include <test_fw.h>
|
||||
#include "comb_test.h"
|
||||
|
||||
static const test_case_t comb_case_runner[] = {
|
||||
sem_event_coopr_test,
|
||||
sem_buf_queue_coopr_test,
|
||||
sem_mutex_coopr_test,
|
||||
NULL
|
||||
};
|
||||
|
||||
void comb_test(void)
|
||||
{
|
||||
if (test_case_register((test_case_t *)comb_case_runner) == 0) {
|
||||
test_case_run();
|
||||
test_case_unregister();
|
||||
}
|
||||
}
|
||||
|
||||
18
Living_SDK/kernel/rhino/test/core/combination/comb_test.h
Executable file
18
Living_SDK/kernel/rhino/test/core/combination/comb_test.h
Executable file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef COMB_TEST_H
|
||||
#define COMB_TEST_H
|
||||
|
||||
#define TASK_COMB_PRI 16
|
||||
#define TASK_TEST_STACK_SIZE 256
|
||||
|
||||
void comb_test(void);
|
||||
void sem_queue_coopr_test(void);
|
||||
void sem_event_coopr_test(void);
|
||||
void sem_buf_queue_coopr_test(void);
|
||||
void sem_mutex_coopr_test(void);
|
||||
|
||||
#endif /* SEM_TEST_H */
|
||||
|
||||
90
Living_SDK/kernel/rhino/test/core/combination/sem_event.c
Normal file
90
Living_SDK/kernel/rhino/test/core/combination/sem_event.c
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
#include <test_fw.h>
|
||||
#include "comb_test.h"
|
||||
|
||||
static ktask_t *task_sem;
|
||||
static ktask_t *task_ksem_trigger;
|
||||
static ktask_t *task_event_trigger;
|
||||
static ksem_t *sem_comb;
|
||||
static kevent_t event_sem;
|
||||
|
||||
#define MODULE_NAME "sem_event_opr"
|
||||
|
||||
|
||||
static void task_sem_opr_entry(void *arg)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
ret = krhino_sem_take(sem_comb, RHINO_WAIT_FOREVER);
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
test_case_success++;
|
||||
PRINT_RESULT(MODULE_NAME, PASS);
|
||||
} else {
|
||||
test_case_fail++;
|
||||
PRINT_RESULT(MODULE_NAME, FAIL);
|
||||
}
|
||||
|
||||
next_test_case_notify();
|
||||
krhino_sem_dyn_del(sem_comb);
|
||||
krhino_task_dyn_del(krhino_cur_task_get());
|
||||
}
|
||||
|
||||
static void task_ksem_trigger_opr_entry(void *arg)
|
||||
{
|
||||
kstat_t ret;
|
||||
uint32_t flag;
|
||||
|
||||
ret = krhino_event_get(&event_sem, 0x1, RHINO_AND_CLEAR, &flag,
|
||||
RHINO_WAIT_FOREVER);
|
||||
if ((ret == RHINO_SUCCESS) && (flag == 0x3)) {
|
||||
krhino_sem_give(sem_comb);
|
||||
krhino_event_del(&event_sem);
|
||||
krhino_task_dyn_del(krhino_cur_task_get());
|
||||
}
|
||||
}
|
||||
|
||||
static void task_event_trigger_opr_entry(void *arg)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
ret = krhino_event_set(&event_sem, 0x1, RHINO_OR);
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
krhino_task_dyn_del(krhino_cur_task_get());
|
||||
}
|
||||
}
|
||||
|
||||
void sem_event_coopr_test(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
krhino_sem_dyn_create(&sem_comb, "semtest", 0);
|
||||
krhino_event_create(&event_sem, "eventtest", 0x2);
|
||||
|
||||
ret = krhino_task_dyn_create(&task_sem, MODULE_NAME, 0, TASK_COMB_PRI,
|
||||
0, TASK_TEST_STACK_SIZE, task_sem_opr_entry, 1);
|
||||
if ((ret != RHINO_SUCCESS) && (ret != RHINO_STOPPED)) {
|
||||
test_case_fail++;
|
||||
PRINT_RESULT(MODULE_NAME, FAIL);
|
||||
}
|
||||
|
||||
ret = krhino_task_dyn_create(&task_ksem_trigger, MODULE_NAME, 0,
|
||||
TASK_COMB_PRI + 1,
|
||||
0, TASK_TEST_STACK_SIZE, task_ksem_trigger_opr_entry, 1);
|
||||
if ((ret != RHINO_SUCCESS) && (ret != RHINO_STOPPED)) {
|
||||
test_case_fail++;
|
||||
PRINT_RESULT(MODULE_NAME, FAIL);
|
||||
}
|
||||
|
||||
ret = krhino_task_dyn_create(&task_event_trigger, MODULE_NAME, 0,
|
||||
TASK_COMB_PRI + 2,
|
||||
0, TASK_TEST_STACK_SIZE, task_event_trigger_opr_entry, 1);
|
||||
if ((ret != RHINO_SUCCESS) && (ret != RHINO_STOPPED)) {
|
||||
test_case_fail++;
|
||||
PRINT_RESULT(MODULE_NAME, FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
76
Living_SDK/kernel/rhino/test/core/combination/sem_mutex.c
Normal file
76
Living_SDK/kernel/rhino/test/core/combination/sem_mutex.c
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
#include <test_fw.h>
|
||||
#include "comb_test.h"
|
||||
|
||||
static ktask_t *task_sem;
|
||||
static ktask_t *task_mutex;
|
||||
static ksem_t *sem_comb;
|
||||
static kmutex_t mutex_comb;
|
||||
|
||||
#define MODULE_NAME "sem_mutex_opr"
|
||||
|
||||
static void task_sem_opr_entry(void *arg)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
ret = krhino_sem_take(sem_comb, RHINO_WAIT_FOREVER);
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
test_case_success++;
|
||||
PRINT_RESULT(MODULE_NAME, PASS);
|
||||
} else {
|
||||
test_case_fail++;
|
||||
PRINT_RESULT(MODULE_NAME, FAIL);
|
||||
}
|
||||
|
||||
next_test_case_notify();
|
||||
krhino_sem_dyn_del(sem_comb);
|
||||
krhino_mutex_del(&mutex_comb);
|
||||
krhino_task_dyn_del(krhino_cur_task_get());
|
||||
}
|
||||
|
||||
static void task_mutex_opr_entry(void *arg)
|
||||
{
|
||||
krhino_mutex_lock(&mutex_comb, RHINO_WAIT_FOREVER);
|
||||
krhino_mutex_lock(&mutex_comb, RHINO_WAIT_FOREVER);
|
||||
krhino_mutex_lock(&mutex_comb, RHINO_WAIT_FOREVER);
|
||||
krhino_mutex_lock(&mutex_comb, RHINO_WAIT_FOREVER);
|
||||
krhino_mutex_lock(&mutex_comb, RHINO_WAIT_FOREVER);
|
||||
krhino_mutex_lock(&mutex_comb, RHINO_WAIT_FOREVER);
|
||||
|
||||
krhino_mutex_unlock(&mutex_comb);
|
||||
krhino_mutex_unlock(&mutex_comb);
|
||||
krhino_mutex_unlock(&mutex_comb);
|
||||
krhino_mutex_unlock(&mutex_comb);
|
||||
krhino_mutex_unlock(&mutex_comb);
|
||||
krhino_mutex_unlock(&mutex_comb);
|
||||
|
||||
krhino_sem_give(sem_comb);
|
||||
krhino_task_dyn_del(krhino_cur_task_get());
|
||||
}
|
||||
|
||||
void sem_mutex_coopr_test(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
krhino_sem_dyn_create(&sem_comb, "semtest", 0);
|
||||
krhino_mutex_create(&mutex_comb, "mutex");
|
||||
|
||||
ret = krhino_task_dyn_create(&task_sem, MODULE_NAME, 0, TASK_COMB_PRI,
|
||||
0, TASK_TEST_STACK_SIZE, task_sem_opr_entry, 1);
|
||||
if ((ret != RHINO_SUCCESS) && (ret != RHINO_STOPPED)) {
|
||||
test_case_fail++;
|
||||
PRINT_RESULT(MODULE_NAME, FAIL);
|
||||
}
|
||||
|
||||
ret = krhino_task_dyn_create(&task_mutex, MODULE_NAME, 0, TASK_COMB_PRI + 1,
|
||||
0, TASK_TEST_STACK_SIZE, task_mutex_opr_entry, 1);
|
||||
if ((ret != RHINO_SUCCESS) && (ret != RHINO_STOPPED)) {
|
||||
test_case_fail++;
|
||||
PRINT_RESULT(MODULE_NAME, FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
#include <test_fw.h>
|
||||
#include "comb_test.h"
|
||||
|
||||
static ktask_t *task_sem;
|
||||
static ktask_t *task_buf_queue;
|
||||
static ktask_t *task_buf_queue_trigger;
|
||||
|
||||
static ksem_t *test_sem;
|
||||
static kbuf_queue_t test_buf_queue;
|
||||
static uint8_t buf_queue_test_buf[1];
|
||||
static uint8_t buf_queue_recv[1];
|
||||
static uint8_t buf_queue_send[1];
|
||||
|
||||
#define MODULE_NAME "sem_queue_buf_opr"
|
||||
|
||||
static void task_sem_opr_entry(void *arg)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
ret = krhino_sem_take(test_sem, RHINO_WAIT_FOREVER);
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
test_case_success++;
|
||||
PRINT_RESULT(MODULE_NAME, PASS);
|
||||
} else {
|
||||
test_case_fail++;
|
||||
PRINT_RESULT(MODULE_NAME, FAIL);
|
||||
}
|
||||
|
||||
next_test_case_notify();
|
||||
krhino_sem_dyn_del(test_sem);
|
||||
krhino_buf_queue_del(&test_buf_queue);
|
||||
krhino_task_dyn_del(krhino_cur_task_get());
|
||||
}
|
||||
|
||||
static void task_buf_queue_entry(void *arg)
|
||||
{
|
||||
kstat_t ret;
|
||||
size_t size;
|
||||
|
||||
ret = krhino_buf_queue_recv(&test_buf_queue, RHINO_WAIT_FOREVER,
|
||||
(void *)buf_queue_recv, &size);
|
||||
if ((ret == RHINO_SUCCESS) && (*(uint8_t *)buf_queue_recv == 0x5a)) {
|
||||
krhino_sem_give(test_sem);
|
||||
krhino_task_dyn_del(krhino_cur_task_get());
|
||||
}
|
||||
}
|
||||
|
||||
static void task_buf_queue_trigger_entry(void *arg)
|
||||
{
|
||||
*(uint8_t *)buf_queue_send = 0x5a;
|
||||
|
||||
krhino_buf_queue_send(&test_buf_queue, (void *)buf_queue_send, 1);
|
||||
krhino_task_dyn_del(krhino_cur_task_get());
|
||||
}
|
||||
|
||||
void sem_buf_queue_coopr_test(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
krhino_sem_dyn_create(&test_sem, "semtest", 0);
|
||||
krhino_buf_queue_create(&test_buf_queue, "bugqueue", (void *)buf_queue_test_buf,
|
||||
8, 1);
|
||||
|
||||
ret = krhino_task_dyn_create(&task_sem, MODULE_NAME, 0, TASK_COMB_PRI,
|
||||
0, TASK_TEST_STACK_SIZE, task_sem_opr_entry, 1);
|
||||
if ((ret != RHINO_SUCCESS) && (ret != RHINO_STOPPED)) {
|
||||
test_case_fail++;
|
||||
PRINT_RESULT(MODULE_NAME, FAIL);
|
||||
}
|
||||
|
||||
ret = krhino_task_dyn_create(&task_buf_queue, MODULE_NAME, 0, TASK_COMB_PRI + 1,
|
||||
0, TASK_TEST_STACK_SIZE, task_buf_queue_entry, 1);
|
||||
if ((ret != RHINO_SUCCESS) && (ret != RHINO_STOPPED)) {
|
||||
test_case_fail++;
|
||||
PRINT_RESULT(MODULE_NAME, FAIL);
|
||||
}
|
||||
|
||||
ret = krhino_task_dyn_create(&task_buf_queue_trigger, MODULE_NAME, 0,
|
||||
TASK_COMB_PRI + 2,
|
||||
0, TASK_TEST_STACK_SIZE, task_buf_queue_trigger_entry, 1);
|
||||
if ((ret != RHINO_SUCCESS) && (ret != RHINO_STOPPED)) {
|
||||
test_case_fail++;
|
||||
PRINT_RESULT(MODULE_NAME, FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
54
Living_SDK/kernel/rhino/test/core/event/event_break.c
Normal file
54
Living_SDK/kernel/rhino/test/core/event/event_break.c
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
#include <test_fw.h>
|
||||
#include "event_test.h"
|
||||
|
||||
#define MODULE_NAME "event_break"
|
||||
|
||||
#define TEST_FLAG 0x5a5a5a5a
|
||||
|
||||
static uint8_t event_break_case1(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
ret = krhino_event_create(NULL, MODULE_NAME, TEST_FLAG);
|
||||
MYASSERT(ret == RHINO_NULL_PTR);
|
||||
|
||||
ret = krhino_event_create(&test_event, MODULE_NAME, TEST_FLAG);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
MYASSERT(test_event.blk_obj.obj_type == RHINO_EVENT_OBJ_TYPE);
|
||||
|
||||
test_event.blk_obj.obj_type = RHINO_OBJ_TYPE_NONE;
|
||||
ret = krhino_event_del(&test_event);
|
||||
MYASSERT(ret == RHINO_KOBJ_TYPE_ERR);
|
||||
|
||||
test_event.blk_obj.obj_type = RHINO_EVENT_OBJ_TYPE;
|
||||
ret = krhino_event_del(&test_event);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const test_func_t event_func_runner[] = {
|
||||
event_break_case1,
|
||||
NULL
|
||||
};
|
||||
|
||||
void event_break_test(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
task_event_entry_register(MODULE_NAME, (test_func_t *)event_func_runner,
|
||||
sizeof(event_func_runner) / sizeof(test_func_t));
|
||||
|
||||
ret = krhino_task_dyn_create(&task_event, MODULE_NAME, 0, TASK_EVENT_PRI,
|
||||
0, TASK_TEST_STACK_SIZE, task_event_entry, 1);
|
||||
if ((ret != RHINO_SUCCESS) && (ret != RHINO_STOPPED)) {
|
||||
test_case_fail++;
|
||||
PRINT_RESULT(MODULE_NAME, FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
322
Living_SDK/kernel/rhino/test/core/event/event_opr.c
Normal file
322
Living_SDK/kernel/rhino/test/core/event/event_opr.c
Normal file
|
|
@ -0,0 +1,322 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
#include <test_fw.h>
|
||||
#include "event_test.h"
|
||||
|
||||
#define MODULE_NAME "event_opr"
|
||||
#define MODULE_NAME_CO "event_coopr"
|
||||
|
||||
#define TEST_FLAG 0x5a5a5a5a
|
||||
#define CHK_AND_ALL_FLAG 0x5a5a5a5a
|
||||
#define CHK_AND_ONE_FLAG 0x00000002
|
||||
#define CHK_AND_ZERO_FLAG 0x00000000
|
||||
#define CHK_AND_PEND_FLAG 0x5a5a5a55
|
||||
|
||||
static uint8_t event_opr_case1(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
uint32_t actl_flags;
|
||||
CPSR_ALLOC();
|
||||
|
||||
ret = krhino_event_create(&test_event, MODULE_NAME, TEST_FLAG);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
MYASSERT(test_event.flags == TEST_FLAG);
|
||||
|
||||
/* check event AND FLAG */
|
||||
RHINO_CRITICAL_ENTER();
|
||||
test_event.blk_obj.obj_type = RHINO_SEM_OBJ_TYPE;
|
||||
RHINO_CRITICAL_EXIT();
|
||||
ret = krhino_event_set(&test_event, TEST_FLAG, RHINO_OR);
|
||||
MYASSERT(ret == RHINO_KOBJ_TYPE_ERR);
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
test_event.blk_obj.obj_type = RHINO_EVENT_OBJ_TYPE;
|
||||
RHINO_CRITICAL_EXIT();
|
||||
|
||||
ret = krhino_event_set(&test_event, TEST_FLAG, RHINO_AND);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
MYASSERT(test_event.flags == TEST_FLAG);
|
||||
|
||||
ret = krhino_event_set(&test_event, TEST_FLAG, RHINO_OR);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
MYASSERT(test_event.flags == TEST_FLAG);
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
test_event.blk_obj.obj_type = RHINO_SEM_OBJ_TYPE;
|
||||
RHINO_CRITICAL_EXIT();
|
||||
ret = krhino_event_get(&test_event, CHK_AND_ALL_FLAG, RHINO_AND, &actl_flags,
|
||||
RHINO_NO_WAIT);
|
||||
MYASSERT(ret == RHINO_KOBJ_TYPE_ERR);
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
test_event.blk_obj.obj_type = RHINO_EVENT_OBJ_TYPE;
|
||||
RHINO_CRITICAL_EXIT();
|
||||
ret = krhino_event_get(&test_event, CHK_AND_ALL_FLAG, RHINO_AND, &actl_flags,
|
||||
RHINO_NO_WAIT);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
MYASSERT(actl_flags == TEST_FLAG);
|
||||
MYASSERT(test_event.flags == TEST_FLAG);
|
||||
|
||||
ret = krhino_event_get(&test_event, CHK_AND_ONE_FLAG, RHINO_AND, &actl_flags,
|
||||
RHINO_NO_WAIT);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
MYASSERT(actl_flags == TEST_FLAG);
|
||||
MYASSERT(test_event.flags == TEST_FLAG);
|
||||
|
||||
ret = krhino_event_get(&test_event, CHK_AND_ZERO_FLAG, RHINO_AND, &actl_flags,
|
||||
RHINO_NO_WAIT);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
MYASSERT(actl_flags == TEST_FLAG);
|
||||
MYASSERT(test_event.flags == TEST_FLAG);
|
||||
|
||||
ret = krhino_event_del(&test_event);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint8_t event_opr_case2(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
uint32_t actl_flags;
|
||||
|
||||
ret = krhino_event_create(&test_event, MODULE_NAME, TEST_FLAG);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
MYASSERT(test_event.flags == TEST_FLAG);
|
||||
|
||||
/* check event AND_CLEAR FLAG */
|
||||
ret = krhino_event_set(&test_event, TEST_FLAG, RHINO_OR);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
MYASSERT(test_event.flags == TEST_FLAG);
|
||||
|
||||
ret = krhino_event_get(&test_event, CHK_AND_ALL_FLAG, RHINO_AND_CLEAR,
|
||||
&actl_flags, RHINO_NO_WAIT);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
MYASSERT(actl_flags == TEST_FLAG);
|
||||
MYASSERT(test_event.flags == (TEST_FLAG & (~CHK_AND_ALL_FLAG)));
|
||||
|
||||
ret = krhino_event_set(&test_event, TEST_FLAG, RHINO_OR);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
MYASSERT(test_event.flags == TEST_FLAG);
|
||||
|
||||
ret = krhino_event_get(&test_event, CHK_AND_ONE_FLAG, RHINO_AND_CLEAR,
|
||||
&actl_flags, RHINO_NO_WAIT);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
MYASSERT(actl_flags == TEST_FLAG);
|
||||
MYASSERT(test_event.flags == (TEST_FLAG & (~CHK_AND_ONE_FLAG)));
|
||||
|
||||
ret = krhino_event_set(&test_event, TEST_FLAG, RHINO_OR);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
MYASSERT(test_event.flags == TEST_FLAG);
|
||||
|
||||
ret = krhino_event_get(&test_event, CHK_AND_ZERO_FLAG, RHINO_AND_CLEAR,
|
||||
&actl_flags, RHINO_NO_WAIT);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
MYASSERT(actl_flags == TEST_FLAG);
|
||||
MYASSERT(test_event.flags == (TEST_FLAG & (~CHK_AND_ZERO_FLAG)));
|
||||
|
||||
ret = krhino_event_del(&test_event);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint8_t event_opr_case3(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
uint32_t actl_flags;
|
||||
|
||||
ret = krhino_event_create(&test_event, MODULE_NAME, TEST_FLAG);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
MYASSERT(test_event.flags == TEST_FLAG);
|
||||
|
||||
/* check event OR FLAG */
|
||||
ret = krhino_event_set(&test_event, TEST_FLAG, RHINO_OR);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
MYASSERT(test_event.flags == TEST_FLAG);
|
||||
|
||||
ret = krhino_event_get(&test_event, CHK_AND_ALL_FLAG, RHINO_OR, &actl_flags,
|
||||
RHINO_NO_WAIT);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
MYASSERT(actl_flags == TEST_FLAG);
|
||||
MYASSERT(test_event.flags == TEST_FLAG);
|
||||
|
||||
ret = krhino_event_get(&test_event, CHK_AND_ONE_FLAG, RHINO_OR, &actl_flags,
|
||||
RHINO_NO_WAIT);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
MYASSERT(actl_flags == TEST_FLAG);
|
||||
MYASSERT(test_event.flags == TEST_FLAG);
|
||||
|
||||
ret = krhino_event_get(&test_event, CHK_AND_ZERO_FLAG, RHINO_OR, &actl_flags,
|
||||
RHINO_NO_WAIT);
|
||||
MYASSERT(ret == RHINO_NO_PEND_WAIT);
|
||||
|
||||
ret = krhino_event_del(&test_event);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint8_t event_opr_case4(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
uint32_t actl_flags;
|
||||
|
||||
ret = krhino_event_create(&test_event, MODULE_NAME, TEST_FLAG);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
MYASSERT(test_event.flags == TEST_FLAG);
|
||||
|
||||
/* check event OR_CLEAR FLAG */
|
||||
ret = krhino_event_set(&test_event, TEST_FLAG, RHINO_OR);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
MYASSERT(test_event.flags == TEST_FLAG);
|
||||
|
||||
ret = krhino_event_get(&test_event, CHK_AND_ALL_FLAG, RHINO_OR_CLEAR,
|
||||
&actl_flags, RHINO_NO_WAIT);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
MYASSERT(actl_flags == TEST_FLAG);
|
||||
MYASSERT(test_event.flags == (TEST_FLAG & (~CHK_AND_ALL_FLAG)));
|
||||
|
||||
ret = krhino_event_set(&test_event, TEST_FLAG, RHINO_OR);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
MYASSERT(test_event.flags == TEST_FLAG);
|
||||
|
||||
ret = krhino_event_get(&test_event, CHK_AND_ONE_FLAG, RHINO_OR_CLEAR,
|
||||
&actl_flags, RHINO_NO_WAIT);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
MYASSERT(actl_flags == TEST_FLAG);
|
||||
MYASSERT(test_event.flags == (TEST_FLAG & (~CHK_AND_ONE_FLAG)));
|
||||
|
||||
ret = krhino_event_set(&test_event, TEST_FLAG, RHINO_OR);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
MYASSERT(test_event.flags == TEST_FLAG);
|
||||
|
||||
ret = krhino_event_del(&test_event);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint8_t event_opr_case5(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
uint32_t actl_flags;
|
||||
|
||||
ret = krhino_event_create(&test_event, MODULE_NAME, TEST_FLAG);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
MYASSERT(test_event.flags == TEST_FLAG);
|
||||
|
||||
/* try to get event flag in case of sched disable */
|
||||
ret = krhino_event_set(&test_event, TEST_FLAG, RHINO_OR);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
MYASSERT(test_event.flags == TEST_FLAG);
|
||||
|
||||
krhino_sched_disable();
|
||||
|
||||
ret = krhino_event_get(&test_event, CHK_AND_PEND_FLAG, RHINO_AND, &actl_flags,
|
||||
RHINO_WAIT_FOREVER);
|
||||
MYASSERT(ret == RHINO_SCHED_DISABLE);
|
||||
|
||||
krhino_sched_enable();
|
||||
|
||||
ret = krhino_event_del(&test_event);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const test_func_t event_func_runner[] = {
|
||||
event_opr_case1,
|
||||
event_opr_case2,
|
||||
event_opr_case3,
|
||||
event_opr_case4,
|
||||
event_opr_case5,
|
||||
NULL
|
||||
};
|
||||
|
||||
void event_opr_test(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
task_event_entry_register(MODULE_NAME, (test_func_t *)event_func_runner,
|
||||
sizeof(event_func_runner) / sizeof(test_func_t));
|
||||
|
||||
ret = krhino_task_dyn_create(&task_event, MODULE_NAME, 0, TASK_EVENT_PRI,
|
||||
0, TASK_TEST_STACK_SIZE, task_event_entry, 1);
|
||||
if ((ret != RHINO_SUCCESS) && (ret != RHINO_STOPPED)) {
|
||||
test_case_fail++;
|
||||
PRINT_RESULT(MODULE_NAME, FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
static void task_event_co1_entry(void *arg)
|
||||
{
|
||||
kstat_t ret;
|
||||
uint32_t actl_flags;
|
||||
|
||||
while (1) {
|
||||
ret = krhino_event_get(&test_event, ~CHK_AND_ALL_FLAG, RHINO_AND, &actl_flags,
|
||||
RHINO_WAIT_FOREVER);
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
break;
|
||||
} else {
|
||||
test_case_fail++;
|
||||
PRINT_RESULT(MODULE_NAME_CO, FAIL);
|
||||
|
||||
krhino_event_del(&test_event);
|
||||
|
||||
next_test_case_notify();
|
||||
krhino_task_dyn_del(krhino_cur_task_get());
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
test_case_success++;
|
||||
PRINT_RESULT(MODULE_NAME_CO, PASS);
|
||||
|
||||
krhino_event_del(&test_event);
|
||||
|
||||
next_test_case_notify();
|
||||
krhino_task_dyn_del(krhino_cur_task_get());
|
||||
}
|
||||
|
||||
static void task_event_co2_entry(void *arg)
|
||||
{
|
||||
while (1) {
|
||||
krhino_event_set(&test_event, ~CHK_AND_ALL_FLAG, RHINO_OR);
|
||||
break;
|
||||
}
|
||||
|
||||
krhino_task_dyn_del(krhino_cur_task_get());
|
||||
}
|
||||
|
||||
void event_coopr_test(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
ret = krhino_event_create(&test_event, MODULE_NAME, TEST_FLAG);
|
||||
if (ret != RHINO_SUCCESS && test_event.flags != TEST_FLAG) {
|
||||
test_case_fail++;
|
||||
PRINT_RESULT(MODULE_NAME_CO, FAIL);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = krhino_task_dyn_create(&task_event_co1, MODULE_NAME, 0, TASK_EVENT_PRI,
|
||||
0, TASK_TEST_STACK_SIZE, task_event_co1_entry, 1);
|
||||
if ((ret != RHINO_SUCCESS) && (ret != RHINO_STOPPED)) {
|
||||
test_case_fail++;
|
||||
PRINT_RESULT(MODULE_NAME, FAIL);
|
||||
}
|
||||
|
||||
ret = krhino_task_dyn_create(&task_event_co2, MODULE_NAME, 0, TASK_EVENT_PRI + 1,
|
||||
0, TASK_TEST_STACK_SIZE, task_event_co2_entry, 1);
|
||||
if ((ret != RHINO_SUCCESS) && (ret != RHINO_STOPPED)) {
|
||||
test_case_fail++;
|
||||
PRINT_RESULT(MODULE_NAME, FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
128
Living_SDK/kernel/rhino/test/core/event/event_param.c
Normal file
128
Living_SDK/kernel/rhino/test/core/event/event_param.c
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
#include <test_fw.h>
|
||||
#include "event_test.h"
|
||||
|
||||
#define MODULE_NAME "event_param"
|
||||
|
||||
#define TEST_FLAG 0x5a5a5a5a
|
||||
|
||||
static uint8_t event_param_case1(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
CPSR_ALLOC();
|
||||
|
||||
ret = krhino_event_create(NULL, MODULE_NAME, TEST_FLAG);
|
||||
MYASSERT(ret == RHINO_NULL_PTR);
|
||||
|
||||
ret = krhino_event_create(&test_event, NULL, TEST_FLAG);
|
||||
MYASSERT(ret == RHINO_NULL_PTR);
|
||||
|
||||
ret = krhino_event_create(&test_event, MODULE_NAME, TEST_FLAG);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
|
||||
ret = krhino_event_del(NULL);
|
||||
MYASSERT(ret == RHINO_NULL_PTR);
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
test_event.mm_alloc_flag = K_OBJ_DYN_ALLOC;
|
||||
RHINO_CRITICAL_EXIT();
|
||||
ret = krhino_event_del(&test_event);
|
||||
MYASSERT(ret == RHINO_KOBJ_DEL_ERR);
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
test_event.mm_alloc_flag = K_OBJ_STATIC_ALLOC;
|
||||
RHINO_CRITICAL_EXIT();
|
||||
ret = krhino_event_del(&test_event);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
|
||||
ret = krhino_event_dyn_create(NULL, MODULE_NAME, TEST_FLAG);
|
||||
MYASSERT(ret == RHINO_NULL_PTR);
|
||||
|
||||
ret = krhino_event_dyn_create(&test_event_ext, NULL, TEST_FLAG);
|
||||
MYASSERT(ret == RHINO_NULL_PTR);
|
||||
|
||||
ret = krhino_event_dyn_create(&test_event_ext, MODULE_NAME, TEST_FLAG);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
|
||||
ret = krhino_event_dyn_del(NULL);
|
||||
MYASSERT(ret == RHINO_NULL_PTR);
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
test_event_ext->blk_obj.obj_type = RHINO_SEM_OBJ_TYPE;
|
||||
RHINO_CRITICAL_EXIT();
|
||||
ret = krhino_event_dyn_del(test_event_ext);
|
||||
MYASSERT(ret == RHINO_KOBJ_TYPE_ERR);
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
test_event_ext->blk_obj.obj_type = RHINO_EVENT_OBJ_TYPE;
|
||||
RHINO_CRITICAL_EXIT();
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
test_event_ext->mm_alloc_flag = K_OBJ_STATIC_ALLOC;
|
||||
RHINO_CRITICAL_EXIT();
|
||||
ret = krhino_event_dyn_del(test_event_ext);
|
||||
MYASSERT(ret == RHINO_KOBJ_DEL_ERR);
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
test_event_ext->mm_alloc_flag = K_OBJ_DYN_ALLOC;
|
||||
RHINO_CRITICAL_EXIT();
|
||||
ret = krhino_event_dyn_del(test_event_ext);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint8_t event_param_case2(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
uint32_t actl_flags;
|
||||
|
||||
ret = krhino_event_create(&test_event, MODULE_NAME, TEST_FLAG);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
|
||||
ret = krhino_event_get(NULL, 0, RHINO_AND, &actl_flags, RHINO_WAIT_FOREVER);
|
||||
MYASSERT(ret == RHINO_NULL_PTR);
|
||||
|
||||
ret = krhino_event_get(&test_event, 0, RHINO_AND, NULL, RHINO_WAIT_FOREVER);
|
||||
MYASSERT(ret == RHINO_NULL_PTR);
|
||||
|
||||
ret = krhino_event_get(&test_event, 0, 0xff, &actl_flags, RHINO_WAIT_FOREVER);
|
||||
MYASSERT(ret == RHINO_NO_THIS_EVENT_OPT);
|
||||
|
||||
ret = krhino_event_set(NULL, TEST_FLAG, RHINO_OR);
|
||||
MYASSERT(ret == RHINO_NULL_PTR);
|
||||
|
||||
ret = krhino_event_set(&test_event, TEST_FLAG, 0xff);
|
||||
MYASSERT(ret == RHINO_NO_THIS_EVENT_OPT);
|
||||
|
||||
ret = krhino_event_del(&test_event);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const test_func_t event_func_runner[] = {
|
||||
event_param_case1,
|
||||
event_param_case2,
|
||||
NULL
|
||||
};
|
||||
|
||||
void event_param_test(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
task_event_entry_register(MODULE_NAME, (test_func_t *)event_func_runner,
|
||||
sizeof(event_func_runner) / sizeof(test_func_t));
|
||||
|
||||
ret = krhino_task_dyn_create(&task_event, MODULE_NAME, 0, TASK_EVENT_PRI,
|
||||
0, TASK_TEST_STACK_SIZE, task_event_entry, 1);
|
||||
if ((ret != RHINO_SUCCESS) && (ret != RHINO_STOPPED)) {
|
||||
test_case_fail++;
|
||||
PRINT_RESULT(MODULE_NAME, FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
57
Living_SDK/kernel/rhino/test/core/event/event_reinit.c
Normal file
57
Living_SDK/kernel/rhino/test/core/event/event_reinit.c
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
#include <test_fw.h>
|
||||
#include "event_test.h"
|
||||
|
||||
#define MODULE_NAME "event_reinit"
|
||||
|
||||
#define TEST_FLAG 0x5a5a5a5a
|
||||
|
||||
static uint8_t event_reinit_case1(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
ret = krhino_event_create(&test_event, MODULE_NAME, TEST_FLAG);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
MYASSERT(test_event.blk_obj.obj_type == RHINO_EVENT_OBJ_TYPE);
|
||||
MYASSERT(test_event.blk_obj.blk_policy == BLK_POLICY_PRI);
|
||||
MYASSERT(test_event.blk_obj.name != NULL);
|
||||
MYASSERT(test_event.flags == TEST_FLAG);
|
||||
|
||||
ret = krhino_event_del(&test_event);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
|
||||
ret = krhino_event_create(&test_event, MODULE_NAME, TEST_FLAG & 0x0000ffff);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
MYASSERT(test_event.blk_obj.obj_type == RHINO_EVENT_OBJ_TYPE);
|
||||
MYASSERT(test_event.flags == (TEST_FLAG & 0x0000ffff));
|
||||
|
||||
ret = krhino_event_del(&test_event);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const test_func_t event_func_runner[] = {
|
||||
event_reinit_case1,
|
||||
NULL
|
||||
};
|
||||
|
||||
void event_reinit_test(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
task_event_entry_register(MODULE_NAME, (test_func_t *)event_func_runner,
|
||||
sizeof(event_func_runner) / sizeof(test_func_t));
|
||||
|
||||
ret = krhino_task_dyn_create(&task_event, MODULE_NAME, 0, TASK_EVENT_PRI,
|
||||
0, TASK_TEST_STACK_SIZE, task_event_entry, 1);
|
||||
if ((ret != RHINO_SUCCESS) && (ret != RHINO_STOPPED)) {
|
||||
test_case_fail++;
|
||||
PRINT_RESULT(MODULE_NAME, FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
80
Living_SDK/kernel/rhino/test/core/event/event_test.c
Normal file
80
Living_SDK/kernel/rhino/test/core/event/event_test.c
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
#include <test_fw.h>
|
||||
#include "event_test.h"
|
||||
|
||||
ktask_t *task_event;
|
||||
ktask_t *task_event_co1;
|
||||
ktask_t *task_event_co2;
|
||||
kevent_t test_event;
|
||||
kevent_t *test_event_ext;
|
||||
|
||||
static test_func_t *module_runner;
|
||||
static const char *module_name;
|
||||
static uint8_t module_casenum;
|
||||
|
||||
static const test_case_t event_case_runner[] = {
|
||||
event_param_test,
|
||||
event_break_test,
|
||||
event_reinit_test,
|
||||
event_opr_test,
|
||||
event_coopr_test,
|
||||
NULL
|
||||
};
|
||||
|
||||
void event_test(void)
|
||||
{
|
||||
if (test_case_register((test_case_t *)event_case_runner) == 0) {
|
||||
test_case_run();
|
||||
test_case_unregister();
|
||||
}
|
||||
}
|
||||
|
||||
void task_event_entry_register(const char *name, test_func_t *runner,
|
||||
uint8_t casenum)
|
||||
{
|
||||
module_runner = runner;
|
||||
module_name = name;
|
||||
module_casenum = casenum;
|
||||
}
|
||||
|
||||
void task_event_entry(void *arg)
|
||||
{
|
||||
test_func_t *runner;
|
||||
uint8_t caseidx;
|
||||
char name[64];
|
||||
uint8_t casenum;
|
||||
|
||||
runner = (test_func_t *)module_runner;
|
||||
casenum = module_casenum;
|
||||
caseidx = 0;
|
||||
|
||||
while (1) {
|
||||
if (*runner == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (casenum > 2) {
|
||||
caseidx++;
|
||||
sprintf(name, "%s_%d", module_name, caseidx);
|
||||
} else {
|
||||
sprintf(name, "%s", module_name);
|
||||
}
|
||||
|
||||
if ((*runner)() == 0) {
|
||||
test_case_success++;
|
||||
PRINT_RESULT(name, PASS);
|
||||
} else {
|
||||
test_case_fail++;
|
||||
PRINT_RESULT(name, FAIL);
|
||||
}
|
||||
runner++;
|
||||
}
|
||||
|
||||
next_test_case_notify();
|
||||
krhino_task_dyn_del(krhino_cur_task_get());
|
||||
}
|
||||
|
||||
32
Living_SDK/kernel/rhino/test/core/event/event_test.h
Normal file
32
Living_SDK/kernel/rhino/test/core/event/event_test.h
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef EVENT_TEST_H
|
||||
#define EVENT_TEST_H
|
||||
|
||||
#define TASK_EVENT_PRI 16
|
||||
#define TASK_TEST_STACK_SIZE 1024
|
||||
|
||||
#define MYASSERT(value) do {if ((int)(value) == 0) { printf("xxxx: %d \n", __LINE__); return 1; }} while (0)
|
||||
|
||||
extern ktask_t *task_event;
|
||||
extern ktask_t *task_event_co1;
|
||||
extern ktask_t *task_event_co2;
|
||||
extern kevent_t test_event;
|
||||
extern kevent_t *test_event_ext;
|
||||
|
||||
typedef uint8_t (*test_func_t)(void);
|
||||
|
||||
void task_event_entry_register(const char *name, test_func_t *runner,
|
||||
uint8_t casenum);
|
||||
void task_event_entry(void *arg);
|
||||
void event_test(void);
|
||||
void event_param_test(void);
|
||||
void event_opr_test(void);
|
||||
void event_break_test(void);
|
||||
void event_reinit_test(void);
|
||||
void event_coopr_test(void);
|
||||
|
||||
#endif /* EVENT_TEST_H */
|
||||
|
||||
133
Living_SDK/kernel/rhino/test/core/mm/mm_break.c
Normal file
133
Living_SDK/kernel/rhino/test/core/mm/mm_break.c
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
#include <test_fw.h>
|
||||
#include "mm_test.h"
|
||||
|
||||
#define MODULE_NAME "mm_break"
|
||||
|
||||
#if (RHINO_CONFIG_MM_TLF > 0)
|
||||
|
||||
static uint8_t mm_break_case1(void)
|
||||
{
|
||||
void *ptr, *newptr;
|
||||
kstat_t ret;
|
||||
char *ptrarray[10];
|
||||
int i;
|
||||
size_t oldsize;
|
||||
ret = krhino_init_mm_head(&pmmhead, (void *)mm_pool, MM_POOL_SIZE);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
|
||||
#if (K_MM_STATISTIC > 0)
|
||||
|
||||
oldsize = pmmhead->used_size;
|
||||
ptr = k_mm_alloc(pmmhead, 8);
|
||||
MYASSERT(ptr != NULL);
|
||||
|
||||
MYASSERT((pmmhead->used_size - oldsize ) == RHINO_CONFIG_MM_BLK_SIZE);
|
||||
|
||||
k_mm_free(pmmhead, ptr);
|
||||
|
||||
oldsize = pmmhead->used_size;
|
||||
ptr = k_mm_alloc(pmmhead, RHINO_CONFIG_MM_BLK_SIZE);
|
||||
MYASSERT(ptr != NULL);
|
||||
MYASSERT((pmmhead->used_size - oldsize ) == RHINO_CONFIG_MM_BLK_SIZE);
|
||||
k_mm_free(pmmhead, ptr);
|
||||
|
||||
oldsize = pmmhead->used_size;
|
||||
ptr = k_mm_alloc(pmmhead, RHINO_CONFIG_MM_BLK_SIZE + 1);
|
||||
|
||||
MYASSERT(ptr != NULL);
|
||||
MYASSERT((pmmhead->used_size - oldsize ) ==
|
||||
(RHINO_CONFIG_MM_BLK_SIZE >= MM_MIN_SIZE ?
|
||||
RHINO_CONFIG_MM_BLK_SIZE + MM_ALIGN_SIZE + MMLIST_HEAD_SIZE :
|
||||
MM_MIN_SIZE + MMLIST_HEAD_SIZE));
|
||||
k_mm_free(pmmhead, ptr);
|
||||
#endif
|
||||
|
||||
|
||||
ptr = k_mm_alloc(pmmhead, RHINO_CONFIG_MM_BLK_SIZE / 2);
|
||||
MYASSERT(ptr != NULL);
|
||||
|
||||
newptr = k_mm_realloc(pmmhead, ptr, RHINO_CONFIG_MM_BLK_SIZE / 2 + 1 );
|
||||
MYASSERT(newptr == ptr);
|
||||
|
||||
newptr = k_mm_realloc(pmmhead, ptr, RHINO_CONFIG_MM_BLK_SIZE - 1);
|
||||
MYASSERT(newptr == ptr);
|
||||
|
||||
ptr = newptr;
|
||||
newptr = k_mm_realloc(pmmhead, ptr, RHINO_CONFIG_MM_BLK_SIZE + 1);
|
||||
MYASSERT(newptr != ptr);
|
||||
|
||||
ptr = newptr;
|
||||
newptr = k_mm_realloc(pmmhead, ptr, RHINO_CONFIG_MM_BLK_SIZE + 2);
|
||||
MYASSERT(newptr == ptr);
|
||||
|
||||
ptr = newptr;
|
||||
newptr = k_mm_realloc(pmmhead, ptr, RHINO_CONFIG_MM_BLK_SIZE * 4);
|
||||
MYASSERT(newptr == ptr);
|
||||
|
||||
ptr = newptr;
|
||||
newptr = k_mm_realloc(pmmhead, ptr, RHINO_CONFIG_MM_BLK_SIZE * 3);
|
||||
MYASSERT(newptr == ptr);
|
||||
|
||||
newptr = k_mm_realloc(pmmhead, ptr, 0);
|
||||
MYASSERT(newptr == NULL);
|
||||
|
||||
ptr = k_mm_realloc(pmmhead, NULL, RHINO_CONFIG_MM_BLK_SIZE * 3);
|
||||
MYASSERT(ptr != NULL);
|
||||
|
||||
k_mm_free(pmmhead, ptr);
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
ptrarray[i] = k_mm_alloc(pmmhead, (i + 1) * 2);
|
||||
MYASSERT(ptrarray[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
if (i % 2 == 0) {
|
||||
k_mm_free(pmmhead, ptrarray[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
if (i % 2 != 0) {
|
||||
ptrarray[i] = k_mm_realloc(pmmhead, ptrarray[i], (i + 1) * 3);
|
||||
}
|
||||
MYASSERT(ptrarray[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
if (i % 2 != 0) {
|
||||
k_mm_free(pmmhead, ptrarray[i]);
|
||||
}
|
||||
}
|
||||
krhino_deinit_mm_head(pmmhead);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const test_func_t mm_func_runner[] = {
|
||||
mm_break_case1,
|
||||
NULL
|
||||
};
|
||||
|
||||
void mm_break_test(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
task_mm_entry_register(MODULE_NAME, (test_func_t *)mm_func_runner,
|
||||
sizeof(mm_func_runner) / sizeof(test_func_t));
|
||||
|
||||
ret = krhino_task_dyn_create(&task_mm, MODULE_NAME, 0, TASK_MM_PRI,
|
||||
0, TASK_TEST_STACK_SIZE, task_mm_entry, 1);
|
||||
if ((ret != RHINO_SUCCESS) && (ret != RHINO_STOPPED)) {
|
||||
test_case_fail++;
|
||||
PRINT_RESULT(MODULE_NAME, FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
146
Living_SDK/kernel/rhino/test/core/mm/mm_opr.c
Normal file
146
Living_SDK/kernel/rhino/test/core/mm/mm_opr.c
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
#include <test_fw.h>
|
||||
#include "mm_test.h"
|
||||
|
||||
#define MODULE_NAME "mm_opr"
|
||||
#define MODULE_NAME_CO "mm_coopr"
|
||||
static void *co_ptr;
|
||||
|
||||
#if (RHINO_CONFIG_MM_TLF > 0)
|
||||
|
||||
static uint8_t mm_opr_case1(void)
|
||||
{
|
||||
char *ptr;
|
||||
kstat_t ret;
|
||||
char tmp;
|
||||
|
||||
ret = krhino_init_mm_head(&pmmhead, (void *)mm_pool, MM_POOL_SIZE);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
|
||||
ptr = k_mm_alloc(pmmhead, 64);
|
||||
MYASSERT(ptr != NULL);
|
||||
//for vagrind test
|
||||
//ptr[64] = ptr[-1];
|
||||
|
||||
k_mm_free(pmmhead, ptr);
|
||||
|
||||
krhino_deinit_mm_head(pmmhead);
|
||||
|
||||
ret = krhino_init_mm_head(&pmmhead, (void *)mm_pool, MM_POOL_SIZE);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
|
||||
krhino_deinit_mm_head(pmmhead);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint8_t mm_opr_case2(void)
|
||||
{
|
||||
void *r_ptr[16];
|
||||
int8_t cnt;
|
||||
kstat_t ret;
|
||||
|
||||
ret = krhino_init_mm_head(&pmmhead, (void *)mm_pool, MM_POOL_SIZE);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
|
||||
/* alloc out of mm pools then free all */
|
||||
cnt = 0;
|
||||
for (cnt = 0; cnt < 16; ++cnt) {
|
||||
r_ptr[cnt] = k_mm_alloc(pmmhead, cnt + 26);
|
||||
if (r_ptr[cnt] == NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
k_mm_free(pmmhead, r_ptr[--cnt]);
|
||||
|
||||
} while (cnt > 0);
|
||||
|
||||
krhino_deinit_mm_head(pmmhead);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const test_func_t mm_func_runner[] = {
|
||||
mm_opr_case1,
|
||||
mm_opr_case2,
|
||||
NULL
|
||||
};
|
||||
|
||||
void mm_opr_test(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
task_mm_entry_register(MODULE_NAME, (test_func_t *)mm_func_runner,
|
||||
sizeof(mm_func_runner) / sizeof(test_func_t));
|
||||
|
||||
ret = krhino_task_dyn_create(&task_mm, MODULE_NAME, 0, TASK_MM_PRI,
|
||||
0, TASK_TEST_STACK_SIZE, task_mm_entry, 1);
|
||||
if ((ret != RHINO_SUCCESS) && (ret != RHINO_STOPPED)) {
|
||||
test_case_fail++;
|
||||
PRINT_RESULT(MODULE_NAME, FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
static void task_mm_co1_entry(void *arg)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
ret = krhino_init_mm_head(&pmmhead, (void *)mm_pool, MM_POOL_SIZE);
|
||||
if (ret != RHINO_SUCCESS) {
|
||||
test_case_fail++;
|
||||
PRINT_RESULT(MODULE_NAME_CO, FAIL);
|
||||
return;
|
||||
}
|
||||
|
||||
co_ptr = k_mm_alloc(pmmhead, 16);
|
||||
k_mm_free(pmmhead, co_ptr);
|
||||
|
||||
co_ptr = k_mm_alloc(pmmhead, 18);
|
||||
k_mm_free(pmmhead, co_ptr);
|
||||
|
||||
co_ptr = k_mm_alloc(pmmhead, 32);
|
||||
k_mm_free(pmmhead, co_ptr);
|
||||
|
||||
co_ptr = k_mm_alloc(pmmhead, 65);
|
||||
k_mm_free(pmmhead, co_ptr);
|
||||
|
||||
co_ptr = k_mm_alloc(pmmhead, 178);
|
||||
k_mm_free(pmmhead, co_ptr);
|
||||
|
||||
co_ptr = k_mm_alloc(pmmhead, 333);
|
||||
k_mm_free(pmmhead, co_ptr);
|
||||
|
||||
krhino_deinit_mm_head(pmmhead);
|
||||
|
||||
next_test_case_notify();
|
||||
krhino_task_dyn_del(krhino_cur_task_get());
|
||||
}
|
||||
|
||||
void mm_coopr_test(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
ret = krhino_init_mm_head(&pmmhead, (void *)mm_pool, MM_POOL_SIZE);
|
||||
if (ret != RHINO_SUCCESS) {
|
||||
test_case_fail++;
|
||||
PRINT_RESULT(MODULE_NAME_CO, FAIL);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = krhino_task_dyn_create(&task_mm, MODULE_NAME, 0, TASK_MM_PRI,
|
||||
0, TASK_TEST_STACK_SIZE, task_mm_co1_entry, 1);
|
||||
if ((ret != RHINO_SUCCESS) && (ret != RHINO_STOPPED)) {
|
||||
test_case_fail++;
|
||||
PRINT_RESULT(MODULE_NAME_CO, FAIL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
85
Living_SDK/kernel/rhino/test/core/mm/mm_param.c
Normal file
85
Living_SDK/kernel/rhino/test/core/mm/mm_param.c
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
#include <test_fw.h>
|
||||
#include "mm_test.h"
|
||||
|
||||
#define MODULE_NAME "mm_param"
|
||||
|
||||
#if (RHINO_CONFIG_MM_TLF > 0)
|
||||
|
||||
static uint8_t mm_param_case1(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
ret = krhino_init_mm_head(NULL, (void *)mm_pool, MM_POOL_SIZE);
|
||||
MYASSERT(ret == RHINO_NULL_PTR);
|
||||
|
||||
ret = krhino_init_mm_head(&pmmhead, NULL, MM_POOL_SIZE);
|
||||
MYASSERT(ret == RHINO_NULL_PTR);
|
||||
|
||||
ret = krhino_init_mm_head(&pmmhead, (void *)mm_pool, MIN_FREE_MEMORY_SIZE + RHINO_CONFIG_MM_TLF_BLK_SIZE - 1);
|
||||
MYASSERT(ret == RHINO_MM_POOL_SIZE_ERR);
|
||||
|
||||
ret = krhino_init_mm_head(&pmmhead, (void *)mm_pool, MM_POOL_SIZE);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
ret = krhino_deinit_mm_head(pmmhead);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint8_t mm_param_case2(void)
|
||||
{
|
||||
void *ptr;
|
||||
kstat_t ret;
|
||||
|
||||
ret = krhino_init_mm_head(&pmmhead, (void *)mm_pool, MM_POOL_SIZE);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
|
||||
ptr = k_mm_alloc( NULL, 64);
|
||||
MYASSERT(ptr == NULL);
|
||||
|
||||
ptr = k_mm_alloc(pmmhead, 0);
|
||||
MYASSERT(ptr == NULL);
|
||||
|
||||
ptr = k_mm_alloc(pmmhead, 64);
|
||||
MYASSERT((ptr > (void *)mm_pool) && (ptr < ((void *)mm_pool + MM_POOL_SIZE)));
|
||||
k_mm_free(pmmhead, ptr);
|
||||
|
||||
ptr = k_mm_alloc(pmmhead, 16);
|
||||
|
||||
MYASSERT(krhino_mblk_check(pmmhead->fix_pool, ptr));
|
||||
|
||||
k_mm_free(pmmhead, ptr);
|
||||
|
||||
krhino_deinit_mm_head(pmmhead);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const test_func_t mm_func_runner[] = {
|
||||
mm_param_case1,
|
||||
mm_param_case2,
|
||||
NULL
|
||||
};
|
||||
|
||||
void mm_param_test(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
task_mm_entry_register(MODULE_NAME, (test_func_t *)mm_func_runner,
|
||||
sizeof(mm_func_runner) / sizeof(test_func_t));
|
||||
|
||||
ret = krhino_task_dyn_create(&task_mm, MODULE_NAME, 0, TASK_MM_PRI,
|
||||
0, TASK_TEST_STACK_SIZE, task_mm_entry, 1);
|
||||
if ((ret != RHINO_SUCCESS) && (ret != RHINO_STOPPED)) {
|
||||
test_case_fail++;
|
||||
PRINT_RESULT(MODULE_NAME, FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
51
Living_SDK/kernel/rhino/test/core/mm/mm_reinit.c
Normal file
51
Living_SDK/kernel/rhino/test/core/mm/mm_reinit.c
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
#include <test_fw.h>
|
||||
#include "mm_test.h"
|
||||
|
||||
#define MODULE_NAME "mm_reinit"
|
||||
|
||||
static uint8_t mm_reinit_case1(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
ret = krhino_mm_pool_init(&mm_pool_test, MODULE_NAME, (void *)mm_pool,
|
||||
MM_POOL_MIN_SIZE);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
MYASSERT(mm_pool_test.fragments == 2);
|
||||
MYASSERT(mm_pool_test.pool_name != NULL);
|
||||
MYASSERT(mm_pool_test.avail == (MM_POOL_MIN_SIZE - (MM_HEAD_SIZE << 1)));
|
||||
|
||||
ret = krhino_mm_pool_init(&mm_pool_test, MODULE_NAME, (void *)mm_pool,
|
||||
MM_POOL_SIZE);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
MYASSERT(mm_pool_test.fragments == 2);
|
||||
MYASSERT(mm_pool_test.pool_name != NULL);
|
||||
MYASSERT(mm_pool_test.avail == (MM_POOL_SIZE - (MM_HEAD_SIZE << 1)));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const test_func_t mm_func_runner[] = {
|
||||
mm_reinit_case1,
|
||||
NULL
|
||||
};
|
||||
|
||||
void mm_reinit_test(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
task_mm_entry_register(MODULE_NAME, (test_func_t *)mm_func_runner,
|
||||
sizeof(mm_func_runner) / sizeof(test_func_t));
|
||||
|
||||
ret = krhino_task_dyn_create(&task_mm, MODULE_NAME, 0, TASK_MM_PRI,
|
||||
0, TASK_TEST_STACK_SIZE, task_mm_entry, 1);
|
||||
if ((ret != RHINO_SUCCESS) && (ret != RHINO_STOPPED)) {
|
||||
test_case_fail++;
|
||||
PRINT_RESULT(MODULE_NAME, FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
82
Living_SDK/kernel/rhino/test/core/mm/mm_test.c
Normal file
82
Living_SDK/kernel/rhino/test/core/mm/mm_test.c
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
#include <test_fw.h>
|
||||
#include "mm_test.h"
|
||||
|
||||
#if (RHINO_CONFIG_MM_TLF > 0)
|
||||
|
||||
ktask_t *task_mm;
|
||||
ktask_t *task_mm_co;
|
||||
k_mm_head *pmmhead;
|
||||
char mm_pool[MM_POOL_SIZE] = {0};
|
||||
|
||||
static test_func_t *module_runner;
|
||||
static const char *module_name;
|
||||
static uint8_t module_casenum;
|
||||
|
||||
static const test_case_t mm_case_runner[] = {
|
||||
mm_param_test,
|
||||
mm_break_test,
|
||||
mm_opr_test,
|
||||
mm_coopr_test,
|
||||
NULL
|
||||
};
|
||||
|
||||
void mm_test(void)
|
||||
{
|
||||
if (test_case_register((test_case_t *)mm_case_runner) == 0) {
|
||||
test_case_run();
|
||||
test_case_unregister();
|
||||
}
|
||||
}
|
||||
|
||||
void task_mm_entry_register(const char *name, test_func_t *runner,
|
||||
uint8_t casenum)
|
||||
{
|
||||
module_runner = runner;
|
||||
module_name = name;
|
||||
module_casenum = casenum;
|
||||
}
|
||||
|
||||
void task_mm_entry(void *arg)
|
||||
{
|
||||
test_func_t *runner;
|
||||
uint8_t caseidx;
|
||||
char name[64];
|
||||
uint8_t casenum;
|
||||
|
||||
runner = (test_func_t *)module_runner;
|
||||
casenum = module_casenum;
|
||||
caseidx = 0;
|
||||
|
||||
while (1) {
|
||||
if (*runner == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (casenum > 2) {
|
||||
caseidx++;
|
||||
sprintf(name, "%s_%d", module_name, caseidx);
|
||||
} else {
|
||||
sprintf(name, "%s", module_name);
|
||||
}
|
||||
|
||||
if ((*runner)() == 0) {
|
||||
test_case_success++;
|
||||
PRINT_RESULT(name, PASS);
|
||||
} else {
|
||||
test_case_fail++;
|
||||
PRINT_RESULT(name, FAIL);
|
||||
}
|
||||
|
||||
runner++;
|
||||
}
|
||||
|
||||
next_test_case_notify();
|
||||
krhino_task_dyn_del(krhino_cur_task_get());
|
||||
}
|
||||
#endif
|
||||
|
||||
33
Living_SDK/kernel/rhino/test/core/mm/mm_test.h
Normal file
33
Living_SDK/kernel/rhino/test/core/mm/mm_test.h
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef MM_TEST_H
|
||||
#define MM_TEST_H
|
||||
|
||||
#define TASK_MM_PRI 16
|
||||
#define TASK_TEST_STACK_SIZE 1024
|
||||
#define MM_POOL_SIZE (1024 * 11)
|
||||
|
||||
#define MYASSERT(value) do {if ((int)(value) == 0) { printf("%s:%d\n", __FUNCTION__, __LINE__);return 1; }} while (0)
|
||||
|
||||
#if (RHINO_CONFIG_MM_TLF > 0)
|
||||
extern ktask_t *task_mm;
|
||||
extern ktask_t *task_mm_co;
|
||||
extern k_mm_head *pmmhead;
|
||||
extern char mm_pool[MM_POOL_SIZE];
|
||||
|
||||
typedef uint8_t (*test_func_t)(void);
|
||||
|
||||
void task_mm_entry_register(const char *name, test_func_t *runner,
|
||||
uint8_t casenum);
|
||||
void task_mm_entry(void *arg);
|
||||
void mm_test(void);
|
||||
void mm_param_test(void);
|
||||
//void mm_reinit_test(void);
|
||||
void mm_break_test(void);
|
||||
void mm_opr_test(void);
|
||||
void mm_coopr_test(void);
|
||||
#endif
|
||||
#endif /* MM_TEST_H */
|
||||
|
||||
42
Living_SDK/kernel/rhino/test/core/mm_blk/mm_blk_break.c
Normal file
42
Living_SDK/kernel/rhino/test/core/mm_blk/mm_blk_break.c
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
#include <test_fw.h>
|
||||
#include "mm_blk_test.h"
|
||||
|
||||
#define MODULE_NAME "mm_blk_break"
|
||||
|
||||
static uint8_t mm_blk_break_case1(void)
|
||||
{
|
||||
void *ptr;
|
||||
kstat_t ret;
|
||||
|
||||
ret = krhino_mblk_pool_init(&mblk_pool_test, MODULE_NAME, (void *)mblk_pool,
|
||||
MBLK_POOL_SIZE >> 2, MBLK_POOL_SIZE);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const test_func_t mm_blk_func_runner[] = {
|
||||
mm_blk_break_case1,
|
||||
NULL
|
||||
};
|
||||
|
||||
void mm_blk_break_test(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
task_mm_blk_entry_register(MODULE_NAME, (test_func_t *)mm_blk_func_runner,
|
||||
sizeof(mm_blk_func_runner) / sizeof(test_func_t));
|
||||
|
||||
ret = krhino_task_dyn_create(&task_mm_blk, MODULE_NAME, 0, TASK_MM_BLK_PRI,
|
||||
0, TASK_TEST_STACK_SIZE, task_mm_blk_entry, 1);
|
||||
if ((ret != RHINO_SUCCESS) && (ret != RHINO_STOPPED)) {
|
||||
test_case_fail++;
|
||||
PRINT_RESULT(MODULE_NAME, FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
70
Living_SDK/kernel/rhino/test/core/mm_blk/mm_blk_fragment.c
Normal file
70
Living_SDK/kernel/rhino/test/core/mm_blk/mm_blk_fragment.c
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
#include <test_fw.h>
|
||||
#include "mm_blk_test.h"
|
||||
|
||||
#define MODULE_NAME "mm_blk_fragment"
|
||||
|
||||
static uint8_t mm_blk_fragment_case1(void)
|
||||
{
|
||||
void *ptr[16];
|
||||
kstat_t ret;
|
||||
uint8_t blkavail;
|
||||
|
||||
ret = krhino_mblk_pool_init(&mblk_pool_test, MODULE_NAME, (void *)mblk_pool,
|
||||
MBLK_POOL_SIZE >> 2, MBLK_POOL_SIZE);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
|
||||
/* check malloc save pointer number is enough or not */
|
||||
MYASSERT(mblk_pool_test.blk_whole <= 16);
|
||||
|
||||
/* alloc all blocks */
|
||||
blkavail = 0;
|
||||
do {
|
||||
ret = krhino_mblk_alloc(&mblk_pool_test, &ptr[blkavail]);
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
blkavail++;
|
||||
}
|
||||
} while (ret == RHINO_SUCCESS);
|
||||
|
||||
MYASSERT(mblk_pool_test.blk_avail == 0);
|
||||
MYASSERT(blkavail == mblk_pool_test.blk_whole);
|
||||
|
||||
/* free all blocks */
|
||||
blkavail = 0;
|
||||
do {
|
||||
ret = krhino_mblk_free(&mblk_pool_test, ptr[blkavail]);
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
blkavail++;
|
||||
}
|
||||
} while (ret == RHINO_SUCCESS);
|
||||
|
||||
MYASSERT(mblk_pool_test.blk_avail == mblk_pool_test.blk_whole);
|
||||
MYASSERT(blkavail == mblk_pool_test.blk_whole);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const test_func_t mm_blk_func_runner[] = {
|
||||
mm_blk_fragment_case1,
|
||||
NULL
|
||||
};
|
||||
|
||||
void mm_blk_fragment_test(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
task_mm_blk_entry_register(MODULE_NAME, (test_func_t *)mm_blk_func_runner,
|
||||
sizeof(mm_blk_func_runner) / sizeof(test_func_t));
|
||||
|
||||
ret = krhino_task_dyn_create(&task_mm_blk, MODULE_NAME, 0, TASK_MM_BLK_PRI,
|
||||
0, TASK_TEST_STACK_SIZE, task_mm_blk_entry, 1);
|
||||
if ((ret != RHINO_SUCCESS) && (ret != RHINO_STOPPED)) {
|
||||
test_case_fail++;
|
||||
PRINT_RESULT(MODULE_NAME, FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
104
Living_SDK/kernel/rhino/test/core/mm_blk/mm_blk_opr.c
Normal file
104
Living_SDK/kernel/rhino/test/core/mm_blk/mm_blk_opr.c
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
#include <test_fw.h>
|
||||
#include "mm_blk_test.h"
|
||||
|
||||
#define MODULE_NAME "mm_blk_opr"
|
||||
#define MODULE_NAME_CO "mm_blk_coopr"
|
||||
|
||||
static void *co_ptr;
|
||||
static ktask_t *blk_task;
|
||||
|
||||
static uint8_t mm_blk_opr_case1(void)
|
||||
{
|
||||
void *ptr;
|
||||
kstat_t ret;
|
||||
|
||||
ret = krhino_mblk_pool_init(&mblk_pool_test, MODULE_NAME, (void *)mblk_pool,
|
||||
MBLK_POOL_SIZE >> 2, MBLK_POOL_SIZE);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
|
||||
ret = krhino_mblk_alloc(&mblk_pool_test, &ptr);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
|
||||
ret = krhino_mblk_free(&mblk_pool_test, ptr);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const test_func_t mm_blk_func_runner[] = {
|
||||
mm_blk_opr_case1,
|
||||
NULL
|
||||
};
|
||||
|
||||
void mm_blk_opr_test(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
task_mm_blk_entry_register(MODULE_NAME, (test_func_t *)mm_blk_func_runner,
|
||||
sizeof(mm_blk_func_runner) / sizeof(test_func_t));
|
||||
|
||||
ret = krhino_task_dyn_create(&task_mm_blk, MODULE_NAME, 0, TASK_MM_BLK_PRI,
|
||||
0, TASK_TEST_STACK_SIZE, task_mm_blk_entry, 1);
|
||||
if ((ret != RHINO_SUCCESS) && (ret != RHINO_STOPPED)) {
|
||||
test_case_fail++;
|
||||
PRINT_RESULT(MODULE_NAME, FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
static void task_mm_blk_co1_entry(void *arg)
|
||||
{
|
||||
while (1) {
|
||||
krhino_mblk_alloc(&mblk_pool_test, &co_ptr);
|
||||
krhino_mblk_free(&mblk_pool_test, co_ptr);
|
||||
krhino_task_sleep(5);
|
||||
krhino_mblk_alloc(&mblk_pool_test, &co_ptr);
|
||||
krhino_mblk_free(&mblk_pool_test, co_ptr);
|
||||
krhino_task_sleep(5);
|
||||
krhino_mblk_alloc(&mblk_pool_test, &co_ptr);
|
||||
krhino_mblk_free(&mblk_pool_test, co_ptr);
|
||||
krhino_task_sleep(5);
|
||||
krhino_mblk_alloc(&mblk_pool_test, &co_ptr);
|
||||
krhino_mblk_free(&mblk_pool_test, co_ptr);
|
||||
krhino_task_sleep(5);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (mblk_pool_test.blk_avail == (MBLK_POOL_SIZE / mblk_pool_test.blk_size)) {
|
||||
test_case_success++;
|
||||
PRINT_RESULT(MODULE_NAME_CO, PASS);
|
||||
} else {
|
||||
test_case_fail++;
|
||||
PRINT_RESULT(MODULE_NAME_CO, FAIL);
|
||||
}
|
||||
|
||||
next_test_case_notify();
|
||||
krhino_task_dyn_del(krhino_cur_task_get());
|
||||
}
|
||||
|
||||
|
||||
void mm_blk_coopr_test(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
ret = krhino_mblk_pool_init(&mblk_pool_test, MODULE_NAME, (void *)mblk_pool,
|
||||
MBLK_POOL_SIZE >> 2, MBLK_POOL_SIZE);
|
||||
if (ret != RHINO_SUCCESS) {
|
||||
test_case_fail++;
|
||||
PRINT_RESULT(MODULE_NAME_CO, FAIL);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = krhino_task_dyn_create(&blk_task, MODULE_NAME, 0, TASK_MM_BLK_PRI + 1,
|
||||
0, TASK_TEST_STACK_SIZE, task_mm_blk_co1_entry, 1);
|
||||
if ((ret != RHINO_SUCCESS) && (ret != RHINO_STOPPED)) {
|
||||
test_case_fail++;
|
||||
PRINT_RESULT(MODULE_NAME_CO, FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
104
Living_SDK/kernel/rhino/test/core/mm_blk/mm_blk_param.c
Normal file
104
Living_SDK/kernel/rhino/test/core/mm_blk/mm_blk_param.c
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
#include <test_fw.h>
|
||||
#include "mm_blk_test.h"
|
||||
|
||||
#define MODULE_NAME "mm_blk_param"
|
||||
|
||||
static uint8_t mm_blk_param_case1(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
ret = krhino_mblk_pool_init(NULL, MODULE_NAME, (void *)mblk_pool,
|
||||
MBLK_POOL_SIZE >> 1, MBLK_POOL_SIZE);
|
||||
MYASSERT(ret == RHINO_NULL_PTR);
|
||||
|
||||
ret = krhino_mblk_pool_init(&mblk_pool_test, NULL, (void *)mblk_pool,
|
||||
MBLK_POOL_SIZE >> 1, MBLK_POOL_SIZE);
|
||||
MYASSERT(ret == RHINO_NULL_PTR);
|
||||
|
||||
ret = krhino_mblk_pool_init(&mblk_pool_test, MODULE_NAME, NULL,
|
||||
MBLK_POOL_SIZE >> 1, MBLK_POOL_SIZE);
|
||||
MYASSERT(ret == RHINO_NULL_PTR);
|
||||
|
||||
/* check block size is less than half of pool size */
|
||||
ret = krhino_mblk_pool_init(&mblk_pool_test, MODULE_NAME, (void *)mblk_pool,
|
||||
(MBLK_POOL_SIZE >> 1) + 1, MBLK_POOL_SIZE);
|
||||
MYASSERT(ret == RHINO_BLK_POOL_SIZE_ERR);
|
||||
|
||||
/* check block size is less than half of pool size */
|
||||
ret = krhino_mblk_pool_init(&mblk_pool_test, MODULE_NAME, (void *)mblk_pool,
|
||||
MBLK_POOL_SIZE, MBLK_POOL_SIZE);
|
||||
MYASSERT(ret == RHINO_BLK_POOL_SIZE_ERR);
|
||||
|
||||
/* check pool address is not align */
|
||||
ret = krhino_mblk_pool_init(&mblk_pool_test, MODULE_NAME,
|
||||
(void *)(mblk_pool + 1),
|
||||
MBLK_POOL_SIZE >> 2, MBLK_POOL_SIZE);
|
||||
MYASSERT(ret == RHINO_INV_ALIGN);
|
||||
|
||||
/* check block size is not align */
|
||||
ret = krhino_mblk_pool_init(&mblk_pool_test, MODULE_NAME, (void *)mblk_pool,
|
||||
(MBLK_POOL_SIZE >> 2) + 1, MBLK_POOL_SIZE);
|
||||
MYASSERT(ret == RHINO_INV_ALIGN);
|
||||
|
||||
/* check pool size is not align */
|
||||
ret = krhino_mblk_pool_init(&mblk_pool_test, MODULE_NAME, (void *)mblk_pool,
|
||||
MBLK_POOL_SIZE >> 2, MBLK_POOL_SIZE + 1);
|
||||
MYASSERT(ret == RHINO_INV_ALIGN);
|
||||
|
||||
ret = krhino_mblk_pool_init(&mblk_pool_test, MODULE_NAME, (void *)mblk_pool,
|
||||
MBLK_POOL_SIZE >> 2, MBLK_POOL_SIZE);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint8_t mm_blk_param_case2(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
void *ptr;
|
||||
|
||||
ret = krhino_mblk_pool_init(&mblk_pool_test, MODULE_NAME, (void *)mblk_pool,
|
||||
MBLK_POOL_SIZE >> 2, MBLK_POOL_SIZE);
|
||||
MYASSERT(ret == RHINO_SUCCESS);
|
||||
|
||||
ret = krhino_mblk_alloc(NULL, &ptr);
|
||||
MYASSERT(ret == RHINO_NULL_PTR);
|
||||
|
||||
ret = krhino_mblk_alloc(&mblk_pool_test, NULL);
|
||||
MYASSERT(ret == RHINO_NULL_PTR);
|
||||
|
||||
ret = krhino_mblk_free(NULL, ptr);
|
||||
MYASSERT(ret == RHINO_NULL_PTR);
|
||||
|
||||
ret = krhino_mblk_free(&mblk_pool_test, NULL);
|
||||
MYASSERT(ret == RHINO_NULL_PTR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const test_func_t mm_blk_func_runner[] = {
|
||||
mm_blk_param_case1,
|
||||
mm_blk_param_case2,
|
||||
NULL
|
||||
};
|
||||
|
||||
void mm_blk_param_test(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
task_mm_blk_entry_register(MODULE_NAME, (test_func_t *)mm_blk_func_runner,
|
||||
sizeof(mm_blk_func_runner) / sizeof(test_func_t));
|
||||
|
||||
ret = krhino_task_dyn_create(&task_mm_blk, MODULE_NAME, 0, TASK_MM_BLK_PRI,
|
||||
0, TASK_TEST_STACK_SIZE, task_mm_blk_entry, 1);
|
||||
if ((ret != RHINO_SUCCESS) && (ret != RHINO_STOPPED)) {
|
||||
test_case_fail++;
|
||||
PRINT_RESULT(MODULE_NAME, FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue