初步实现异常捕获机制
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
build/
|
21
.vscode/c_cpp_properties.json
vendored
Normal file
21
.vscode/c_cpp_properties.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Linux",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/**"
|
||||
],
|
||||
"defines": [
|
||||
"_DEBUG",
|
||||
"UNICODE",
|
||||
"_UNICODE"
|
||||
],
|
||||
"windowsSdkVersion": "10.0.22621.0",
|
||||
"compilerPath": "C:/cygwin64/bin/gcc.exe",
|
||||
"cStandard": "c17",
|
||||
"cppStandard": "c++17",
|
||||
"intelliSenseMode": "linux-gcc-x64"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
46
.vscode/launch.json
vendored
Normal file
46
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
{
|
||||
// 使用 IntelliSense 了解相关属性。
|
||||
// 悬停以查看现有属性的描述。
|
||||
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "(Windows) 启动",
|
||||
"type": "cppvsdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/hello.exe",
|
||||
"args": [],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${fileDirname}",
|
||||
"environment": [],
|
||||
"console": "externalTerminal"
|
||||
},
|
||||
{
|
||||
"name": "(gdb) 启动",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/hello.exe",
|
||||
"args": [],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${fileDirname}",
|
||||
"environment": [],
|
||||
"externalConsole": false,
|
||||
"MIMode": "gdb",
|
||||
"miDebuggerPath": "/path/to/gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "为 gdb 启用整齐打印",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"description": "将反汇编风格设置为 Intel",
|
||||
"text": "-gdb-set disassembly-flavor intel",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
]
|
||||
}
|
10
.vscode/settings.json
vendored
Normal file
10
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"files.associations": {
|
||||
"stdio.h": "c",
|
||||
"regex.h": "c",
|
||||
"test1.h": "c",
|
||||
"stdint.h": "c",
|
||||
"exception.h": "c",
|
||||
"mythread.h": "c"
|
||||
}
|
||||
}
|
8
ReadMe.txt
Normal file
8
ReadMe.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
|
||||
|
||||
2024.6.18
|
||||
初步实现 基于线程的异常捕获,触发异常时可以自动释放异常捕获期间的动态内存
|
||||
|
||||
|
||||
|
||||
|
78
main.c
Normal file
78
main.c
Normal file
@@ -0,0 +1,78 @@
|
||||
#include "stdio.h"
|
||||
#include "regex.h"
|
||||
#include "stdlib.h"
|
||||
#include "stdint.h"
|
||||
#include "soft/exception.h"
|
||||
#include "soft/mythread.h"
|
||||
#include "unistd.h"
|
||||
|
||||
|
||||
int thread_fun(void *t){
|
||||
printf("run in thread_fun.\n");
|
||||
|
||||
while(1){
|
||||
sleep(5);
|
||||
throw_("s");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SystemInit();
|
||||
extern char **environ;
|
||||
int main(int argc,char *argv[]){
|
||||
int id;
|
||||
printf("hello world.\n");
|
||||
|
||||
|
||||
|
||||
// while(p&&(*p)){
|
||||
|
||||
// printf("%s\n",*p++);
|
||||
// }
|
||||
|
||||
// printf("a+b=%d",test_add(3,5));
|
||||
id=myth_create(thread_fun,NULL);
|
||||
id=myth_create(NULL,NULL);
|
||||
// sleep(10);
|
||||
myth_join();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#define func_def(...)
|
||||
|
||||
|
||||
|
||||
|
||||
#define SLOT_FUN_RUN(fun,param) \
|
||||
((slot_fun_def)(fun))(param[0],param[1],param[2],\
|
||||
param[3],param[4],param[5],param[6],param[7])
|
||||
|
||||
typedef void (*slot_fun_def)(size_t a,size_t b,size_t c,size_t d,size_t e,size_t f,size_t g,size_t h);
|
||||
|
||||
|
||||
|
||||
void funptr_test(){
|
||||
printf("print from funptr_test fun.\n");
|
||||
}
|
||||
|
||||
void add_test(int a,int b,void (*f)()){
|
||||
printf("add_fun:%d+%d=%d\n",a,b,a+b);
|
||||
f();
|
||||
}
|
||||
|
||||
void SystemInit()
|
||||
{
|
||||
func_def(int (int a,int b){
|
||||
int a;
|
||||
return;
|
||||
});
|
||||
size_t pars[8]={4,5,(size_t)funptr_test};
|
||||
SLOT_FUN_RUN(add_test,pars);
|
||||
}
|
||||
|
||||
|
||||
|
189
make.py
Normal file
189
make.py
Normal file
@@ -0,0 +1,189 @@
|
||||
|
||||
# -*- coding: gbk -*-
|
||||
|
||||
|
||||
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
|
||||
'''
|
||||
|
||||
<EFBFBD>ı<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ű<EFBFBD>֮<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫȫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>
|
||||
|
||||
'''
|
||||
|
||||
|
||||
CC = 'gcc'
|
||||
# CC = 'C:\\ARM_GCC\\bin\\arm-none-eabi-gcc'
|
||||
|
||||
# AS = CC + ' -x assembler-with-cpp'
|
||||
|
||||
# HEX = 'C:\\ARM_GCC\\bin\\arm-none-eabi-objcopy' + ' -O ihex'
|
||||
# BIN = 'C:\\ARM_GCC\\bin\\arm-none-eabi-objcopy' + ' -O binary -S'
|
||||
|
||||
CSRC = []
|
||||
|
||||
CINC = ['-Isoft']
|
||||
|
||||
CDEF = ["-DTEST"]
|
||||
|
||||
ASRC = []
|
||||
|
||||
BUILD_DIR = 'build'
|
||||
|
||||
TARGET = 'hello'
|
||||
|
||||
# CFLAG = ["-Wall -pedantic -specs=nano.specs -mcpu=cortex-m3 -mthumb -lc -lm -lnosys -Og -Tstm32_boot.ld",
|
||||
# f"-Wl,-Map={BUILD_DIR}/{TARGET}.map,--cref -Wl,--gc-sections"]
|
||||
CFLAG = ["-Wall -pedantic -g"]
|
||||
|
||||
# <20>ҵ<EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><D7BA><EFBFBD>ļ<EFBFBD>
|
||||
def find_type(path:str,fix:list[str]):
|
||||
dlist=os.listdir(path)
|
||||
file_list=[]
|
||||
for i in dlist:
|
||||
ps=os.path.join(path, i)
|
||||
if os.path.isdir(ps):
|
||||
file_list+=find_type(ps,fix)
|
||||
else:
|
||||
suf=ps.split('.')[-1]
|
||||
if(suf in fix):
|
||||
file_list.append(ps)
|
||||
return file_list
|
||||
|
||||
|
||||
|
||||
'''
|
||||
<EFBFBD><EFBFBD>.c<><63><EFBFBD><EFBFBD>Ϊ.o<>ļ<EFBFBD><C4BC><EFBFBD>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ű<EFBFBD><EFBFBD><EFBFBD>Ҫʵ<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.c<>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>±<EFBFBD><C2B1><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>.o<>ļ<EFBFBD>
|
||||
gcc -c test.c -o test.o
|
||||
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD><EFBFBD>.d<>ļ<EFBFBD>
|
||||
gcc -MM main.c -o build/main.d
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
'''
|
||||
|
||||
|
||||
def tran_path(path:str):
|
||||
p=path.replace('\\','/')
|
||||
p=p.replace('/','_')
|
||||
if(p[0]=='.'):
|
||||
return p[1:]
|
||||
else:
|
||||
return p
|
||||
|
||||
|
||||
# <20>ж<EFBFBD><D0B6>Ƿ<EFBFBD><C7B7><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
def check_rebuild(dst:str,src:list[str]):
|
||||
if(not os.path.exists(dst)):
|
||||
return True
|
||||
dst_time=os.path.getmtime(dst)
|
||||
src_time=[]
|
||||
for i in src:
|
||||
src_time.append(os.path.getmtime(i))
|
||||
src_time.sort()
|
||||
if(src_time[-1]>dst_time):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
|
||||
# <20><>ȡ.d<>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC>б<EFBFBD>
|
||||
def read_depend_files(name:str):
|
||||
with open(name) as f:
|
||||
t=f.readline()
|
||||
t=t.split(':')[-1].strip()
|
||||
t=t.split(' ')
|
||||
# print(f"<22><><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD>{t}")
|
||||
return t
|
||||
|
||||
|
||||
# <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ
|
||||
def build_depend(src:list[str]):
|
||||
flags=f"{' '.join(CINC)} {' '.join(CDEF)} {' '.join(CFLAG)}"
|
||||
for i in src:
|
||||
name=tran_path(i).split('.')[0]
|
||||
dst='.'.join([name,'d'])
|
||||
dst=os.path.join(BUILD_DIR,dst)
|
||||
if(check_rebuild(dst,[i])):
|
||||
cmd=f"{CC} -MM {i} -o {dst} {flags}"
|
||||
print(cmd)
|
||||
ret=os.system(cmd)
|
||||
if(ret):
|
||||
exit()
|
||||
|
||||
|
||||
# <20><><EFBFBD><EFBFBD><EFBFBD>м<EFBFBD><D0BC>ļ<EFBFBD>
|
||||
def build_object(src:list[str]):
|
||||
flags=f"{' '.join(CINC)} {' '.join(CDEF)} {' '.join(CFLAG)}"
|
||||
for i in src:
|
||||
name_l=tran_path(i).split('.')
|
||||
name=name_l[0]
|
||||
file_type=name_l[-1]
|
||||
dst='.'.join([name,'o'])
|
||||
dst=os.path.join(BUILD_DIR,dst)
|
||||
cd='.'.join([name,'d'])
|
||||
cmd = ''
|
||||
if(file_type in ['c','.C']):
|
||||
cd=os.path.join(BUILD_DIR,cd)
|
||||
if(check_rebuild(dst,read_depend_files(cd))):
|
||||
cmd=f"{CC} -c {i} -o {dst} {flags}"
|
||||
elif(file_type in ['s','S','asm','ASM']):
|
||||
if(check_rebuild(dst,[i])):
|
||||
cmd=f"{AS} -c {i} -o {dst} {flags}"
|
||||
if(len(cmd)>0):
|
||||
print(cmd)
|
||||
ret=os.system(cmd)
|
||||
if(ret):
|
||||
exit()
|
||||
|
||||
|
||||
# <20><><EFBFBD>ɿ<EFBFBD>ִ<EFBFBD><D6B4><EFBFBD>ļ<EFBFBD>
|
||||
def build_target(src:list[str]):
|
||||
flags=f"{' '.join(CINC)} {' '.join(CDEF)} {' '.join(CFLAG)}"
|
||||
obj_list=[]
|
||||
for i in src:
|
||||
name=tran_path(i).split('.')[0]
|
||||
obj_list.append(BUILD_DIR+'/'+'.'.join([name,'o']))
|
||||
dst=os.path.join(BUILD_DIR,TARGET)
|
||||
if(check_rebuild(dst,obj_list)):
|
||||
cmd=f"{CC} {' '.join(obj_list)} -o {dst} {flags}"
|
||||
print(cmd)
|
||||
ret=os.system(cmd)
|
||||
if(ret):
|
||||
exit()
|
||||
else:
|
||||
print("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>£<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɵ<EFBFBD>Ŀ<EFBFBD><EFBFBD>")
|
||||
|
||||
|
||||
def main():
|
||||
global CSRC
|
||||
global ASRC
|
||||
CSRC+=find_type('./',['c','C'])
|
||||
# ASRC+=find_type('./',['s','S','asm','ASM'])
|
||||
|
||||
if(not os.path.exists(BUILD_DIR)):
|
||||
os.makedirs(BUILD_DIR)
|
||||
|
||||
print("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ")
|
||||
build_depend(CSRC)
|
||||
print("<EFBFBD><EFBFBD><EFBFBD>ɶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>")
|
||||
build_object(CSRC)
|
||||
build_object(ASRC)
|
||||
print("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>")
|
||||
build_target(CSRC+ASRC)
|
||||
# os.system(f"{HEX} {BUILD_DIR}/{TARGET} {BUILD_DIR}/{TARGET}.hex")
|
||||
# os.system(f"{BIN} {BUILD_DIR}/{TARGET} {BUILD_DIR}/{TARGET}.bin")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
|
||||
|
97
soft/exception.c
Normal file
97
soft/exception.c
Normal file
@@ -0,0 +1,97 @@
|
||||
|
||||
|
||||
#include "setjmp.h"
|
||||
#include "stdio.h"
|
||||
#include "stdlib.h"
|
||||
#include "unistd.h"
|
||||
#include "string.h"
|
||||
#include "stdarg.h"
|
||||
#include "exception.h"
|
||||
#include "mystdlib.h"
|
||||
|
||||
|
||||
|
||||
exception_def *exception(){
|
||||
static exception_def frame={0};
|
||||
return &frame;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void __throw(char *file,int line,const char *fmt,...){
|
||||
exception_def *f=exception();
|
||||
jmp_fram *h=f->jmp_head;
|
||||
char *buff=0;
|
||||
int length=0;
|
||||
va_list args;
|
||||
f->file=file;
|
||||
f->line=line;
|
||||
buff=f->log;
|
||||
va_start(args, fmt);
|
||||
length += vsnprintf(buff + length, THROW_LOG__MAX_SIZE - length - 1, fmt, args);
|
||||
va_end(args);
|
||||
longjmp((h->fram),1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
char *err_(){
|
||||
exception_def *f=exception();
|
||||
return f->log;
|
||||
}
|
||||
char *file_(){
|
||||
exception_def *f=exception();
|
||||
return f->file;
|
||||
}
|
||||
int line_(){
|
||||
exception_def *f=exception();
|
||||
return f->line;
|
||||
}
|
||||
void func_two();
|
||||
|
||||
int test_add(int a, int b)
|
||||
{
|
||||
printf("setjmp test.\n");
|
||||
try_{
|
||||
printf("first enter setjmp.\n");
|
||||
|
||||
try_{
|
||||
printf("try in try.\n");
|
||||
func_two();
|
||||
// throw_("throw two err.");
|
||||
}catch_{
|
||||
printf("file=%s,line=%d,err=%s.\n",file_(),line_(),err_());
|
||||
}
|
||||
throw_("throw a err.");
|
||||
|
||||
}catch_{
|
||||
printf("sssss\n");
|
||||
printf("file=%s,line=%d,err=%s.\n",file_(),line_(),err_());
|
||||
try_{
|
||||
printf("try in catch.\n");
|
||||
func_two();
|
||||
// throw_("throw two err.");
|
||||
}catch_{
|
||||
printf("file=%s,line=%d,err=%s.\n",file_(),line_(),err_());
|
||||
}
|
||||
}
|
||||
printf("setjmp end.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void func_two(){
|
||||
printf("in func:%s\n",__func__);
|
||||
void *p=mem_malloc(512);
|
||||
throw_("throw in func_two. in func:%s",__func__);
|
||||
mem_free(p);
|
||||
}
|
||||
|
||||
|
||||
|
104
soft/exception.h
Normal file
104
soft/exception.h
Normal file
@@ -0,0 +1,104 @@
|
||||
|
||||
|
||||
#ifndef exception_h__
|
||||
#define exception_h__
|
||||
|
||||
#include "setjmp.h"
|
||||
#include "mystdlib.h"
|
||||
|
||||
#define THROW_LOG__MAX_SIZE 1024
|
||||
|
||||
|
||||
typedef struct _jmp_fram{
|
||||
struct _jmp_fram *next;
|
||||
struct _jmp_fram *last;
|
||||
map_def *mem;
|
||||
jmp_buf fram;
|
||||
}jmp_fram;
|
||||
|
||||
|
||||
typedef struct{
|
||||
size_t jmp_num;
|
||||
jmp_fram *jmp_head;
|
||||
int ret;
|
||||
char *file;
|
||||
int line;
|
||||
char log[THROW_LOG__MAX_SIZE];
|
||||
}exception_def;
|
||||
|
||||
|
||||
|
||||
#define jmp_next(j) {\
|
||||
if((*j)){\
|
||||
(*j)->next=calloc(sizeof(jmp_fram),1);\
|
||||
(*j)->next->last=(*j);\
|
||||
(*j)=(*j)->next;\
|
||||
}else{\
|
||||
(*j)=calloc(sizeof(jmp_fram),1);\
|
||||
}\
|
||||
}
|
||||
|
||||
#define jmp_last(j) {\
|
||||
if((*j)){\
|
||||
jmp_fram *l=(*j)->last;\
|
||||
if(l){\
|
||||
__mem_mov(&(l)->mem,&(*j)->mem);\
|
||||
}\
|
||||
free(*j);\
|
||||
(*j)=l;\
|
||||
if(*j){\
|
||||
(*j)->next=0;\
|
||||
}\
|
||||
}\
|
||||
}
|
||||
|
||||
|
||||
#define jmp_clear(j) {\
|
||||
if((*j)){\
|
||||
jmp_fram *l=(*j)->last;\
|
||||
__mem_clear(&(*j)->mem);\
|
||||
free(*j);\
|
||||
(*j)=l;\
|
||||
if(*j){\
|
||||
(*j)->next=0;\
|
||||
}\
|
||||
}\
|
||||
}
|
||||
|
||||
|
||||
#define __try(){\
|
||||
exception_def *f=exception();\
|
||||
jmp_fram **h=&f->jmp_head;\
|
||||
int ret;\
|
||||
jmp_next(h);\
|
||||
ret= setjmp(((*h)->fram));\
|
||||
if(ret){\
|
||||
jmp_clear(h);\
|
||||
}\
|
||||
f->ret=ret;\
|
||||
}
|
||||
|
||||
#define try_ __try();if(exception()->ret==0){
|
||||
#define catch_ {\
|
||||
exception_def *f=exception();\
|
||||
jmp_fram **h=&f->jmp_head;\
|
||||
jmp_last(h);\
|
||||
}}else
|
||||
|
||||
#define throw_(fmt,...) __throw(__FILE__,__LINE__,fmt,##__VA_ARGS__)
|
||||
|
||||
exception_def *exception();
|
||||
void __throw(char *file,int line,const char *fmt,...);
|
||||
|
||||
|
||||
|
||||
|
||||
int test_add(int a,int b);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
107
soft/mystdlib.c
Normal file
107
soft/mystdlib.c
Normal file
@@ -0,0 +1,107 @@
|
||||
|
||||
#include "mystdlib.h"
|
||||
#include "string.h"
|
||||
#include "exception.h"
|
||||
#include "stdio.h"
|
||||
|
||||
|
||||
static void __mem_append_m(map_def **m,void *p);
|
||||
|
||||
|
||||
void __mem_clear(map_def **m){
|
||||
if(!(*m)){
|
||||
return;
|
||||
}
|
||||
size_t *map=(*m)->mem_map;
|
||||
size_t size=(*m)->map_size;
|
||||
for(size_t i=0;i<size;i++){
|
||||
if(map[i]){
|
||||
free((void *)map[i]);
|
||||
printf("clear eme_p=%08lx\n",map[i]);
|
||||
}
|
||||
}
|
||||
free(*m);
|
||||
*m=0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void __mem_mov(map_def **d,map_def **s){
|
||||
if(!(*s)){
|
||||
return;
|
||||
}
|
||||
size_t *map=(*s)->mem_map;
|
||||
for(size_t i=0;i<(*s)->map_size;i++){
|
||||
if(map[i]){
|
||||
__mem_append_m(d,(void *)map[i]);
|
||||
}
|
||||
}
|
||||
free(*s);
|
||||
(*s)=0;
|
||||
printf("mem mov end.\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void mem_free(void *p){
|
||||
exception_def *th=exception();
|
||||
map_def **m=&th->jmp_head->mem;
|
||||
if(*m){
|
||||
for(size_t i=0;i<(*m)->map_size;i++){
|
||||
if((*m)->mem_map[i]==(size_t)p){
|
||||
(*m)->mem_map[i]=0;
|
||||
printf("free eme_p=%08lx\n",(size_t)p);
|
||||
(*m)->mam_used--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(p);
|
||||
}
|
||||
|
||||
static void __mem_append_m(map_def **m,void *p){
|
||||
if(!(*m)){
|
||||
(*m)=calloc(sizeof(map_def)+MAP_SIZE_STEP*sizeof(size_t),1);
|
||||
(*m)->map_size=MAP_SIZE_STEP;
|
||||
}
|
||||
if((*m)->mam_used>=(*m)->map_size){
|
||||
map_def *mt=*m;
|
||||
*m=calloc(sizeof(map_def)+((*m)->map_size+ MAP_SIZE_STEP)*sizeof(size_t),1);
|
||||
(*m)->mam_used=mt->mam_used;
|
||||
(*m)->map_size=mt->map_size+MAP_SIZE_STEP;
|
||||
memcpy((*m)->mem_map,mt->mem_map,mt->map_size*sizeof(size_t));
|
||||
free(mt);
|
||||
}
|
||||
if((*m)->mam_used<(*m)->map_size){
|
||||
for(size_t i=0;i<(*m)->map_size;i++){
|
||||
if((*m)->mem_map[i]==0){
|
||||
(*m)->mem_map[i]=(size_t)p;
|
||||
printf("append eme_p=%08lx\n",(size_t)p);
|
||||
(*m)->mam_used++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void __mem_append(void *p){
|
||||
exception_def *th=exception();
|
||||
map_def **m=&th->jmp_head->mem;
|
||||
__mem_append_m(m,p);
|
||||
}
|
||||
|
||||
void *mem_malloc(size_t size){
|
||||
void *p=malloc(size);
|
||||
__mem_append(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
void *mem_calloc(size_t memb_size,size_t memb_num){
|
||||
void *p=calloc(memb_size,memb_num);
|
||||
__mem_append(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
|
28
soft/mystdlib.h
Normal file
28
soft/mystdlib.h
Normal file
@@ -0,0 +1,28 @@
|
||||
|
||||
|
||||
#ifndef mystdlib_h__
|
||||
#define mystdlib_h__
|
||||
|
||||
#include "stdint.h"
|
||||
#include "stdlib.h"
|
||||
|
||||
|
||||
#define MAP_SIZE_STEP 50
|
||||
|
||||
|
||||
|
||||
typedef struct _map_def{
|
||||
size_t map_size;
|
||||
size_t mam_used;
|
||||
size_t mem_map[0];
|
||||
}map_def;
|
||||
|
||||
|
||||
void __mem_clear(map_def **m);
|
||||
void __mem_mov(map_def **d,map_def **s);
|
||||
|
||||
void *mem_calloc(size_t memb_size,size_t memb_num);
|
||||
void *mem_malloc(size_t size);
|
||||
void mem_free(void *p);
|
||||
|
||||
#endif
|
87
soft/mythread.c
Normal file
87
soft/mythread.c
Normal file
@@ -0,0 +1,87 @@
|
||||
|
||||
|
||||
#include "pthread.h"
|
||||
#include "unistd.h"
|
||||
#include "mythread.h"
|
||||
#include "exception.h"
|
||||
#include "stdio.h"
|
||||
|
||||
|
||||
typedef struct _myth_def{
|
||||
struct _myth_def *next;
|
||||
struct _myth_def *last;
|
||||
pthread_t th;
|
||||
exception_def except;
|
||||
size_t id;
|
||||
int (*func)(void *);
|
||||
void *arg;
|
||||
}myth_def;
|
||||
|
||||
typedef struct{
|
||||
myth_def *head;
|
||||
|
||||
}self_def;
|
||||
static self_def g_self;
|
||||
|
||||
|
||||
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
|
||||
void *(*start_routine) (void *), void *arg);
|
||||
|
||||
|
||||
|
||||
static void *p_thread(void *t){
|
||||
myth_def *th=(myth_def *)t;
|
||||
th->id=(size_t)pthread_self();
|
||||
printf("func:%08lx start id=%d.\n",(size_t)th->func,th->id);
|
||||
try_{
|
||||
if(!th->func){
|
||||
throw_("th->func was null.");
|
||||
}
|
||||
th->func(th->arg);
|
||||
}catch_{
|
||||
printf("func:%08lx failed.\n",(size_t)th->func);
|
||||
printf("file=%s,line=%d,err=%s\n",exception()->file,exception()->line,exception()->log);
|
||||
}
|
||||
printf("func:%08lx end.\n",(size_t)th->func);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int myth_create(int (*func)(void *t),void *t){
|
||||
myth_def *m=calloc(sizeof(myth_def),1);
|
||||
m->func=func;
|
||||
m->arg=t;
|
||||
pthread_create(&m->th,NULL,p_thread,m);
|
||||
{
|
||||
self_def *s=&g_self;
|
||||
if(s->head==NULL){
|
||||
s->head=m;
|
||||
}else{
|
||||
myth_def *myth=s->head;
|
||||
while(myth->next){
|
||||
myth=myth->next;
|
||||
}
|
||||
myth->next=m;
|
||||
m->last=myth;
|
||||
}
|
||||
}
|
||||
return m->id;
|
||||
}
|
||||
|
||||
|
||||
int myth_join(){
|
||||
self_def *s=&g_self;
|
||||
myth_def *myth=s->head;
|
||||
myth_def *old;
|
||||
while(myth){
|
||||
pthread_join(myth->th,NULL);
|
||||
old=myth;
|
||||
myth=myth->next;
|
||||
free(old);
|
||||
}
|
||||
s->head=NULL;
|
||||
return 0;
|
||||
}
|
||||
|
12
soft/mythread.h
Normal file
12
soft/mythread.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef mythread_h__
|
||||
#define mythread_h__
|
||||
|
||||
|
||||
#include "pthread.h"
|
||||
|
||||
int myth_create(int (*func)(void *t),void *t);
|
||||
int myth_join();
|
||||
|
||||
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user