mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-09-22 11:30:01 +08:00
[lwP] Add light weight process component.
This commit is contained in:
+117
-16
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user