view src/parallel_execution/generate_context.pl @ 210:ba56dab79dc4

separate code init for each executable
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Tue, 27 Dec 2016 17:13:45 +0900
parents b6ffdd99e525
children 421ea91dd76c
line wrap: on
line source

#!/usr/bin/perl

use Getopt::Std;

# CodeGear
# 
# *.c
# __code taskManager_stub(struct Context* context) {
# 
# context.h
# C_taskManager,
# 
# context.c
# extern __code taskManager_stub(struct Context*);
# 
# context->code[C_taskManager]   = taskManager_stub;
# 
# DataGear
# 
# 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;
# 
# typedef struct Worker Worker;
# D_Worker,
# 
# context.c
# ALLOC_DATA(context, Worker);

system "rm -rf c";
system "mkdir c";

our($opt_o);
getopts('o:');

my $name = $opt_o;

for (@ARGV) {
    next if (/context.c/);
    &getStubInfo($_);
}

my (%mCodeGear) = (%codeGear);

while (<*.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\)/ or /^\s__code (\w+)_stub\(struct Context\* context\)/) {
            $codeGear{$1} = $filename;
        }
    }

    open my $cx,"<","context.h" or die("can't open context.h $!");
    while (<$cx>) {
        if (! $inUnionData) {
            if ( /^union Data/) {
                $inUnionData = 1;
            }
            next;
        }
        last if (/union Data end/);
        if (/struct (\w+) \{/) {
            $dataGear{$1} = $1;
        }
    }
}

sub generateContext {
    open my $fd,">","c/extern.h" or die("can't open c/extern.h $!");
    for my $code ( sort keys %codeGear ) {
        print $fd "extern __code ${code}_stub(struct Context*);\n";
    }
    print $fd "\n";

    open my $fd,">","c/enumCode.h" or die("can't open c/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 $context_c = << "EOFEOF";
#include <stdlib.h>

#include "../context.h"
#include "extern.h"

__code 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->data[D_ActiveQueue] = createSynchronizedQueue(context);
    // context->data[D_WaitQueue]   = createSynchronizedQueue(context);

    context->dataNum = D_Queue;
}
EOFEOF

    open my $fd,">","c/$name-context.c" or die("can't open c/$name-context.c $!");
    print $fd $context_c;
    

    open my $fd,">","c/enumData.h" or die("can't open c/enumData.h $!");
    print $fd "enum DataType {\n";
    for my $data ( sort keys %dataGear ) {
        print $fd "    D_${data},\n";
    }
    print $fd "};\n\n";
    
    open my $fd,">","c/typedefData.h" or die("can't open c/typedefData.h $!");
    for my $data ( sort keys %dataGear ) {
        print $fd "typedef struct ${data} ${data};\n";
    }

    open my $fd,">","c/dataGearInit.c" or die("can't open c/dataGearInit.c $!");
    for my $data ( sort keys %dataGear ) {
        print $fd "    ALLOC_DATA(context, ${data});\n";
    }
}

# end