Skip to content
Snippets Groups Projects
Commit 3d3c095d authored by Terraneo Federico's avatar Terraneo Federico
Browse files

Code optimizations

parent 5a481dde
Branches
Tags
No related merge requests found
......@@ -175,6 +175,8 @@ DefaultConsole& DefaultConsole::instance()
void DefaultConsole::IRQset(intrusive_ref_ptr<ConsoleDevice> console)
{
//Note: should be safe to be called also outside of IRQ as it's used by
//checkInit
atomic_store(&rawConsole,console);
atomic_store(&terminal,
intrusive_ref_ptr<TerminalDevice>(new TerminalDevice(rawConsole)));
......
......@@ -68,18 +68,29 @@ int DeviceFile::fstat(struct stat* pstat) const
// class DevFs
//
DevFs::DevFs()
DevFs::DevFs() : inodeCount(1)
{
string null="/null";
string zero="/zero";
string console="/console";
addDeviceFile("/null",intrusive_ref_ptr<DeviceFile>(new NullFile));
addDeviceFile("/zero",intrusive_ref_ptr<DeviceFile>(new ZeroFile));
addDeviceFile("/console",DefaultConsole::instance().get());
}
files[StringPart(null)]=intrusive_ref_ptr<DeviceFile>(new NullFile);
files[StringPart(zero)]=intrusive_ref_ptr<DeviceFile>(new ZeroFile);
bool DevFs::addDeviceFile(const char* name, intrusive_ref_ptr<DeviceFile> file)
{
if(name==0 || name[0]!='/' || name[1]=='\0') return false;
int len=strlen(name);
for(int i=1;i<len;i++) if(name[i]=='/') return false;
Lock<FastMutex> l(mutex);
bool result=files.insert(make_pair(StringPart(name),file)).second;
if(result) assignInode(file);
return result;
}
intrusive_ref_ptr<DeviceFile> consoleDev=DefaultConsole::instance().get();
if(consoleDev) files[StringPart(console)]=consoleDev;
else files[StringPart(console)]=files[StringPart(null)];
bool DevFs::removeDeviceFile(const char* name)
{
if(name==0 || name[0]!='/' || name[1]=='\0') return false;
Lock<FastMutex> l(mutex);
return files.erase(StringPart(name))==1;
}
int DevFs::open(intrusive_ref_ptr<FileBase>& file, StringPart& name,
......@@ -121,4 +132,9 @@ bool DevFs::areAllFilesClosed()
return true;
}
void DevFs::assignInode(intrusive_ref_ptr<DeviceFile> file)
{
file->setFileInfo(atomicAddExchange(&inodeCount,1),filesystemId);
}
} //namespace miosix
......@@ -112,6 +112,24 @@ public:
*/
DevFs();
/**
* Add a device file to DevFs
* \param name File name, must start with a slash.
* \param file file to add
* \return true if the file was successfully added
*/
bool addDeviceFile(const char *name, intrusive_ref_ptr<DeviceFile> file);
/**
* Remove a device file. This prevents the file from being opened again,
* but if at the time this member function is called the file is already
* opened, it won't be deallocated till the application closes it, thanks
* to the reference counting scheme.
* \param name name of file to remove
* \return true if the file was successfully removed
*/
bool removeDeviceFile(const char *name);
/**
* Open a file
* \param file the file object will be stored here, if the call succeeds
......@@ -148,8 +166,11 @@ public:
virtual bool areAllFilesClosed();
private:
void assignInode(intrusive_ref_ptr<DeviceFile> file);
FastMutex mutex;
std::map<StringPart,intrusive_ref_ptr<DeviceFile> > files;
int inodeCount;
};
} //namespace miosix
......
......@@ -284,9 +284,8 @@ private:
ResolvedPath PathResolution::resolvePath(string& path, bool followLastSymlink)
{
char rootPath[2]; rootPath[0]='/'; rootPath[1]='\0';//A non-const "/" string
map<StringPart,intrusive_ref_ptr<FilesystemBase> >::const_iterator it;
it=filesystems.find(StringPart(rootPath));
it=filesystems.find(StringPart("/"));
if(it==filesystems.end()) return ResolvedPath(-ENOENT); //should not happen
root=fs=it->second;
syms=fs->supportsSymlinks();
......@@ -505,9 +504,8 @@ int FilesystemManager::umount(const char* path, bool force)
if(path==0 || path[0]=='\0') return -ENOENT;
int len=strlen(path);
if(len>PATH_MAX) return -ENAMETOOLONG;
string pathStr(path);
Lock<FastMutex> l(mutex); //A reader-writer lock would be better
fsIt it=filesystems.find(StringPart(pathStr));
fsIt it=filesystems.find(StringPart(path));
if(it==filesystems.end()) return -EINVAL;
//This finds all the filesystems that have to be recursively umounted
......
......@@ -62,11 +62,29 @@ StringPart::StringPart(char* s, unsigned int idx, unsigned int off)
offset=min(offset,index);
}
StringPart::StringPart(const char* s)
: ccstr(s), offset(0), saved('\0'), owner(false), type(CCSTR)
{
assert(ccstr); //Passed pointer can't be null
index=strlen(s);
}
StringPart::StringPart(StringPart& rhs, unsigned int idx, unsigned int off)
: saved('\0'), owner(false), type(rhs.type)
{
if(type==CSTR) this->cstr=rhs.cstr;
else this->str=rhs.str;
switch(type)
{
case CSTR:
this->cstr=rhs.cstr;
break;
case CCSTR:
type=CSTR; //To make a substring of a CCSTR we need to make a copy
if(rhs.empty()==false) assign(rhs); else cstr=&saved;
break;
case CPPSTR:
this->str=rhs.str;
break;
}
if(idx!=string::npos && idx<rhs.length())
{
index=rhs.offset+idx;//Make index relative to beginning of original str
......@@ -79,7 +97,7 @@ StringPart::StringPart(StringPart& rhs, unsigned int idx, unsigned int off)
cstr[index]='\0';
}
} else index=rhs.index;
offset=min(rhs.offset+off,index);
offset=min(rhs.offset+off,index); //Works for CCSTR as offset is always zero
}
StringPart::StringPart(const StringPart& rhs)
......@@ -105,16 +123,36 @@ bool StringPart::startsWith(const StringPart& rhs) const
return memcmp(this->c_str(),rhs.c_str(),rhs.length())==0;
}
const char *StringPart::c_str() const
{
switch(type)
{
case CSTR: return cstr+offset;
case CCSTR: return ccstr; //Offset always 0
default: return str->c_str()+offset;
}
}
char StringPart::operator[] (unsigned int index) const
{
switch(type)
{
case CSTR: return cstr[offset+index];
case CCSTR: return ccstr[index]; //Offset always 0
default: return (*str)[offset+index];
}
}
void StringPart::clear()
{
if(type==CSTR)
{
cstr[index]=saved;//Worst case we'll overwrite terminating \0 with an \0
if(owner) delete[] cstr;
} else {
} else if(type==CPPSTR) {
if(index!=str->length()) (*str)[index]=saved;
if(owner) delete str;
}
} //For CCSTR there's nothing to do
cstr=&saved; //Reusing saved as an empty string
saved='\0';
index=offset=0;
......
......@@ -36,7 +36,7 @@ namespace miosix {
/**
* \internal
* This class is used to take a substring of a string containing a file path
* without creating a substring, and therefore requiring additional memory
* without creating a copy, and therefore requiring additional memory
* allocation.
*
* When parsing a path like "/home/test/directory/file" it is often necessary
......@@ -102,6 +102,16 @@ public:
explicit StringPart(char *s, unsigned int idx=std::string::npos,
unsigned int off=0);
/**
* Constructor from const C string
* \param s original string. A pointer to the string is taken, the string
* is NOT copied. Therefore, the caller is responsible to guarantee the
* string won't be deallocated while this class is alive. Note that this
* constructor misses the idx and off parameters as it's not possible to
* make an in-place substring of a string if it's const.
*/
explicit StringPart(const char *s);
/**
* Substring constructor. Given a StringPart, produce another StringPart
* holding a substring of the original StringPart. Unlike the normal copy
......@@ -153,15 +163,13 @@ public:
/**
* \return the StringPart as a C string
*/
const char *c_str() const
{
return type==CSTR ? cstr+offset : str->c_str()+offset;
}
const char *c_str() const;
char operator[] (unsigned int index) const
{
return type==CSTR ? cstr[offset+index] : (*str)[offset+index];
}
/**
* \param index index into the string
* \return the equivalent of this->c_str()[index]
*/
char operator[] (unsigned int index) const;
/**
* \return true if the string is empty
......@@ -188,13 +196,14 @@ private:
union {
std::string *str; ///< Pointer to underlying C++ string
char *cstr; ///< Pointer to underlying C string
const char *ccstr; ///< Pointer to underlying const C string
};
unsigned int index; ///< Index into the character substituted by '\0'
unsigned int offset; ///< Offset to skip the first part of a string
char saved; ///< Char that was replaced by '\0'
bool owner; ///< True if this class owns str
char type; ///< either CPPSTR or CSTR. Using char to reduce size
enum { CPPSTR, CSTR }; ///< Possible values fot type
enum { CPPSTR, CSTR, CCSTR }; ///< Possible values fot type
};
} //namespace miosix
......
......@@ -309,6 +309,8 @@
</df>
<df name="filesystem">
<df name="devfs">
<in>base_files.cpp</in>
<in>base_files.h</in>
<in>console_device.cpp</in>
<in>console_device.h</in>
<in>devfs.cpp</in>
......@@ -331,6 +333,8 @@
<in>file_access.h</in>
<in>filesystem.cpp</in>
<in>filesystem.h</in>
<in>stringpart.cpp</in>
<in>stringpart.h</in>
</df>
<df name="interfaces">
<in>arch_registers.h</in>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment