/**************************************************************************** * mm/mempool/mempool_procfs.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 #include #include #include #include #include #include /**************************************************************************** * 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 g_mempool_operations = { mempool_open, /* open */ mempool_close, /* close */ mempool_read, /* read */ NULL, /* write */ NULL, /* poll */ 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; } } }