C基础——用标签实现队列使命调用,即PostgreSQL内核函数调用时ExecInterpE ...

打印 上一主题 下一主题

主题 973|帖子 973|积分 2919

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
=================================版权声明=================================
版权声明:原创文章 禁止转载 

请通过右侧公告中的“联系邮箱(wlsandwho@foxmail.com)”联系我
勿用于学术性引用。
勿用于贸易出版、贸易印刷、贸易引用以及其他贸易用途。                   
 
本文不定期修正美满。
本文链接:https://www.cnblogs.com/wlsandwho/p/18350973
羞耻墙:http://www.cnblogs.com/wlsandwho/p/4206472.html
=======================================================================
这几年在搞数据库。近来离职了,想在青岛找工作。
闲着没事,写点东西。
=======================================================================
由于工作的内容收到保密协议的影响,只能写点零散的小东西。
=======================================================================
看过PG代码的朋友都知道,PG执行函数的时候,在内核有一块奇怪的代码,函数名叫做ExecInterpExpr,文件名叫做execExprInterp.c
这个函数里面有一个EEO_SWITCH和很多EEO_CASE,然后调试起来很奇怪。
=======================================================================
实在,这个是一些奇技淫巧而已。
为避免依次调用很多功能函数、一套参数在各个函数间传递
PG让各个功能都在一个大函数里实现,通过在差别的功能块间跳转,实现雷同的结果。
=======================================================================
因此,这个现实上是goto lable的花哨用法。固然PG9时代,这块代码不是这个样子的。
=======================================================================
我这里给大家写一个好理解的简化版本。
要注意的是,获取lable地址的做法,gcc支持,MSVC不支持。
[code]  1 //gcc -g -o main demo_runlable.c -std=c99  2 #include   3   4 #define WORK_ARRAY_LEN 32  5 int gWorkIndex=0;  6 static void* gWorkArray[WORK_ARRAY_LEN]={};  7   8 #define MY_SWITCH()   9 #define MY_CASE(val) MYLABE_##val 10 #define MY_OP_FROM_OPNUM(opnum) ((void*)gDispatchTable[opnum])  11 #define MY_DISPATCH()  do{\ 12                         gWorkIndex=0;\ 13                         goto *(gWorkArray[gWorkIndex]);\ 14                     }while(0) 15 #define MY_NEXT()   do{\ 16                         gWorkIndex++;\ 17                         goto *(gWorkArray[gWorkIndex]);\ 18                     }while(0) 19  20 enum OPNUM 21 { 22     OPNUM_0=0, 23     OPNUM_1, 24     OPNUM_2, 25     OPNUM_3, 26     OPNUM_4, 27     OPNUM_5, 28     OPNUM_END 29 }; 30  31 static void** gDispatchTable=NULL; 32 static void* MyRunning(int run) 33 { 34     static void* mydispatchtable[] =  35     { 36         && MY_CASE(OPNUM_0), 37         && MY_CASE(OPNUM_1), 38         && MY_CASE(OPNUM_2) , 39         && MY_CASE(OPNUM_3), 40         && MY_CASE(OPNUM_4), 41         && MY_CASE(OPNUM_5), 42         && MY_CASE(OPNUM_END) 43     }; 44  45     if(run != 0) 46     { 47         MY_DISPATCH(); 48     } 49     else 50     { 51         return mydispatchtable; 52     } 53  54     MY_SWITCH() 55     { 56         MY_CASE(OPNUM_0) : 57         { 58             printf("0"); 59             MY_NEXT(); 60         } 61  62         MY_CASE(OPNUM_1) : 63         { 64             printf("1"); 65             MY_NEXT(); 66         } 67  68         MY_CASE(OPNUM_2) : 69         { 70             printf("2"); 71             MY_NEXT(); 72         } 73  74         MY_CASE(OPNUM_3) : 75         { 76             printf("3"); 77                MY_NEXT(); 78         } 79  80         MY_CASE(OPNUM_4) : 81         { 82             printf("4"); 83             MY_NEXT(); 84         } 85  86         MY_CASE(OPNUM_5) : 87         { 88             printf("5"); 89             MY_NEXT(); 90         } 91  92         MY_CASE(OPNUM_END) : 93         { 94             printf("\n"); 95             goto out; 96         } 97     } 98 out: 99     return NULL;100 }101 102 103 void Test1()104 {105     //init106     gDispatchTable=MyRunning(0);107 108     //reset109     for(int i=0;i
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

徐锦洪

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表