diff src/gearsTools/generate_context.pl @ 44:94ca6db2ee9c

add perl script
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sat, 02 Mar 2019 21:05:26 +0900
parents
children 9647d79fe97e
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gearsTools/generate_context.pl	Sat Mar 02 21:05:26 2019 +0900
@@ -0,0 +1,225 @@
+#!/usr/bin/perl
+
+use Getopt::Std;
+use strict;
+
+# 
+# generrate Gears OS context heaader and initializer from CbC sources
+#
+# CodeGear
+# 
+# get stub information from # *.c
+#     __code taskManager_stub(struct Context* context) {
+# 
+# generate CodeGear indexn in context.h
+#     C_taskManager,
+# 
+# generate CodeGear stub reference in context.h
+#     extern __code taskManager_stub(struct Context*);
+# 
+# generate CodeGear stub reference in $name-context.h for each module
+#     context->code[C_taskManager]   = taskManager_stub;
+# 
+# DataGear
+# 
+# get DataGear information from context.h
+#     struct Worker {
+#         int id;
+#         struct Context* contexts;
+#         enum Code execute;
+#         enum Code taskSend;
+#         enum Code taskRecive;
+#         enum Code shutdown;
+#         struct Queue* tasks;
+#     } Worker;
+# 
+# generate typedefs and DataGear index in context.h
+#     typedef struct Worker Worker;
+#     D_Worker,
+# 
+# generate DataGear allocator in context.h
+#      ALLOC_DATA(context, Worker);
+#
+
+my $ddir = "c";
+
+our($opt_o,$opt_d,$opt_h);
+getopts('o:d:h');
+
+my $name = $opt_o?$opt_o:"gears";
+
+if ($opt_d) {
+    $ddir = $opt_d;
+}
+
+if ( ! -d $ddir) {
+    mkdir $ddir;
+}
+
+if ($opt_h) {
+    print "$0  [-d distdir] [-h]\n";
+    exit;
+}
+
+my %codeGear;
+my %dataGear;
+my %constructor;
+
+# gather module Information for code table initialization
+for (@ARGV) {
+    next if (/context.c/);
+    &getStubInfo($_);
+}
+
+my (%mCodeGear) = (%codeGear);
+
+# anyway we gather all Gears Information
+while (<*.c test/*.c>) {
+    next if (/context.c/);
+    &getStubInfo($_);
+}
+
+&generateContext();
+
+sub getStubInfo {
+    my ($filename) = @_;
+    open my $fd,"<",$filename or die("can't open $filename $!");
+    while (<$fd>) {
+        if (/^__code (\w+)_stub\(struct  *Context *\* *context\)/) {
+            $codeGear{$1} = $filename;
+        } elsif (/^(\w+)(\*)+  *create(\w+)\(([^]]*)\)/) {
+            my $interface = $1;
+            my $implementation = $3;
+            my $constructorArgs = $4;
+            $constructor{$implementation} = [$interface, $constructorArgs];
+        }
+    }
+
+    open my $cx,"<","context.h" or die("can't open context.h $!");
+    my $inUnionData = 0;
+    while (<$cx>) {
+        if (! $inUnionData) {
+            if ( /^union Data/) {
+                $inUnionData = 1;
+            }
+            next;
+        }
+        last if (/union Data end/);
+        if (/struct (\w+) \{/) {
+            $dataGear{$1} = 'struct';
+        } elsif (/^\s{4}(\w+) (\w+);/) { # primitive type
+            $dataGear{$1} = 'primitive';
+        }
+        $dataGear{"Context"} = "struct";
+    }
+}
+
+sub generateContext {
+    $codeGear{"start_code"} = "$ddir/$name-context.c";
+    $codeGear{"exit_code"} = "$ddir/$name-context.c";
+    $mCodeGear{"start_code"} = "$ddir/$name-context.c";
+    $mCodeGear{"exit_code"} = "$ddir/$name-context.c";
+    open my $fd,">","$ddir/extern.h" or die("can't open $ddir/extern.h $!");
+    for my $code ( sort keys %codeGear ) {
+        print $fd "extern __code ${code}_stub(struct Context*);\n";
+    }
+    for my $impl ( sort keys %constructor ) {
+        my ($interface, $constructorArgs) = @{$constructor{$impl}};
+        print $fd "extern ${interface}* create${impl}($constructorArgs);\n";
+    }
+    print $fd "\n";
+
+    open my $fd,">","$ddir/enumCode.h" or die("can't open $ddir/enumCode.h $!");
+    print $fd "enum Code {\n";
+    for my $code ( sort keys %codeGear ) {
+        print $fd "    C_${code},\n";
+    }
+    print $fd "};\n";
+   
+    my $code_init = ''; 
+    for my $code ( sort keys %mCodeGear ) {
+        $code_init .=  "    context->code[C_${code}]    = ${code}_stub;\n";
+    }
+
+    my $data_num = keys(%dataGear);
+    $data_num++;
+my $context_c = << "EOFEOF";
+#include <stdlib.h>
+
+#include "../context.h"
+
+void initContext(struct Context* context) {
+    context->heapLimit = sizeof(union Data)*ALLOCATE_SIZE;
+    context->code = (__code(**) (struct Context*)) NEWN(ALLOCATE_SIZE, void*);
+    context->data = NEWN(ALLOCATE_SIZE, union Data*);
+    context->heapStart = NEWN(context->heapLimit, char);
+    context->heap = context->heapStart;
+    // context->codeNum = Exit;
+
+$code_init
+
+#include "dataGearInit.c"
+    context->dataNum = $data_num;
+}
+EOFEOF
+
+    open my $fd,">","$ddir/$name-context.c" or die("can't open $ddir/$name-context.c $!");
+    print $fd $context_c;
+
+my $meta_call = <<"EOFEOF";
+__code meta(struct Context* context, enum Code next) {
+    // printf("meta %d\\n",next);
+    if (context->task == NULL) {
+      goto (context->code[next])(context);
+    }
+    context->task     = NULL;
+    context->taskList = NULL;
+    goto (context->code[Gearef(context, TaskManager)->taskManager->TaskManager.spawnTasks])(context);
+}
+
+__code start_code(struct Context* context) {
+    goto meta(context, context->next);
+}
+
+__code start_code_stub(struct Context* context) {
+    goto start_code(context);
+}
+
+__code exit_code(struct Context* context) {
+    free(context->code);
+    free(context->data);
+    free(context->heapStart);
+    goto exit(0);
+}
+
+__code exit_code_stub(struct Context* context) {
+    goto exit_code(context);
+}    
+
+// end context_c
+EOFEOF
+
+print $fd $meta_call;
+
+open my $fd,">","$ddir/enumData.h" or die("can't open $ddir/enumData.h $!");
+print $fd "enum DataType {\n";
+print $fd "    D_Code,\n";
+for my $data ( sort keys %dataGear ) {
+    print $fd "    D_${data},\n";
+}
+print $fd "};\n\n";
+
+open my $fd,">","$ddir/typedefData.h" or die("can't open $ddir/typedefData.h $!");
+for my $data ( sort keys %dataGear ) {
+    if ($dataGear{$data} eq 'struct') {
+        print $fd "typedef struct ${data} ${data};\n";
+    }
+}
+
+open my $fd,">","$ddir/dataGearInit.c" or die("can't open $ddir/dataGearInit.c $!");
+for my $data ( sort keys %dataGear ) {
+    print $fd "    ALLOC_DATA(context, ${data});\n";
+}
+}
+
+# end