[lwP] Add light weight process component.

This commit is contained in:
Bernard Xiong
2018-06-10 17:57:34 +08:00
parent 682da9b249
commit bca65f30a9
22 changed files with 3675 additions and 16 deletions
+117 -16
View File
@@ -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)
{