diff options
| author | Bernard Xiong <[email protected]> | 2018-06-10 17:57:34 +0800 |
|---|---|---|
| committer | Bernard Xiong <[email protected]> | 2018-06-10 17:57:34 +0800 |
| commit | bca65f30a90857287dc1371ddbc8d5f165691c7f (patch) | |
| tree | 73f7c113f17883996ddb2009bbb8726b9f6c5f0a /components/dfs/src | |
| parent | 682da9b249c8019c078b277742a6b36deb2af7b2 (diff) | |
[lwP] Add light weight process component.
Diffstat (limited to 'components/dfs/src')
| -rw-r--r-- | components/dfs/src/dfs.c | 133 |
1 files changed, 117 insertions, 16 deletions
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) { |
