xiuos3/kernel/kernel_test/test_gatherblock.c

571 lines
17 KiB
C

/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file test_gatherblock.c
* @brief support to test gather block function
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#include <xiuos.h>
#include <string.h>
extern long ShowGatherMem(void);
extern void ShowMemory(void);
extern void ShowBuddy(void);
/**************************single gatherblock test sample***********************************/
static uint8 *ptr[30];
static uint8 mempool[2048];
static struct MemGather gm;
static GatherMemType gm_d;
#define TASK_PRIORITY 25
#define TASK_STACK_SIZE 2048
#define TASK_TIMESLICE 5
/* thread control pointer */
static int32 tid1;
static int32 tid2;
/* task1 entry */
static void Task1GmAlloc(void *parameter)
{
int i;
for (i = 0 ; i < 30 ; i++){
if (ptr[i] == NONE){
/* alloc memory blocks for 50 times, if failed, suspend task1 and start task2 */
if (0 == strncmp("static", parameter, strlen("static"))){
ptr[i] = AllocBlockMemGather(&gm, WAITING_FOREVER);
if (ptr[i] != NONE)
KPrintf("task1: allocate No.%d from static gatherblock\n", i);
}
else{
ptr[i] = AllocBlockMemGather(gm_d, WAITING_FOREVER);
if (ptr[i] != NONE)
KPrintf("task1: allocate No.%d from dynamic gatherblock\n", i);
}
}
}
}
/* task2 entry, its priority is lower than task1 */
static void Task2GmRelease(void *parameter)
{
int i;
KPrintf("task2 try to release block\n");
for (i = 0; i < 30 ; i++){
DelayKTask(10);
/* release all memory blocks */
if (ptr[i] != NONE){
KPrintf("release block %d\n", i);
FreeBlockMemGather(ptr[i]);
ptr[i] = NONE;
}
}
if (0 == strncmp("static", parameter, strlen("static"))) {
KPrintf("**************** detach gatherblock test *****************\n");
RemoveMemGather(&gm);
} else {
KPrintf("**************** delete gatherblock test *****************\n");
DeleteMemGather(gm_d);
}
}
int SingleGatherblockTest(char * parameter)
{
int i;
for (i = 0; i < 30; i ++) ptr[i] = NONE;
/* init memory blocks object */
if(0 == strncmp("static", parameter, strlen("static"))){
KPrintf("test static create gatherblock.\n");
InitMemGather(&gm, "mp_s", &mempool[0], sizeof(mempool), 80);
ShowGatherMem();
}
if(0 == strncmp("dynamic", parameter, strlen("dynamic"))){
KPrintf("test dynamic create gatherblock.\n");
//FreeBlockMemGather(&mp, "mp1", &mempool[0], sizeof(mempool), 80);
gm_d = CreateMemGather("mp_d",20,80);
if(gm_d == NONE){
KPrintf("%s: allocate failure.\n",__func__);
return -1;
}
ShowGatherMem();
}
/* create task1, alloc memory blocks */
tid1 = KTaskCreate("task1", Task1GmAlloc, parameter,
TASK_STACK_SIZE,
TASK_PRIORITY);
if (tid1 >= 0){
KPrintf("single test: task1 startup.\n");
StartupKTask(tid1);
}
/* create task2, release memory blocks */
tid2 = KTaskCreate("task2", Task2GmRelease, parameter,
TASK_STACK_SIZE,
TASK_PRIORITY + 1);
if (tid2 >= 0){
StartupKTask(tid2);
}
else{
KPrintf("create task2 for release failure.\n");
}
return 0;
}
/**************************************************************************************/
/**********************mutiple gatherblock test sample**************************************/
struct MemGather s_gm1;
struct MemGather *d_gm1 = NONE;
static uint8 mempool_gm1[1024];
#define MAX_SIZE 11
#define TASK_PRIORITY 25
#define TASK_STACK_SIZE 2048
#define TASK_TIMESLICE 5
/* thread control pointer */
static int32 m_tid1 = NONE;
static int32 m_tid2 = NONE;
static uint8 *multiple_s_ptr[20];
static uint8 *multiple_d_ptr[20];
void Task1AllocEntry(void *parameter){
int index = 0;
for(int i=0;i<20;i++){
multiple_s_ptr[i] = AllocBlockMemGather(&s_gm1, WAITING_FOREVER);
if(multiple_s_ptr[i] != NONE){
KPrintf("task1: allocate No.%d from static\n", i);
}
multiple_d_ptr[i] = AllocBlockMemGather(d_gm1, WAITING_FOREVER);
if (ptr[i] != NONE)
KPrintf("task1: allocate No.%d from dynamic\n", i);
}
}
void Task2FreeEntry(void *parameter){
DelayKTask(100);
for(int i=0;i<20;i++){
DelayKTask(10);
if(multiple_s_ptr[i]){
FreeBlockMemGather(multiple_s_ptr[i]);
KPrintf("task2: free No.%d of static\n", i);
}
DelayKTask(10);
if(multiple_d_ptr[i]){
FreeBlockMemGather(multiple_d_ptr[i]);
KPrintf("task2: free No.%d of dynamic\n", i);
}
}
KPrintf("**************** detach gatherblock test *****************\n");
RemoveMemGather(&s_gm1);
KPrintf("**************** delete gatherblock test *****************\n");
DeleteMemGather(d_gm1);
}
int MultipleGatherblockTest(void)
{
KPrintf("****************mutiple gatherblock test start*****************\n");
for(int i=0;i<20;i++){
multiple_s_ptr[i] = NONE;
multiple_d_ptr[i] = NONE;
}
InitMemGather(&s_gm1, "m_gm_s1", &mempool_gm1[0], sizeof(mempool_gm1), 80);
d_gm1 = CreateMemGather("m_gm_d1", MAX_SIZE, 80);
if (mempool_gm1 == NONE){
KPrintf("create m_gm_d2 failed.");
CHECK(0);
}
ShowGatherMem();
/* create task1, alloc memory blocks */
m_tid1 = KTaskCreate("task1_m", Task1AllocEntry, NONE,
TASK_STACK_SIZE,
TASK_PRIORITY);
if (m_tid1 >= 0){
StartupKTask(m_tid1);
}
/* create task2, release memory blocks */
m_tid2 = KTaskCreate("task2_m", Task2FreeEntry, NONE,
TASK_STACK_SIZE,
TASK_PRIORITY + 1);
if (m_tid2 >= 0){
StartupKTask(m_tid2);
}
else{
KPrintf("create task2 for release failure.\n");
}
return 0;
}
/**************************************************************************************/
/* thread control pointer */
static int32 l_tid1 = NONE;
static int32 l_tid2 = NONE;
struct MemGather *gm_l = NONE;
void *l_ptr[50];
void LTask1AllocEntry(void *parameter){
int index = 0;
for(int i=0;i<50;i++){
l_ptr[i] = AllocBlockMemGather(gm_l, WAITING_FOREVER);
if(l_ptr[i] != NONE){
KPrintf("l_task1: allocate No.%d\n", i);
}
}
}
void LTask2FreeEntry(void *parameter){
DelayKTask(100);
for(int i=0;i<50;i++){
DelayKTask(10);
if(l_ptr[i]){
FreeBlockMemGather(l_ptr[i]);
KPrintf("l_task2: free No.%d\n", i);
}
}
KPrintf("**************** delete gatherblock test *****************\n");
DeleteMemGather(gm_l);
}
void GatherblockLimitTest(char *name, int count, int blocksize){
gm_l = CreateMemGather(name, count, blocksize);
if(gm_l == NONE){
KPrintf("no memory.\n");
return;
}
ShowBuddy();
/* create task1, alloc memory blocks */
l_tid1 = KTaskCreate("task1_l", LTask1AllocEntry, NONE,
TASK_STACK_SIZE,
TASK_PRIORITY);
if (l_tid1 >= 0){
StartupKTask(l_tid1);
}
/* create task2, release memory blocks */
l_tid2 = KTaskCreate("task2_l", LTask2FreeEntry, NONE,
TASK_STACK_SIZE,
TASK_PRIORITY + 1);
if (l_tid2 >= 0){
StartupKTask(l_tid2);
}
}
#ifdef ARCH_ARM
#define CACHE_COUNT 1024
#else
#define CACHE_COUNT 8000
#endif
struct MemGather *pools[CACHE_COUNT];
void GatherblockLimitcountTest(char *name, int count, int blocksize, int poolcount){
if(poolcount>CACHE_COUNT || poolcount<=0){
KPrintf("type the poolcount between 0-%d\n",CACHE_COUNT);
return;
}
int index;
for(index=0;index < poolcount;index++){
pools[index] = CreateMemGather(name, count, blocksize);
if(pools[index] == NONE){
KPrintf("gatherblock allocation failure,count[%d],size[%d]\n", count, blocksize);
break;
}
KPrintf("gatherblock allocation,count[%d],size[%d]\n", count, blocksize);
}
ShowBuddy();
index--;
for(;index>=0;index--){
DeleteMemGather(pools[index]);
}
}
/*****************************************************************/
static int32 traverse_tid = NONE;
static struct MemGather *traverse_gm = NONE;
void TraverseGmEntry(void *parameter){
int count,size;
int limit_count, limit_size;
for(count =1; count <= 30; count++){
for(size = 1; ;size++){
traverse_gm = CreateMemGather("hello",count,size);
if( traverse_gm == NONE ){
KPrintf("gatherblock allocation failure,count[%d],size[%d]\n", count, size);
if(count == 1)
limit_size = size;
break;
}else{
DeleteMemGather(traverse_gm);
}
}
if(size ==1){
limit_count = count;
break;
}
}
KPrintf("\n\n--------------------------- bound -----------------------------\n\n");
KPrintf("\n\n--------------------------- over end -----------------------------\n\n");
}
#define TRAVERSE_TASK_PRIORITY 5
void TraverseGmTest(){
traverse_tid = KTaskCreate("traverse_task", TraverseGmEntry, NONE,
TASK_STACK_SIZE ,
TRAVERSE_TASK_PRIORITY);
if(traverse_tid >= 0){
StartupKTask(traverse_tid);
}else{
KPrintf("Fail.\n");
}
}
/********************************************************************/
/***************************test random read and write **************/
static uint8 *random_ptr[50];
static struct MemGather random_static_gm;
static GatherMemType random_dynamic_gm;
static uint8 dynamic_mempool[2048];
/* thread control pointer */
static int32 random_tid1 = NONE;
static int32 random_tid2 = NONE;
/* task1 entry */
int time_seed = 1;
char temp_parameter[40];
static void RandomTask1GmAlloc(void *parameter)
{
int i;
int total=0;
time_seed++;
srand(time_seed);
char string[10];
while(total<40){
i = rand()%40;
if (random_ptr[i] == NONE){
/* alloc memory blocks for 50 times, if failed, suspend task1 and start task2 */
if (0 == strncmp("static", temp_parameter, strlen("static"))){
random_ptr[i] = AllocBlockMemGather(&random_static_gm, WAITING_FOREVER);
if (random_ptr[i] != NONE){
itoa(i,string,10);
memcpy(random_ptr[i],string,sizeof(string));
KPrintf("%s No.%d: %s\n",temp_parameter, i, random_ptr[i]);
}
}else{
random_ptr[i] = AllocBlockMemGather(random_dynamic_gm, WAITING_FOREVER);
if (random_ptr[i] != NONE){
itoa(i,string,10);
memcpy(random_ptr[i],string,sizeof(string));
KPrintf("%s No.%d: %s\n", temp_parameter, i, random_ptr[i]);
}
}
total++;
}
}
}
/* task2 entry, its priority is lower than task1 */
static void RandomTask2GmRelease(void *parameter)
{
int i;
time_seed++;
srand(time_seed);
int total = 0;
while(total<40){
i = rand()%40;
/* release all memory blocks */
if (random_ptr[i] != NONE){
DelayKTask(10);
KPrintf("release block %d: %s\n",i, random_ptr[i]);
FreeBlockMemGather(random_ptr[i]);
random_ptr[i] = NONE;
total++;
}
}
if (0 == strncmp("static", temp_parameter, strlen("static"))) {
KPrintf("**************** detach gatherblock test *****************\n");
RemoveMemGather(&random_static_gm);
} else {
KPrintf("**************** delete gatherblock test *****************\n");
DeleteMemGather(random_dynamic_gm);
}
}
int RandomAllocFreeTest(void *parameter)
{
int i;
for (i = 0; i < 40; i ++) random_ptr[i] = NONE;
memcpy(temp_parameter,parameter, 10);
/* init memory block object */
if(0 == strncmp("static", parameter, strlen("static"))){
KPrintf("test static create gatherblock-%s.\n",parameter);
InitMemGather(&random_static_gm, "ran_mp_s", &dynamic_mempool[0], sizeof(dynamic_mempool), 80);
ShowGatherMem();
}else{
KPrintf("test dynamic create gatherblock.\n");
random_dynamic_gm = CreateMemGather("ran_mp_d",40,80);
if(random_dynamic_gm == NONE){
KPrintf("%s: allocate failure.\n",__func__);
return -1;
}
ShowGatherMem();
}
/* create task1, alloc memory blocks */
random_tid1 = KTaskCreate("r_task1", RandomTask1GmAlloc, parameter,
TASK_STACK_SIZE,
TASK_PRIORITY);
if (random_tid1 >= 0){
StartupKTask(random_tid1);
}
/* create task2, release memory blocks */
random_tid2 = KTaskCreate("r_task2", RandomTask2GmRelease, parameter,
TASK_STACK_SIZE,
TASK_PRIORITY + 1);
if (random_tid2 >= 0){
StartupKTask(random_tid2);
}
else{
KPrintf("create task2 for release failure.\n");
}
return 0;
}
/********************************************************************/
void TestGatherblockUsage(void)
{
KPrintf("TestGatherblockUsage.\n");
KPrintf("test_main gm -a --static, dynamic and multiple test.\n");
KPrintf("test_main gm -s static/dynamic --test static create gatherblock to allocate and free.\n");
KPrintf("test_main gm -m --test multiple gatherblock to allocate and free.\n");
KPrintf("test_main gm count_size [count] [size] --create a gatherblock with typed count and size "
"to allocate and free.\n");
KPrintf("test_main gm multiple_gms [count] [size] [gm_ns] --create multiple gatherblocks with typed count and \n");
KPrintf(" size to allocate and free.\n");
KPrintf("test_main gm traverse --traverse.\n");
KPrintf("test_main gm -r static/dynamic --random allocate and free.\n");
}
int TestGatherblock(char *argv[])
{
int ret = 0;
if (NONE == argv || 0 == strncmp("-h", argv[0], strlen("-h")) || 0 == strncmp("usage", argv[0], strlen("usage"))) {
TestGatherblockUsage();
return -EINVALED;
}
/**************** gatherblock auto test ******************/
if (0 == strncmp("-a", argv[0], strlen("-a"))) {
ret = SingleGatherblockTest("static"); ///< static creat single gatherblock test
MdelayKTask(7000);
ret |= SingleGatherblockTest("dynamic"); ///< dynamic creat single gatherblock test
MdelayKTask(7000);
ret |= MultipleGatherblockTest();
MdelayKTask(7000);
ret |= RandomAllocFreeTest("static");
MdelayKTask(7000);
ret |= RandomAllocFreeTest("dynamic");
goto out;
}
/**************** single gatherblock test ****************/
if (0 == strncmp("-s",argv[0],strlen("-s")) ) {
if (0 == strncmp("static",argv[1],strlen("static"))) {
ret = SingleGatherblockTest("static"); ///< static creat single gatherblock test
} else {
ret = SingleGatherblockTest("dynamic"); ///< dynamic creat single gatherblock test
}
goto out;
}
/**************** mutiple gatherblock test ****************/
if (0 == strncmp("-m",argv[0],strlen("-m")) ) {
ret = MultipleGatherblockTest();
goto out;
}
/******************** limitation test **********************/
if (0 == strncmp("count_size",argv[0],strlen("count_size")) ) {
int size = atoi(argv[2]);
int count = atoi(argv[1]);
GatherblockLimitTest("xsos",count,size);
ret = 1;
goto out;
}
/******************** limitation test **********************/
if (0 == strncmp("multiple_gms",argv[0],strlen("multiple_gms")) ) {
int size = atoi(argv[2]);
int count = atoi(argv[1]);
int poolnumber = atoi(argv[3]);
GatherblockLimitcountTest("xsos",count,size,poolnumber);
ret = 1;
goto out;
}
/********************** traverse test **********************/
if (0 == strncmp("traverse",argv[0],strlen("traverse")) ) {
TraverseGmTest();
goto out;
}
/**************** random alloc and free test ****************/
if (0 == strncmp("-r",argv[0],strlen("-r")) ) {
ret = RandomAllocFreeTest(argv[1]);
goto out;
}
out:
if (ret < 0) {
KPrintf("test gatherblock failed ret = %d.\n",ret);
return -ERROR;
}
return 0;
}