Xiang Xiao 85a6aaa322 apps/testing: Move irtest/sensortest/resmonitor/monkey to apps/system
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
2025-01-27 02:25:08 +01:00

258 lines
6.5 KiB
C

/****************************************************************************
* apps/system/resmonitor/fillmem.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <errno.h>
#include <getopt.h>
#include <malloc.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <syslog.h>
#include <unistd.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define PAYLOADSIZE 100
/****************************************************************************
* Private Data
****************************************************************************/
static int go = 1;
/****************************************************************************
* Private Functions
****************************************************************************/
static void handler(int sig)
{
go = 0;
}
static void show_usages(void)
{
syslog(LOG_WARNING,
"Usage: CMD [-f <fill size>] [-r <remain size>]\n"
"\t\t-f: set fill mem size, can end with KkMm, (disabled if -r "
"is set)\n"
"\t\t-r: set remain size, can end with KkMm\n"
"\t\t-p: set percentage occupancy\n");
exit(1);
}
static uintmax_t bytes(char *s)
{
uintmax_t n;
if (sscanf(s, "%ju", &n) < 1)
{
return 0;
}
if ((s[strlen(s) - 1] == 'k') || (s[strlen(s) - 1] == 'K'))
{
n *= 1024;
}
if ((s[strlen(s) - 1] == 'm') || (s[strlen(s) - 1] == 'M'))
{
n *= (1024 * 1024);
}
return n;
}
int main(int argc, char *argv[])
{
struct mallinfo g_alloc_info;
size_t fill_size = 0;
size_t remain_size = 0;
size_t free_mem = 0;
size_t largest_mem = 0;
size_t total_mem = 0;
size_t used_mem = 0;
float fill_percentage = 0;
char *payloads[PAYLOADSIZE];
int idx = 0;
go = 1;
struct timeval sleeptime;
memset(payloads, 0, sizeof(payloads));
int mode = 0;
if (argc == 1)
{
show_usages();
}
int o;
while ((o = getopt(argc, argv, "r:f:p:")) != EOF)
{
switch (o)
{
case 'r':
remain_size = (size_t)bytes(optarg);
mode = 1;
break;
case 'f':
fill_size = (size_t)bytes(optarg);
break;
case 'p':
fill_percentage = atof(optarg);
mode = 2;
break;
default:
show_usages();
break;
}
}
g_alloc_info = mallinfo();
total_mem = (size_t)g_alloc_info.arena;
free_mem = (size_t)g_alloc_info.fordblks;
largest_mem = (size_t)g_alloc_info.mxordblk;
used_mem = (size_t)g_alloc_info.uordblks;
if (mode == 2)
{
size_t per_fill = (size_t)total_mem * fill_percentage;
syslog(LOG_INFO, "per fill is %zu\n", per_fill);
fill_size = per_fill - used_mem;
if (fill_size < 0)
{
syslog(LOG_WARNING,
"memory has used %zu, has exceed %f\n",
used_mem,
fill_percentage);
return 0;
}
mode = 0;
}
if (remain_size != 0 || mode == 1)
{
if (remain_size > free_mem)
{
syslog(LOG_INFO,
"remain is greater than free, remain %zu, free %zu\n",
remain_size,
free_mem);
return 0;
}
fill_size = free_mem - remain_size;
}
if (fill_size > free_mem)
{
syslog(LOG_INFO,
"no enough mem, fill %zu, free %zu\n",
fill_size,
free_mem);
return 0;
}
syslog(LOG_INFO,
"fill size %zu, free %zu, largest %zu\n",
fill_size,
free_mem,
largest_mem);
if (fill_size <= largest_mem)
{
payloads[0] = malloc(fill_size - 100);
if (payloads[0] == NULL)
{
syslog(LOG_ERR, "malloc fail, errno %d\n", errno);
goto END;
}
syslog(LOG_INFO, "malloc size %zu\n", fill_size);
}
else
{
while ((fill_size > largest_mem) && (idx < PAYLOADSIZE - 1))
{
if (largest_mem <= 150)
{
break;
}
payloads[idx] = malloc(largest_mem - 100);
if (payloads[idx] == NULL)
{
syslog(LOG_ERR, "malloc fail, errno %d\n", errno);
goto END;
}
fill_size -= largest_mem;
syslog(LOG_INFO, "idx: %d, malloc size %zu\n", idx, largest_mem);
g_alloc_info = mallinfo();
largest_mem = (size_t)g_alloc_info.mxordblk;
idx++;
}
if (largest_mem > 100)
{
if (largest_mem - fill_size <= 100)
{
fill_size = largest_mem - 100;
}
payloads[idx] = malloc(fill_size);
if (payloads[idx] == NULL)
{
syslog(LOG_ERR, "malloc fail, errno %d\n", errno);
goto END;
}
syslog(LOG_INFO, "idx: %d, malloc size %zu\n", idx, fill_size);
}
}
signal(SIGINT, handler);
signal(SIGKILL, handler);
while (go)
{
sleeptime.tv_sec = 600;
sleeptime.tv_usec = 0;
select(0, NULL, NULL, NULL, &sleeptime);
}
syslog(LOG_INFO, "program complete!\n");
END:
for (int i = 0; i < PAYLOADSIZE; i++)
{
if (payloads[i] != NULL)
{
free(payloads[i]);
}
}
return 0;
}