CMap调整

正在对CMap进行更加合理化的结构调整。
This commit is contained in:
Saturneic 2019-01-20 03:10:45 +08:00
parent c36e9761d7
commit 5cfefb1374
9 changed files with 217 additions and 226 deletions

View File

@ -10,13 +10,7 @@
9221DA1121EB5FB8007310A7 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9221DA1021EB5FB8007310A7 /* main.cpp */; };
925A13A621EC68D500CBD427 /* cpart.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 925A13A421EC67C900CBD427 /* cpart.cpp */; };
925A13A921EC973000CBD427 /* cmap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 925A13A721EC973000CBD427 /* cmap.cpp */; };
925A13AD21EC9DB900CBD427 /* cthread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 925A13AB21EC9DB900CBD427 /* cthread.cpp */; };
92A1F29821F0C19500340EFA /* socket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92A1F29721F0C19500340EFA /* socket.cpp */; };
92A1F29B21F0C5CC00340EFA /* clock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92A1F29921F0C5CC00340EFA /* clock.cpp */; };
92A1F29E21F0C72C00340EFA /* addr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92A1F29D21F0C72C00340EFA /* addr.cpp */; };
92A1F2A121F1663300340EFA /* memory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92A1F29F21F1663300340EFA /* memory.cpp */; };
92A1F2A521F21DC700340EFA /* a.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92A1F2A421F21DC700340EFA /* a.cpp */; };
92D6CE6921EE4920005AEF3B /* server.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92D6CE6721EE4920005AEF3B /* server.cpp */; };
92A1F2A821F365D800340EFA /* memory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92A1F29F21F1663300340EFA /* memory.cpp */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
@ -176,15 +170,9 @@
buildActionMask = 2147483647;
files = (
9221DA1121EB5FB8007310A7 /* main.cpp in Sources */,
92A1F2A521F21DC700340EFA /* a.cpp in Sources */,
92A1F2A821F365D800340EFA /* memory.cpp in Sources */,
925A13A621EC68D500CBD427 /* cpart.cpp in Sources */,
92A1F29B21F0C5CC00340EFA /* clock.cpp in Sources */,
925A13A921EC973000CBD427 /* cmap.cpp in Sources */,
92A1F29E21F0C72C00340EFA /* addr.cpp in Sources */,
92A1F2A121F1663300340EFA /* memory.cpp in Sources */,
92D6CE6921EE4920005AEF3B /* server.cpp in Sources */,
92A1F29821F0C19500340EFA /* socket.cpp in Sources */,
925A13AD21EC9DB900CBD427 /* cthread.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

159
cmap.cpp
View File

@ -9,162 +9,3 @@
#include "memory.h"
#include "cmap.h"
CMap::CMap(string path){
ifstream map;
map.open(path+"/pcs.map");
this->path = path;
// 如果文件存在且打开成功
if(map.good()){
string line;
map>>line;
// 读取计算模块信息
if(line == "#PCS"){
BuildCPart(map);
}
map>>line;
// 读取计算模块之间的依赖关系信息
if(line == "#DEPEND"){
BuildConnection(map);
}
}
else throw "fail to open pcs.map";
}
void CMap::BuildCPart(ifstream &map){
string line;
map>>line;
// 从初始行开始读取在描述结束符之前的所有行
while(line!="END"){
// 定位括号,来截取计算模块的名字
unsigned long qs = line.find('(',0), qe = line.find(')',0);
string name = line.substr(qs+1,qe-qs-1);
// 定位尖括号来截取计算模块所在源文件的名字
qs = line.find('<',0);
qe = line.find('>',0);
string src_name = line.substr(qs+1,qe-qs-1);
// 根据以上信息构造计算管理结构对象
CPart *ncp = new CPart(path,"./Lib",src_name,name);
// 在列表中加入该对象
this->cparts.insert(pair<string,CPart *>(name,ncp));
// 构造该计算模块的输入与输出形式参数列表
vector<int>fargs_in,fargs_out;
map>>line;
if(line[0] == '>'){
fargs_in = BuidArgs(line);
}
map>>line;
if(line[0] == '<'){
fargs_out = BuidArgs(line);
}
// 设置输入与输出形式参数列表
ncp->setArgsType(fargs_in, fargs_out);
// 读入下一行
map>>line;
}
}
vector<int> CMap::BuidArgs(string &line){
vector<int> fargs;
unsigned long qs,qe;
// 定位方括号来获得函数的作用域
qs = line.find('[',0);
qe = line.find(']',0);
unsigned long idx = qs;
while(idx < qe){
unsigned long ts,te;
// 截取冒号与逗号之间的类型信息
ts = line.find(':',idx);
te = line.find(',',ts);
if(te == string::npos){
te = qe;
}
string type = line.substr(ts+1,te-ts-1);
// 在形式参数列表中加入类型信息
if(type == "int")
fargs.push_back(INT);
else if(type == "double")
fargs.push_back(DOUBLE);
// 向下移动
idx = te;
}
return fargs;
}
void CMap::BuildConnection(ifstream &map){
string line;
map>>line;
// 从初始行开始读取在描述结束符之前的所有行
while(line != "END"){
// 定位圆括号来截取计算模块的名字
unsigned long qs = line.find('(',0), qe = line.find(')',0);
string name = line.substr(qs+1,qe-qs-1);
// 通过计算模块的名字在参数列表中找到对应的计算模块
CPart *p_ncp = cparts.find(name)->second;
// 定位大括号来截取依赖模块的列表
unsigned long idx = line.find('{',qe);
unsigned long ss = line.find('}',idx);
unsigned long ts, te;
while(idx+1 < ss){
// 定位圆括号与方括号来截取依赖的计算模块的名字及依赖的相关参数信息
ts = line.find('(',idx);
te = line.find(']',ts);
if(te == string::npos){
te = ss;
}
// 在计算模块管理结构中添加构造的依赖信息管理结构
string item = line.substr(ts,te-ts+1);
p_ncp->depends.push_back(ReadItem(item));
//cout<<item<<endl;
// 向下移动
idx = te+1;
}
map>>line;
}
}
Depends CMap::ReadItem(string item){
// 构造依赖关系信息结构
Depends dep;
// 定位圆括号来截取计算模块的名字
unsigned long qs = item.find('(',0), qe = item.find(')',qs);
string name = item.substr(qs+1,qe-qs-1);
// 通过模块名字在模块列表中找到相应模块
dep.t_cpart = cparts.find(name)->second;
// 定位方括号来截取依赖参数信息
unsigned long idx = item.find('[',0),ss = item.find(']',idx);
unsigned long ts, te;
while(idx < ss){
ts = idx;
te = item.find(',',ts+1);
if(te == string::npos){
te = ss;
}
// 将字符串转换为整数
string arg = item.substr(ts+1,te-ts-1);
std::stringstream sstr;
int darg;
sstr<<arg;
sstr>>darg;
// 加入依赖参数序号信息
dep.args.push_back(darg);
// 向下移动
idx = te;
}
return dep;
}
void CMap::MapThrough(CPart *pcp,void (*func)(void *, CPart *),void *args){
// 调用回调函数
func(args,pcp);
auto dpds = pcp->depends;
for(auto i = dpds.begin(); i != dpds.end(); i++){
MapThrough(i->t_cpart, func, args);
}
}

171
cmap.h
View File

@ -13,15 +13,174 @@
#include "cpart.h"
//计算模块图类
//计算模块管理对象间的依赖关系管理结构
class cp_depend{
public:
// 指向某计算模块对象
CPart *f_cpart;
// 记录所依赖的子计算模块对象及其参数信息
map<CPart *, vector<int> > cdpd;
// 记录其父计算模块对象及其参数信息
map<CPart *, vector<int> > fdpd;
};
class Proj{
// 计算工程描述文件所在的地址
string proj_path;
string proj_file;
// 工程名
string name;
// 计算工程读入流
ifstream ifsproj;
// 源文件所在的目录
vector<string> src_paths;
// 关系描述文件所在的目录
vector<string> map_paths;
// 模块描述文件所在目录
vector<string> cpt_paths;
// 动态链接库存放的目录
string lib_path;
// 判断参数是否为字符串
bool if_string(string &arg){
if(arg[0] == '\"' && arg[arg.size()-1] == '\"') return true;
else return false;
}
// 判断下一条命令的有无
bool if_continue(string &arg){
if(arg.find(",") != string::npos && arg[arg.size()-1] == ',') return true;
else return false;
}
// 消去字符串的双引号
string cut_string(string &arg){
return arg.substr(1,arg.size()-2);
}
// 处理描述文件的命令
void deal_order(string tag, string arg){
if(tag == "cpt"){
cpt_paths.push_back(arg);
}
else if (tag == "map"){
map_paths.push_back(arg);
}
else if(tag == "src_dir"){
src_paths.push_back(arg);
}
else if(tag == "lib_dir"){
this->lib_path = arg;
}
else throw "syntax error";
}
protected:
// 检查路径或文件
void check_paths(vector<string> paths){
for(auto path : paths){
if(!~access((proj_path+path).data(),F_OK)) throw path+" is abnormal";
}
}
// 检查字符是否合法
bool if_illegal(char c){
if(isalnum(c) || c == '_') return true;
else return false;
}
// 寻找保留字
bool search_key(ifstream &ifsfile,string key){
string line;
do{
ifsfile>>line;
}while(line.find("proj") == string::npos && ifsfile.eof() == false);
if(ifsfile.eof()) return false;
return true;
}
public:
Proj(string t_projpath, string t_projfile){
// 检查工程描述文件是否可读
if(!~access(t_projpath.data(), R_OK)) throw "project directory state is abnormal";
if(proj_path[proj_path.find_last_not_of(" ")] != '/')
t_projpath += "/";
proj_path = t_projpath;
if(!~access((t_projpath+t_projfile).data(), R_OK)) throw "project file state is abnormal";
proj_file = t_projfile;
ifsproj.open(proj_path+proj_file);
if(ifsproj.good()){
string line;
// 寻找保留字
if(!search_key(ifsproj,"proj")) throw "project struct not found";
// 读取下一段信息
ifsproj>>line;
// 大括号位置
string::size_type qb_idx = line.find("{");
// 寻找任务工程名
string t_name;
if(qb_idx == string::npos) t_name = line;
else t_name = line.substr(0,qb_idx);
// 检查工程名是否含有非法字符
for(auto c:t_name){
if(if_illegal(c));
else throw "project's name has illegal char";
}
name = t_name;
// 寻找左大括号
if(qb_idx == string::npos){
ifsproj>>line;
if((qb_idx = line.find("{")) == string::npos) throw "syntax error";
}
// 逐行分析语句
string tag,cma,arg;
bool if_ctn = false;
do{
// 读取命令标签
ifsproj>>tag;
// 读取冒号
ifsproj>>cma;
// 读取命令变量
ifsproj>>arg;
// 检查参数是否含有非法字符
for(auto c:t_name){
if(if_illegal(c));
else throw " arg has illegal char";
}
if(cma != ":") throw "syntax error";
if((if_ctn = if_continue(arg)) == true){
// 消掉逗号
arg = arg.substr(0,arg.size()-1);
}
if(if_string(arg)){
deal_order(tag, cut_string(arg));
}
else throw "syntax error";
}while(if_ctn);
ifsproj>>line;
if(line != "};") throw "syntax error";
}
else throw "fail to open project file";
// 检查目录以及描述文件是否存在
if(!~access((proj_path+lib_path).data(),W_OK)) throw "lib path is abnormal";
check_paths(src_paths);
check_paths(map_paths);
check_paths(cpt_paths);
}
};
class Cpt:public Proj{
};
class Map: public Cpt{
};
//计算任务图类
class CMap{
public:
// 图中包含的的计算模块列表
// 计算任务图中包含的的计算模块列表
map<string,CPart *> cparts;
// 图目录所在的目录
string path;
// 记录计算模块依赖关系
map<CPart *, cp_depend> depends;
// 构造函数传入图包所在的目录
CMap(string path);
CMap(string proj_path);
// 根据图的表述文件构造计算模块列表
void BuildCPart(ifstream &map);
// 根据图表述文件中的描述信息,处理并转化为形式输入或输出参数列表
@ -29,7 +188,7 @@ public:
// 根据图的表述文件构造计算模块之间的依赖关系
void BuildConnection(ifstream &map);
// 根据图描述文件依赖关系描述语句所提供的信息转化为依赖关系结构
Depends ReadItem(string item);
// Depends ReadItem(string item);
// 由某个节点递归向下遍历
static void MapThrough(CPart *pcp,void(*func)(void *,CPart *),void *);

View File

@ -32,16 +32,16 @@ PCSFUNC_DEFINE(name)
//调用失败的返回
#define FAIL -1
//输入或输出入口操作柄管理类
class LibArgsTransfer{
friend class CPart;
// 计算过程参数入口或出口操作柄
vector<block_info> *args = nullptr;
// 计算模块向入口添加自定义指针参数
void addArgPtr(int size, void *p_arg);
// 清空参数入口与出口
void clear(void);
// 空构造函数
LibArgsTransfer();
public:
// 计算过程构造该类的唯一构造函数
@ -51,15 +51,15 @@ public:
// 计算过程从入口处获得参数
template<class T>
T get_arg(int idx){
T *pvle = (T *)(*args)[idx].pvle;
T *pvle = (T *)(*args)[idx].get_pvle();
// 检查用户所提供的类型与入口该位置的参数大小是否匹配
if((*args)[idx].size == sizeof(T)) return *pvle;
if((*args)[idx].get_size() == sizeof(T)) return *pvle;
else throw "arg size conflict";
}
// 计算过程从入口获得自定义指针参数
template<class T>
T *get_arg_ptr(int idx){
T *pvle = (*args)[idx].pvle;
T *pvle = (*args)[idx].get_pvle();
return pvle;
}
// 计算过程向出口末尾添加自定义指针参数

View File

@ -148,7 +148,7 @@ int CPart::Run(void){
if(func() == SUCCESS){
// 从出口获得传出参数到传出参数缓冲区
for(auto libarg : *libargs_out.args){
void *arg = main_pool.bp_malloc(libarg.size, libarg.pvle);
void *arg = main_pool.bp_malloc(libarg.get_size(), libarg.get_pvle());
args_out.push_back(arg);
}
// 清空出口数据
@ -186,7 +186,7 @@ void LibArgsTransfer::addArgPtr(int size, void *p_arg){
void LibArgsTransfer::clear(void){
for(auto arg : *args)
free(arg.pvle);
free(arg.get_pvle());
args->clear();
}

15
cpart.h
View File

@ -21,17 +21,6 @@
//计算模块入口函数类型
typedef int(*PCSFUNC)(void);
class CPart;
//计算模块管理对象间的依赖关系管理结构
class Depends{
public:
// 指向依赖的计算模块管理对象的指针
CPart *t_cpart;
// 所依赖的输入参数在计算模块输入参数列表中的序号
vector<int> args;
};
//计算模块类
class CPart{
public:
@ -41,10 +30,8 @@ public:
vector<void *> args_in, args_out;
// 计算过程入口与出口管理类
LibArgsTransfer libargs_in, libargs_out;
// 依赖计算对象列表
vector<Depends> depends;
// 计算过程的入口函数的地址
int (*func)(void) = nullptr;
PCSFUNC func = nullptr;
// 动态链接库操作柄
void *handle = nullptr;
// 源文件所在目录

View File

@ -14,18 +14,19 @@
#include "cmap.h"
#include "cthread.h"
void CPMT(void){
CMap map("./PCS");
CThread thread(&map);
thread.Analyse();
thread.DoLine();
thread.SetDaemon();
thread.CancelChildPCS(0);
}
int main(void){
initClock();
try{
Proj nproj("./PCS","pcs.proj");
}
catch(char const *error_info){
printf("%s\n",error_info);
}
return 0;
}
void wiki_cpart(void){
CPart ncp("./PCS","./Libs","a.cpp","A");
void *a = main_pool.bv_malloc<double>(2.0);
void *b = main_pool.bv_malloc<double>(3.5);
@ -39,9 +40,6 @@ int main(void){
main_pool.b_free(a);
main_pool.b_free(b);
main_pool.b_free(c);
return 0;
}

View File

@ -11,18 +11,35 @@
#include <stdint.h>
struct block_info{
//内存块管理类
class block_info{
friend class BlocksPool;
// 内存块大小
uint32_t size = 0;
// 锁
int lock = 0;
// 是否受到保护
bool pted = false;
// 指向内存块的指针
void *pvle = nullptr;
block_info(){
}
public:
// 简化构造函数
block_info(uint32_t size,void *pvle){
this->size = size;
this->pvle = pvle;
}
block_info(){
void *get_pvle(void){
return pvle;
}
uint32_t get_size(void){
return size;
}
};
#endif /* memory_type_h */

View File

@ -28,6 +28,7 @@ struct compute_result{
//通用数据包类
class packet{
public:
// 数据包类型
unsigned int type;
// 记录块的大小及内容所在的内存地址
vector<pair<unsigned int, void *>> buffs;