Mercurial > hg > Papers > 2012 > aplas
changeset 33:bbbda7a58067
mm
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 15 Jun 2012 22:04:31 +0900 |
parents | 22dbcdbcae5f (current diff) d0dada806f0a (diff) |
children | 7294b17518c6 |
files | paper/rectype.ind |
diffstat | 9 files changed, 462 insertions(+), 81 deletions(-) [+] |
line wrap: on
line diff
--- a/paper/Makefile Thu Jun 14 21:11:54 2012 +0900 +++ b/paper/Makefile Fri Jun 15 22:04:31 2012 +0900 @@ -1,6 +1,6 @@ -DEPENDENCY = rectype.ind +DEPENDENCY = rectype.ind figure/code.pdf figure/tree1.pdf figure/tree2.pdf -DEPENDOHP = ohp.tex +DEPENDOHP = ohp.tex figure/code.pdf figure/tree1.pdf figure/tree2.pdf PAPER = rectype.ind
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/paper/main.tex Fri Jun 15 22:04:31 2012 +0900 @@ -0,0 +1,36 @@ +\documentclass[envcountsame]{llncs} +\usepackage[dvipdfmx]{graphicx} +\usepackage{llncsdoc} +\usepackage{url} +\usepackage{listings} + + +\bibliographystyle{plain} % for bibliography +%\title{The implementation of recursive type syntax on GCC-4.6 for CbC} +\title{Recursive type syntax in Continuation based C} +\titlerunning{title running} +\toctitle{toc title} +%\subtitle{sub title} +\author{Shinji Kono\inst{1} Nobuyasu Oshiro\inst{2}} +\authorrunning{authorrunning} +\institute{University of the Ryukyus} +\email{} + +\begin{document} +\maketitle +\newcommand\rectype{{\tt \_\_rectype}} +\newcommand\code{{\tt \_\_code}} +\newcommand\treelist{{\tt TREE\_LIST}} +\newcommand\pointertype{{\tt POINTER\_TYPE}} +\newcommand\functiontype{{\tt FUNCTION\_TYPE}} + +\begin{abstract} +\input{abstract} +\end{abstract} + +%\pagenumbering{arabic} + +\input{0} % sections + +\bibliography{ref} +\end{document}
--- a/paper/o2tex Thu Jun 14 21:11:54 2012 +0900 +++ b/paper/o2tex Fri Jun 15 22:04:31 2012 +0900 @@ -131,7 +131,7 @@ close fh; -$[ = 1; # set array base to 1 +#$[ = 1; # set array base to 1 $FS = ' '; # set field separator $, = ' '; # set output field separator $\ = "\n"; # set output record separator @@ -338,12 +338,12 @@ &Pick('>>', $file); # center environment disturbes caption counter and label reference $line = <<"EOF"; -\begin{figure}[htb] -\begin{center} -\includegraphics[width=6cm]{${fig}} -${caption}\end{center} +\\begin{figure}[htb] +\\begin{center} +\\includegraphics[width=6cm]{${fig}} +${caption}\\end{center} \\label{${alt}} -\end{figure} +\\end{figure} EOF # print $fh "(fig.\\ref{$alt})\n"; print $fh $line; @@ -368,12 +368,12 @@ } &Pick('>>', $file); $line = <<"EOF"; -\begin{figure}[htb] -\begin{center} -\includegraphics[width=6cm]{${fig}} -${caption}\end{center} +\\begin{figure}[htb] +\\begin{center} +\\includegraphics[width=6cm]{${fig}} +${caption}\\end{center} \\label{${alt}} -\end{figure} +\\end{figure} EOF # print $fh "(fig.\\ref{$alt})\n"; print $fh $line; @@ -386,7 +386,8 @@ } next line; } elsif (/\\epsfile\{.*file=([^{},]+)/ || - /\\input(.*)/ || /\\include(.*)/) { + /\\includegraphics\{([^{},]+)\}/ || + /\\input (.*)/ || /\\include (.*)/) { $fig = $1; &Pick('>>', $file) && (print $fh $_);
--- a/paper/rectype.ind Thu Jun 14 21:11:54 2012 +0900 +++ b/paper/rectype.ind Fri Jun 15 22:04:31 2012 +0900 @@ -1,6 +1,5 @@ -title: Recursive type syntax in Continuation based C -\newcommand{\rectype}{{\tt \_\_rectype}} --author: Nobuyasu Oshiro, Shinji KONO @@ -23,7 +22,7 @@ --Continuation based C -CbC's basic programming unit is a code segment. It is not a subroutine, but it +CbC's basic programming unit is a Code Segment. It is not a subroutine, but it looks like a function, because it has input and output. We can use C struct as input and output interfaces. @@ -35,31 +34,23 @@ goto g(b); } -In this example, a code segment -\verb+f+ has \verb+input a+ and sends \verb+output b+ to a code segment \verb+g+. -There is no return from code segment \verb+b+, \verb+b+ should call another +In this example, a Code Segment +\verb+f+ has \verb+input a+ and sends \verb+output b+ to a Code Segment \verb+g+. +There is no return from Code Segment \verb+b+, \verb+b+ should call another continuation using \verb+goto+. Any control structure in C is allowed in CwC language, but in case of CbC, we restrict ourselves to use \verb+if+ statement only, because it is sufficient to implement C to CbC translation. In this case, -code segment has one input interface and several output interfaces (fig.\ref{code}). +Code Segment has one input interface and several output interfaces (fig.\ref{code}). -\includegraphics[width=6cm]{ -\begin{figure}[htb] -\begin{center} -\includegraphics[width=6cm]{figure/code.pdf} -\caption{code} -\end{center} -\label{code} -\end{figure} - +<center><img src="figure/code.pdf" alt="code"></center> \verb+__code+ and parameterized global goto statement is an extension of Continuation based C. Unlike \verb+C--+ \cite{cminusminus}'s parameterized goto, we cannot goto into normal C function. -In CwC, we can go to a code segment from a C function and we can call C functions -in a code segment. So we don't have to shift completely from C to CbC. The later +In CwC, we can go to a Code Segment from a C function and we can call C functions +in a Code Segment. So we don't have to shift completely from C to CbC. The later one is straight forward, but the former one needs further extensions. void *env; @@ -79,18 +70,89 @@ In this hello world example, the environment of \verb+main()+ and its continuation is kept in global variables. The environment and the continuation can be get using \verb+__environment+, -and \verb+__return+. Arbitrary mixture of code segments and functions +and \verb+__return+. Arbitrary mixture of Code Segments and functions are allowed (in CwC). The continuation of \verb+goto+ statement never returns to original function, but it goes to caller of original function. In this case, it returns result 0 to the operating system. ---recursive type syntax +CbC is a kind of high level assembler language. It can do several +original C language cannot do. For examples, + + Thread Scheduler + Context Switch + Synchronization Primitives + I/O wait semantics + + +are impossible to write in C. Usually it requires some help of +assembler language such as \verb+__asm+ statement extension which is +of course not portable. + +--Scheduler example + +We can easily write these things in CbC, because +CbC has no hidden information behind the stack frame of C. +A thread simply go to the scheduler, + + goto scheduler(self, task_list); + + +and the scheduler simply pass the control to the next +thread in the task queue. + + code scheduler(Thread self,TaskPtr list) + { + TaskPtr t = list; + TaskPtr e; + list = list->next; + goto list->thread->next(list->thread,list); + } + +Of course it is a simulator, but it is an implementation +also. If we have a CPU resource API, we can write real multi +CPU scheduler in CbC. -We implemented \rectype syntax in CbC on GCC. +This is impossible in C, because we cannot access the hidden +stack which is necessary to switch in the scheduler. In CbC, +everything is visible, so we can switch threads very easily. + +This means we can use CbC as an executable specification +language of OS API. + + +--Recursive type syntax + +CbC's program pass next pointer of Code Segment on argument. +It is passed as follows. + + __code csA( __code (*p)() ) { + goto p(csB); + } + +p is next pointer of Code Segment. +But, This declaration is not right. +Because p have arguments. +We wanted to the same type of p's arguments as type of csA's arguments. +Right declaration is as follows. + + __code csA( __code (*p)( __code (*)( __code (*)( __code *)))) { + goto p(csB); + } + +The syntax of C Must be declared recursively. +The following declaration if it may be that the type checking of p. + + __code csA( __code (*p)( __code(*)())) { + goto p(csB); + } + +However this declaration is to require long typing. +Therefore we implemented \rectype syntax in CbC on GCC. + \rectype syntax is declare a recursive type. -This example is using \rectype in CbC. +This example is using \rectype syntax. __code csA( __rectype *p) { goto p(csB); @@ -99,24 +161,9 @@ *p represent pointer of csA at \ref{code:rectype} . p's argument type is same csA that function pointer. -Recursive type Can not declarated in C. -Because -It is the same as the following. - - void csA( void (*p)(void*)) { - p(csB); - } - - - - __code csA( __code (*p)( __code (*)( __code (*)( __code )))) { - goto p(csB); - } - - --Recursive type syntax struct interface { @@ -139,51 +186,172 @@ __code fibonacci(__rectype *p, int num, int count, int result, int prev) ---GCC implementation + + +--How to implement \rectype +\rectype syntax is implemented overriding AST. +First, \rectype syntax make Tree same \code(\ref{fig:tree1}). +Second, tree was created to be rectype flag. +Third, to override AST(\ref{fig:tree2}). \begin{figure}[htpb] - \begin{minipage}{0.5\hsize} - \begin{center} +\begin{minipage}{0.5\hsize} +\begin{center} \scalebox{0.35}{\includegraphics{figure/tree1.pdf}} - \end{center} - \caption{} - \label{fig:tree1} - \end{minipage} - \begin{minipage}{0.2\hsize} - \begin{center} +\end{center} +\caption{AST of function pointer} +\label{fig:tree1} +\end{minipage} +\begin{minipage}{0.2\hsize} +\begin{center} \scalebox{0.35}{\includegraphics{figure/tree2.pdf}} - \end{center} - \caption{\rectype} - \label{fig:tree2} +\end{center} +\caption{AST of \rectype} +\label{fig:tree2} \end{minipage} \end{figure} +This AST(\ref{fig:tree2}) is made by syntax of \verb+__code csA(__rectype *p)+ . +\treelist have infomation of argument. +First \treelist represent that argument is function pointer(\verb+__code (*p)()+) . +Second \treelist represent that csA is Fixed-length argument. +First \treelist is connected with \pointertype. +\pointertype have pointer of function(\functiontype). +We have to override it in the pointer of csA. + + + + +--Problems with implementation of \rectype. + +Segmentation fault has occurred in the following program on compile. + + __code csA(__rectype *p) { + goto p(3); + } + +The above code is the wrong argument of p. +The p's argument is converted by GCC. +3 of type int is converted to a pionter type of Code Segment. +At this time, GCC looks at the type of the argument. +p's argument is pointer of csA. +csA's argument is p. +GCC is also an infinite recursion happens to see the type of tye argument of the argument. + +We Solve this problem that does not check the arguments if the \rectype flag is true. +The following program become part was fixed gcc/c-family/c-pretty-print.c. + + static void + pp_c_abstract_declarator (c_pretty_printer *pp, tree t) + { + if (TREE_CODE (t) == POINTER_TYPE) + { + if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE + || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE) + pp_c_right_paren (pp); + #ifndef noCbC + if (IS_RECTYPE(t)) return; + #endif + t = TREE_TYPE (t); + } + pp_direct_abstract_declarator (pp, t); + } + + +Variable t have information of p's argument. +If t is \pointertype, t is assigned type of \pointertype(\verb+t = TREE_TYPE (t);+). +We have added code \verb+if (IS_RECTYPE(t)) return;+ +Thereby we have solved type checking and infinite recursion problem. + + -\begin{table}[htpb] -\centering -\small -\begin{tabular}{|l|r|r|r|} \hline -(unit: s) & ./conv1 1 & ./conv1 2 & ./conv1 3 \\ \hline -Micro-C(32bit) & 9.93 & 6.31 & 7.18 \\ \hline -Micro-C(64bit) & 5.03 & 5.12 & 5.00 \\ \hline \hline -GCC -O3(32bit) & 2.52 & 2.34 & 1.53 \\ \hline -GCC -O3(64bit) & 1.80 & 1.20 & 1.44 \\ \hline -\end{tabular} -\caption{Micro-C, GCC bench mark (in sec)} -\label{tab:mc,gcc,compare} -\end{table} +--Method other than \rectype + +The recursively program of C's syntax can be solved using struct syntax. +For example, if we write + + struct interface { + __code (*next)(struct interface); + }; + + __code csA(struct interface p) { + struct interface ds; + ds.next = csB; + goto p.next(ds); + } + + int main() { + struct interface ds; + ds = print; + goto csA(ds); + return 0; + } + +there is no need to write recursively. +Because the struct syntax wrapped in a function pointer. +Code Segment does not receive function pointer in arguments. +Recursively program does not occur. - ---Data Segment +--Comparison ---Data Segment vs recursive type - +Here is CbC program that finds the Fibonacci sequence. ---Experience in CbC + __code print(__rectype *p, long int num, + long int count, long int result, long int prev) { + printf("fibonacci(%d) = %ld\n",num,result); + goto cs_while(print, num, count, result, prev); + } + + __code fibonacci(__rectype *p, long int num, + long int count, long int result, long int prev) { + if (count == 0) { + result += 0; + count++; + } else if (count == 1) { + result += 1; + count++; + } else if (count > 1){ + long int tmp = prev; + prev = result; + result = result + tmp; + count++; + } else { + printf("please enter nutural number\n"); + exit(0); + } + if (num < count) { + goto p(fibonacci, num, count, result, prev); + } + goto fibonacci(p, num, count, result, prev); + } + __code cs_while(__rectype *p, long int num, + long int count, long int result, long int prev) { + if (num > 0) { + num--; + goto fibonacci(print, num, 0, 0, 0); + } + exit(0); + } ---Future direction +It is written using \rectype syntax. +Do not use the \rectype syntax program would be the following declaration. + + __code print(__code (*p)(__code(*)(),long int,long int,long int,long int), + long int num, long int count, long int result, long int prev); + + __code fibonacci(__code (*p)(__code(*)(),long int,long int, long int,long int), + long int num, long int count, long int result, long int prev); + __code cs_while(__code (*p)(__code(*)(),long int, long int, long int, long int), + long int num, long int count, long int result, long int prev); +Comparing the program that made the declaration of each. +AST is almost the same should be created both. +Therefore, there should be no difference was the result. + +Here is the result. + +--Conclusion
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/paper/src/fibonacci2.cbc Fri Jun 15 22:04:31 2012 +0900 @@ -0,0 +1,50 @@ +#include <stdio.h> +#include <stdlib.h> +__code print(__rectype *p, long int num, long int count, long int result, long int prev) { + printf("fibonacci(%d) = %ld\n",num,result); + goto cs_while(print, num, count, result, prev); +// exit(0); +} + +__code fibonacci(__rectype *p, long int num, long int count, long int result, long int prev) { +//__code fibonacci(__code (*p)(__code(*)(__rectype),int), long int num, long int count, long int result, long int prev) { + if (count == 0) { + result += 0; + count++; + } else if (count == 1) { + result += 1; + count++; + } else if (count > 1){ + long int tmp = prev; + prev = result; + result = result + tmp; + count++; + } else { + printf("please enter nutural number\n"); + exit(0); + } + if (num < count) { + goto p(fibonacci, num, count, result, prev); + } + goto fibonacci(p, num, count, result, prev); +} + +__code cs_while(__rectype *p, long int num, long int count, long int result, long int prev) { + if (num > 0) { + num--; + goto fibonacci(print, num, 0, 0, 0); + } + exit(0); +} + + +int main(int argc, char* argv[]) { + if (argc < 2) { + printf("usage: ./fibonacci number \n"); + exit(0); + } + long int num = (long int)atoi(argv[1]); + goto fibonacci(print, num, 0, 0, 0); + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/paper/src/fibonacci2_norec.cbc Fri Jun 15 22:04:31 2012 +0900 @@ -0,0 +1,52 @@ +#include <stdio.h> +#include <stdlib.h> +//__code print(__rectype *p, long int num, long int count, long int result, long int prev) { +__code print(__code (*p)(__code(*)(),long int,long int,long int,long int), long int num, long int count, long int result, long int prev) { + printf("fibonacci(%d) = %ld\n",num,result); + goto cs_while(print, num, count, result, prev); +// exit(0); +} + +//__code fibonacci(__rectype *p, long int num, long int count, long int result, long int prev) { +__code fibonacci(__code (*p)(__code(*)(),long int,long int, long int,long int), long int num, long int count, long int result, long int prev) { + if (count == 0) { + result += 0; + count++; + } else if (count == 1) { + result += 1; + count++; + } else if (count > 1){ + long int tmp = prev; + prev = result; + result = result + tmp; + count++; + } else { + printf("please enter nutural number\n"); + exit(0); + } + if (num < count) { + goto p(fibonacci, num, count, result, prev); + } + goto fibonacci(p, num, count, result, prev); +} + +//__code cs_while(__rectype *p, long int num, long int count, long int result, long int prev) { +__code cs_while(__code (*p)(__code(*)(),long int, long int, long int, long int), long int num, long int count, long int result, long int prev) { + if (num > 0) { + num--; + goto fibonacci(print, num, 0, 0, 0); + } + exit(0); +} + + +int main(int argc, char* argv[]) { + if (argc < 2) { + printf("usage: ./fibonacci number \n"); + exit(0); + } + long int num = (long int)atoi(argv[1]); + goto fibonacci(print, num, 0, 0, 0); + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/paper/src/norectype.cbc Fri Jun 15 22:04:31 2012 +0900 @@ -0,0 +1,22 @@ +#include <stdio.h> +#include <stdlib.h> +__code print(__code (*p)(__code(*)())) +{ + printf("print\n"); + exit(0); +} +__code csA(__code (*p)(__code(*)())) +{ + goto p(csA); +} + +void main1() +{ + goto csA(print); +} + +int main() +{ + main1(); + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/paper/src/rectype.cbc Fri Jun 15 22:04:31 2012 +0900 @@ -0,0 +1,22 @@ +#include <stdio.h> +#include <stdlib.h> +__code print(__rectype *p) +{ + printf("print\n"); + exit(0); +} +__code csA(__rectype *p) +{ + goto p(csA); +} + +void main1() +{ + goto csA(print); +} + +int main() +{ + main1(); + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/paper/src/struct.cbc Fri Jun 15 22:04:31 2012 +0900 @@ -0,0 +1,30 @@ +#include <stdio.h> +#include <stdlib.h> +struct interface { + __code (*next)(struct interface); +}; + +__code print(struct interface p) +{ + printf("print\n"); + exit(0); +} +__code csA(struct interface p) +{ + struct interface ds; + ds.next = csA; + goto p.next(ds); +} + +void main1() +{ + struct interface ds; + ds.next = print; + goto csA(ds); +} + +int main() +{ + main1(); + return 0; +}