summaryrefslogtreecommitdiff
path: root/components/dfs
diff options
context:
space:
mode:
authorBernard Xiong <[email protected]>2018-06-10 17:57:34 +0800
committerBernard Xiong <[email protected]>2018-06-10 17:57:34 +0800
commitbca65f30a90857287dc1371ddbc8d5f165691c7f (patch)
tree73f7c113f17883996ddb2009bbb8726b9f6c5f0a /components/dfs
parent682da9b249c8019c078b277742a6b36deb2af7b2 (diff)
[lwP] Add light weight process component.
Diffstat (limited to 'components/dfs')
-rw-r--r--components/dfs/include/dfs.h8
-rw-r--r--components/dfs/src/dfs.c133
2 files changed, 125 insertions, 16 deletions
diff --git a/components/dfs/include/dfs.h b/components/dfs/include/dfs.h
index 91ef42ab56..f17458bd69 100644
--- a/components/dfs/include/dfs.h
+++ b/components/dfs/include/dfs.h
@@ -95,6 +95,12 @@ struct dirent
char d_name[DFS_PATH_MAX]; /* The null-terminated file name */
};
+struct dfs_fdtable
+{
+ uint32_t maxfd;
+ struct dfs_fd **fds;
+};
+
/* Initialization of dfs */
int dfs_init(void);
@@ -110,6 +116,8 @@ struct dfs_fd *fd_get(int fd);
void fd_put(struct dfs_fd *fd);
int fd_is_open(const char *pathname);
+struct dfs_fdtable* dfs_fdtable_get(void);
+
#ifdef __cplusplus
}
#endif
diff --git a/components/dfs/src/dfs.c b/components/dfs/src/dfs.c
index 858399fd13..f613168a4c 100644
--- a/components/dfs/src/dfs.c
+++ b/components/dfs/src/dfs.c
@@ -21,12 +21,16 @@
* Date Author Notes
* 2005-02-22 Bernard The first version.
* 2017-12-11 Bernard Use rt_free to instead of free in fd_is_open().
+ * 2018-03-20 Heyuanjie dynamic allocation FD
*/
#include <dfs.h>
#include <dfs_fs.h>
#include <dfs_file.h>
#include "dfs_private.h"
+#ifdef RT_USING_LWP
+#include <lwp.h>
+#endif
/* Global variables */
const struct dfs_filesystem_ops *filesystem_operation_table[DFS_FILESYSTEM_TYPES_MAX];
@@ -39,7 +43,8 @@ static struct rt_mutex fslock;
char working_directory[DFS_PATH_MAX] = {"/"};
#endif
-struct dfs_fd fd_table[DFS_FD_MAX];
+static struct dfs_fdtable _fdtab;
+static int fd_alloc(struct dfs_fdtable *fdt, int startfd);
/**
* @addtogroup DFS
@@ -57,7 +62,7 @@ int dfs_init(void)
/* clear filesystem table */
memset(filesystem_table, 0, sizeof(filesystem_table));
/* clean fd table */
- memset(fd_table, 0, sizeof(fd_table));
+ memset(&_fdtab, 0, sizeof(_fdtab));
/* create device filesystem lock */
rt_mutex_init(&fslock, "fslock", RT_IPC_FLAG_FIFO);
@@ -90,9 +95,13 @@ INIT_PREV_EXPORT(dfs_init);
*/
void dfs_lock(void)
{
- rt_err_t result;
+ rt_err_t result = -RT_EBUSY;
+
+ while (result == -RT_EBUSY)
+ {
+ result = rt_mutex_take(&fslock, RT_WAITING_FOREVER);
+ }
- result = rt_mutex_take(&fslock, RT_WAITING_FOREVER);
if (result != RT_EOK)
{
RT_ASSERT(0);
@@ -109,6 +118,54 @@ void dfs_unlock(void)
rt_mutex_release(&fslock);
}
+static int fd_alloc(struct dfs_fdtable *fdt, int startfd)
+{
+ int idx;
+
+ /* find an empty fd entry */
+ for (idx = startfd; idx < fdt->maxfd; idx++)
+ {
+ if (fdt->fds[idx] == RT_NULL)
+ break;
+ if (fdt->fds[idx]->ref_count == 0)
+ break;
+ }
+
+ /* allocate a larger FD container */
+ if (idx == fdt->maxfd && fdt->maxfd < DFS_FD_MAX)
+ {
+ int cnt, index;
+ struct dfs_fd **fds;
+
+ /* increase the number of FD with 4 step length */
+ cnt = fdt->maxfd + 4;
+ cnt = cnt > DFS_FD_MAX? DFS_FD_MAX : cnt;
+
+ fds = rt_realloc(fdt->fds, cnt * sizeof(struct dfs_fd *));
+ if (fds == NULL) goto __out; /* return fdt->maxfd */
+
+ /* clean the new allocated fds */
+ for (index = fdt->maxfd; index < cnt; index ++)
+ {
+ fds[index] = NULL;
+ }
+
+ fdt->fds = fds;
+ fdt->maxfd = cnt;
+ }
+
+ /* allocate 'struct dfs_fd' */
+ if (idx < fdt->maxfd &&fdt->fds[idx] == RT_NULL)
+ {
+ fdt->fds[idx] = rt_malloc(sizeof(struct dfs_fd));
+ if (fdt->fds[idx] == RT_NULL)
+ idx = fdt->maxfd;
+ }
+
+__out:
+ return idx;
+}
+
/**
* @ingroup Fd
* This function will allocate a file descriptor.
@@ -119,21 +176,23 @@ int fd_new(void)
{
struct dfs_fd *d;
int idx;
+ struct dfs_fdtable *fdt;
+ fdt = dfs_fdtable_get();
/* lock filesystem */
dfs_lock();
/* find an empty fd entry */
- for (idx = 0; idx < DFS_FD_MAX && fd_table[idx].ref_count > 0; idx++);
+ idx = fd_alloc(fdt, 0);
/* can't find an empty fd entry */
- if (idx == DFS_FD_MAX)
+ if (idx == fdt->maxfd)
{
idx = -(1 + DFS_FD_OFFSET);
goto __result;
}
- d = &(fd_table[idx]);
+ d = fdt->fds[idx];
d->ref_count = 1;
d->magic = DFS_FD_MAGIC;
@@ -154,13 +213,15 @@ __result:
struct dfs_fd *fd_get(int fd)
{
struct dfs_fd *d;
+ struct dfs_fdtable *fdt;
+ fdt = dfs_fdtable_get();
fd = fd - DFS_FD_OFFSET;
- if (fd < 0 || fd >= DFS_FD_MAX)
+ if (fd < 0 || fd >= fdt->maxfd)
return NULL;
dfs_lock();
- d = &fd_table[fd];
+ d = fdt->fds[fd];
/* check dfs_fd valid or not */
if (d->magic != DFS_FD_MAGIC)
@@ -186,12 +247,25 @@ void fd_put(struct dfs_fd *fd)
RT_ASSERT(fd != NULL);
dfs_lock();
+
fd->ref_count --;
/* clear this fd entry */
if (fd->ref_count == 0)
{
- memset(fd, 0, sizeof(struct dfs_fd));
+ int index;
+ struct dfs_fdtable *fdt;
+
+ fdt = dfs_fdtable_get();
+ for (index = 0; index < fdt->maxfd; index ++)
+ {
+ if (fdt->fds[index] == fd)
+ {
+ rt_free(fd);
+ fdt->fds[index] = 0;
+ break;
+ }
+ }
}
dfs_unlock();
}
@@ -211,7 +285,9 @@ int fd_is_open(const char *pathname)
unsigned int index;
struct dfs_filesystem *fs;
struct dfs_fd *fd;
+ struct dfs_fdtable *fdt;
+ fdt = dfs_fdtable_get();
fullpath = dfs_normalize_path(NULL, pathname);
if (fullpath != NULL)
{
@@ -233,11 +309,10 @@ int fd_is_open(const char *pathname)
dfs_lock();
- for (index = 0; index < DFS_FD_MAX; index++)
+ for (index = 0; index < fdt->maxfd; index++)
{
- fd = &(fd_table[index]);
- if (fd->fops == NULL)
- continue;
+ fd = fdt->fds[index];
+ if (fd == NULL) continue;
if (fd->fops == fs->ops->fops && strcmp(fd->path, mountpath) == 0)
{
@@ -414,17 +489,43 @@ up_one:
return fullpath;
}
RTM_EXPORT(dfs_normalize_path);
+
+/**
+ * This function will get the file descriptor table of current process.
+ */
+struct dfs_fdtable* dfs_fdtable_get(void)
+{
+ struct dfs_fdtable *fdt;
+#ifdef RT_USING_LWP
+ struct rt_lwp *lwp;
+
+ lwp = (struct rt_lwp *)rt_thread_self()->user_data;
+ if (lwp)
+ fdt = &lwp->fdt;
+ else
+ fdt = &_fdtab;
+#else
+ fdt = &_fdtab;
+#endif
+
+ return fdt;
+}
+
#ifdef RT_USING_FINSH
#include <finsh.h>
int list_fd(void)
{
int index;
+ struct dfs_fdtable *fd_table;
+
+ fd_table = dfs_fdtable_get();
+ if (!fd_table) return -1;
rt_enter_critical();
- for (index = 0; index < DFS_FD_MAX; index ++)
+ for (index = 0; index < fd_table->maxfd; index ++)
{
- struct dfs_fd *fd = &(fd_table[index]);
+ struct dfs_fd *fd = fd_table->fds[index];
if (fd->fops)
{