nuttx/mm/mempool/mempool_procfs.c
Jiuzhu Dong a01f3beefd mm/mempool: support multiple memory pool
Signed-off-by: Jiuzhu Dong <dongjiuzhu1@xiaomi.com>
2022-10-28 21:31:35 +08:00

264 lines
8.6 KiB
C

/****************************************************************************
* mm/mempool/mempool_procfs.c
*
* 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 <nuttx/config.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <nuttx/kmalloc.h>
#include <nuttx/mm/mempool.h>
#include <nuttx/nuttx.h>
#include <nuttx/fs/procfs.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Determines the size of an intermediate buffer that must be large enough
* to handle the longest line generated by this logic.
*/
#define MEMPOOLINFO_LINELEN 80
/****************************************************************************
* Private Types
****************************************************************************/
/* This structure describes one open "file" */
struct mempool_file_s
{
struct procfs_file_s base; /* Base open file structure */
unsigned int linesize; /* Number of valid characters in line[] */
char line[MEMPOOLINFO_LINELEN]; /* Pre-allocated buffer for formatted lines */
};
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
static int mempool_open(FAR struct file *filep, FAR const char *relpath,
int oflags, mode_t mode);
static int mempool_close(FAR struct file *filep);
static int mempool_dup(FAR const struct file *oldp,
FAR struct file *newp);
static int mempool_stat(FAR const char *relpath, FAR struct stat *buf);
static ssize_t mempool_read(FAR struct file *filep, FAR char *buffer,
size_t buflen);
/****************************************************************************
* Public Data
****************************************************************************/
const struct procfs_operations mempool_operations =
{
mempool_open, /* open */
mempool_close, /* close */
mempool_read, /* read */
NULL, /* write */
mempool_dup, /* dup */
NULL, /* opendir */
NULL, /* closedir */
NULL, /* readdir */
NULL, /* rewinddir */
mempool_stat /* stat */
};
static FAR struct mempool_procfs_entry_s *g_mempool_procfs = NULL;
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: mempool_open
****************************************************************************/
static int mempool_open(FAR struct file *filep, FAR const char *relpath,
int oflags, mode_t mode)
{
FAR struct mempool_file_s *procfile;
procfile = kmm_zalloc(sizeof(struct mempool_file_s));
if (procfile == NULL)
{
return -ENOMEM;
}
filep->f_priv = procfile;
return 0;
}
/****************************************************************************
* Name: mempool_close
****************************************************************************/
static int mempool_close(FAR struct file *filep)
{
kmm_free(filep->f_priv);
filep->f_priv = NULL;
return 0;
}
/****************************************************************************
* Name: mempool_read
****************************************************************************/
static ssize_t mempool_read(FAR struct file *filep, FAR char *buffer,
size_t buflen)
{
FAR const struct mempool_procfs_entry_s *entry;
FAR struct mempool_file_s *procfile;
size_t linesize;
size_t copysize;
size_t totalsize;
off_t offset;
offset = filep->f_pos;
procfile = filep->f_priv;
linesize = procfs_snprintf(procfile->line, MEMPOOLINFO_LINELEN,
"%13s%11s%9s%9s%9s%9s%9s\n", "", "total",
"bsize", "nused", "nfree", "nifree",
"nwaiter");
copysize = procfs_memcpy(procfile->line, linesize, buffer, buflen,
&offset);
totalsize = copysize;
for (entry = g_mempool_procfs; entry != NULL; entry = entry->next)
{
if (totalsize < buflen)
{
FAR struct mempool_s *pool = container_of(entry, struct mempool_s,
procfs);
struct mempoolinfo_s minfo;
buffer += copysize;
buflen -= copysize;
mempool_info(pool, &minfo);
linesize = procfs_snprintf(procfile->line, MEMPOOLINFO_LINELEN,
"%12s:%11lu%9lu%9lu%9lu%9lu%9lu\n",
entry->name, minfo.arena,
minfo.sizeblks, minfo.aordblks,
minfo.ordblks, minfo.iordblks,
minfo.nwaiter);
copysize = procfs_memcpy(procfile->line, linesize, buffer,
buflen, &offset);
totalsize += copysize;
}
}
filep->f_pos += totalsize;
return totalsize;
}
/****************************************************************************
* Name: mempool_dup
*
* Description:
* Duplicate open file data in the new file structure.
*
****************************************************************************/
static int mempool_dup(FAR const struct file *oldp, FAR struct file *newp)
{
FAR struct mempool_file_s *oldattr;
FAR struct mempool_file_s *newattr;
oldattr = oldp->f_priv;
newattr = kmm_malloc(sizeof(struct mempool_file_s));
if (newattr == NULL)
{
return -ENOMEM;
}
memcpy(newattr, oldattr, sizeof(struct mempool_file_s));
newp->f_priv = newattr;
return 0;
}
/****************************************************************************
* Name: mempool_stat
*
* Description: Return information about a file or directory
*
****************************************************************************/
static int mempool_stat(FAR const char *relpath, FAR struct stat *buf)
{
memset(buf, 0, sizeof(struct stat));
buf->st_mode = S_IFREG | S_IROTH | S_IRGRP | S_IRUSR;
return 0;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: mempool_procfs_register
*
* Description:
* Add a new mempool entry to the procfs file system.
*
* Input Parameters:
* entry - Describes the entry to be registered.
*
****************************************************************************/
void mempool_procfs_register(FAR struct mempool_procfs_entry_s *entry,
FAR const char *name)
{
entry->name = name;
entry->next = g_mempool_procfs;
g_mempool_procfs = entry;
}
/****************************************************************************
* Name: mempool_procfs_unregister
*
* Description:
* Remove a mempool entry from the procfs file system.
*
* Input Parameters:
* entry - Describes the entry to be unregistered.
*
****************************************************************************/
void mempool_procfs_unregister(FAR struct mempool_procfs_entry_s *entry)
{
FAR struct mempool_procfs_entry_s **cur;
for (cur = &g_mempool_procfs; *cur != NULL; cur = &(*cur)->next)
{
if (*cur == entry)
{
*cur = entry->next;
break;
}
}
}