Skip to content
Snippets Groups Projects
Commit 8518ae39 authored by Fort Frédéric's avatar Fort Frédéric
Browse files

Summary: Improved support for AER and added ptask wrapper

git-svn-id: https://svn.onera.fr/Prelude/Prelude/trunk@868 49f62630-d767-4ccd-930e-b3f5589f52e1
parent 38aa42f5
No related branches found
No related tags found
No related merge requests found
......@@ -22,7 +22,7 @@
#include <string.h>
#include "extern_com.h"
extern void ** buffer_addresses;
extern void * buffer_addresses[];
void write_val(int id, int cell, int data_size, const void* data){
memcpy(buffer_addresses[id]+cell*data_size, data, data_size);
......
......@@ -33,6 +33,9 @@ struct nonencoded_aer_task_params {
int (*nea_t_A)(void*); // Input acquisition step
int (*nea_t_E)(void*); // Execution step
int (*nea_t_R)(void*); // Output restitution step
int (*nea_t_I)(void*); // Initialization step
};
void get_task_set(int* task_number, struct nonencoded_aer_task_params** task_set);
#endif
/* ----------------------------------------------------------------------------
* Copyright (C) 2009-2011, ONERA, Toulouse, FRANCE - LIFL, Lille, FRANCE
*
* This file is part of Prelude
*
* Prelude is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation ; either version 2 of
* the License, or (at your option) any later version.
*
* Prelude is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program ; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*---------------------------------------------------------------------------- */
// Authors: Titouan ROOS, Julien FORGET, Frédéric FORT
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ptask.h"
#include "pbarrier.h"
#include "nonencoded_aer_task_params.h"
#include "multirate_precedence.h"
struct task_args
{
struct nonencoded_aer_task_params *params;
struct job_prec **pred_pref;
int* pred_pref_size;
struct job_prec **pred_pat;
int* pred_pat_size;
sem_t **pred_sem;
int *pred_period;
int pred_count;
struct job_prec **succ_pref;
int* succ_pref_size;
struct job_prec **succ_pat;
int* succ_pat_size;
sem_t **succ_sem;
int *succ_period;
int succ_count;
};
void append(void** array, void* add, size_t num_elements, size_t elem_size);
sem_t create_sem();
int nth(int n, struct job_prec* pref, int pref_size, struct job_prec* pat, int pat_size, int src);
int gcd(int a, int b);
int lcm(int a, int b);
void task_body()
{
struct task_args *args = ptask_get_argument();
struct nonencoded_aer_task_params *task_struct = args->params;
int job_id = 0;
int i;
while(1)
{
for(i = 0; i < args->pred_count; ++i)
{
if(job_id % args->pred_period[i] ==
nth(job_id,
args->pred_pref[i], args->pred_pref_size[i],
args->pred_pat[i], args->pred_pat_size[i],
0))
{
sem_wait(args->pred_sem[i]);
}
}
//ptime next_deadline;
// call step function
if (task_struct->nea_t_A)
task_struct->nea_t_A(NULL);
if (task_struct->nea_t_E)
task_struct->nea_t_E(NULL);
if (task_struct->nea_t_R)
task_struct->nea_t_R(NULL);
for(i = 0; i < args->succ_count; ++i)
{
if (job_id % args->succ_period[i] ==
nth(job_id,
args->succ_pref[i], args->succ_pref_size[i],
args->succ_pat[i], args->succ_pat_size[i],
1))
sem_post(args->succ_sem[i]);
}
job_id += 1;
ptask_wait_for_period();
}
}
int main()
{
struct nonencoded_aer_task_params *task_set;
struct multirate_precedence *prec_set;
tpars param;
int task_number, prec_number, i, j;
ptask_init(SCHED_DEADLINE, PARTITIONED, PRIO_INHERITANCE);
// get Prelude task set
get_task_set(&task_number, &task_set);
get_precedence_set(&prec_number, &prec_set);
int task_pid[task_number];
struct task_args args[task_number];
sem_t sems[prec_number];
int sem_count = 0;
memset(&args, 0, task_number*sizeof(struct task_args));
//populate task arguments
for (i=0; i<task_number; i++)
{
args[i].params = &task_set[i];
}
for (i=0; i<prec_number; i++)
{
int pred = -1;
int succ = -1;
for (j=0; j<task_number && (pred==-1 || succ==-1); j++)
{
if (strcmp(prec_set[i].src_name, task_set[j].nea_t_name) == 0)
{
pred = j;
}
else if (strcmp(prec_set[i].dst_name, task_set[j].nea_t_name) == 0)
{
succ = j;
}
}
sems[sem_count] = create_sem();
int hyperperiod = lcm(task_set[pred].nea_t_period, task_set[succ].nea_t_period);
sem_t *sem = &sems[sem_count];
int succ_period = hyperperiod/task_set[succ].nea_t_period;
int pred_period = hyperperiod/task_set[pred].nea_t_period;
append(
(void**)&args[succ].pred_pref,
&prec_set[i].prec_pref,
args[succ].pred_count,
sizeof(struct job_prec*));
append(
(void**)&args[succ].pred_pat,
&prec_set[i].prec_pat,
args[succ].pred_count,
sizeof(struct job_prec*));
append(
(void**)&args[succ].pred_pref_size,
&prec_set[i].prec_pref_size,
args[succ].pred_count,
sizeof(int));
append(
(void**)&args[succ].pred_pat_size,
&prec_set[i].prec_pat_size,
args[succ].pred_count,
sizeof(int));
append(
(void**)&args[succ].pred_sem,
&sem,
args[succ].pred_count,
sizeof(sem_t*));
append(
(void**)&args[succ].pred_period,
&succ_period,
args[succ].pred_count,
sizeof(int));
append(
(void**)&args[pred].succ_pref,
&prec_set[i].prec_pref,
args[pred].succ_count,
sizeof(struct job_prec*));
append(
(void**)&args[pred].succ_pref_size,
&prec_set[i].prec_pref_size,
args[pred].pred_count,
sizeof(int));
append(
(void**)&args[pred].succ_pat,
&prec_set[i].prec_pat,
args[pred].succ_count,
sizeof(struct job_prec*));
append(
(void**)&args[pred].succ_pat_size,
&prec_set[i].prec_pat_size,
args[pred].succ_count,
sizeof(int));
append(
(void**)&args[pred].succ_sem,
&sem,
args[pred].succ_count,
sizeof(sem_t*));
append(
(void**)&args[pred].succ_period,
&pred_period,
args[pred].succ_count,
sizeof(int));
sem_count += 1;
args[pred].succ_count += 1;
args[succ].pred_count += 1;
}
// create tasks
for (i=0; i<task_number; i++)
{
ptask_param_init(param);
ptask_param_argument(param, &args[i]);
ptask_param_period(param, (ptime)(task_set[i].nea_t_period), MILLI);
ptask_param_deadline(param, (ptime)task_set[i].nea_t_deadline, MILLI);
ptask_param_processor(param, i%2); // multi-core scheduling
ptask_param_runtime(param, (ptime)(task_set[i].nea_t_wcet), MILLI);
ptask_param_activation(param, DEFERRED);
task_pid[i] = ptask_create_param(task_body, &param);
if (task_pid[i]<0) {
fprintf(stderr,"Could not create task %s\n",task_set[i].nea_t_name);
exit(-1);
}
//printf("Created task %s with dd %d\n", task_set[i].nea_t_name, (int)deadline);
}
printf("All tasks created\n");
for (i= 0; i<task_number; i++)
{
if (task_set[i].nea_t_I != NULL)
{
ptask_param_init(param);
ptask_param_processor(param, i%2);
int pid = ptask_create_param((void(*)(void))task_set[i].nea_t_I, &param);
if (pid<0)
{
fprintf(stderr, "Could not create task %s_I\n", task_set[i].nea_t_name);
exit(-1);
}
pthread_join(ptask_get_threadid(pid), 0);
}
}
ptime now = ptask_gettime(MILLI);
for (i=0; i<task_number; i++)
{
ptime offt = 10 + now;
int r = ptask_activate_at(i, offt, MILLI);
if (r < 0)
{
printf("Could not activate task %s\n", task_set[i].nea_t_name);
}
}
printf("All tasks activated\n");
// Wait for tasks to finish even if they shouldn't
for(i=0; i<task_number; i++)
{
pthread_join(ptask_get_threadid(task_pid[i]), 0);
}
// This should never return
return 1;
}
sem_t create_sem()
{
sem_t sem;
sem_init(&sem, 0, 0);
return sem;
}
int nth
(int n,
struct job_prec* pref, int pref_size,
struct job_prec* pat, int pat_size,
int src)
{
if (n < pref_size)
{
if (src)
return pref[n].src_job;
else
return pref[n].dst_job;
}
else
{
if (src)
return pat[(n-pref_size)%pat_size].src_job;
else
return pat[(n-pref_size)%pat_size].dst_job;
}
}
int gcd(int a, int b)
{
if (a==b)
return a;
else if (a > b)
return gcd(a-b, b);
else
return gcd(a, b-a);
}
int lcm(int a, int b)
{
return (a*b)/gcd(a,b);
}
void append(void** array, void* add, size_t num_elements, size_t elem_size)
{
char* tmp = realloc(*array, elem_size*(num_elements+1));
memcpy(tmp+(num_elements*elem_size), add, elem_size);
*array = tmp;
}
# Authors: Titouan ROOS, Julien FORGET, Frédéric Fort
.SUFFIX:
# modify these folders depending on your installation
PTASK_SOURCE_FOLDER=/usr/local
PRELUDE_FOLDER=/usr/local
PRELUDE_BIN_FOLDER=$(PRELUDE_FOLDER)/bin
PRELUDE_SHARE_FOLDER=$(PRELUDE_FOLDER)/share
PRELUDE_LIB_FOLDER=$(PRELUDE_FOLDER)/lib
# modify these 3 lines for each new Prelude program
PRELUDE_PROGRAM_FOLDER=.
PRELUDE_PROGRAM_NAME=fcs
PRELUDE_NODE_NAME=fcs
# you might want to copy the file out of your installation and modify this line
PTASK_WRAPPER=$(PRELUDE_SHARE_FOLDER)/ptask_wrapper_aer
PRELUDE_PROGRAM=$(PRELUDE_PROGRAM_FOLDER)/$(PRELUDE_PROGRAM_NAME).plu
PRELUDE_C_FOLDER=$(PRELUDE_PROGRAM_FOLDER)/$(PRELUDE_PROGRAM_NAME)_c
PRELUDE_C_PROGRAM=$(PRELUDE_C_FOLDER)/$(PRELUDE_NODE_NAME)
USER_C_FOLDER=$(PRELUDE_PROGRAM_FOLDER)
# next line is used only if nodes are not directly defined in header file
USER_C_NODES=$(PRELUDE_PROGRAM_NAME)_nodes
EXTERN_BUFFERS=$(PRELUDE_C_FOLDER)/$(PRELUDE_NODE_NAME)_extbuffers
EXTERN_COM=extern_com
OBJS=$(PRELUDE_C_PROGRAM).o $(EXTERN_BUFFERS).o $(PTASK_WRAPPER).o $(USER_C_NODES).o $(EXTERN_COM).o
PRELUDEC=$(PRELUDE_BIN_FOLDER)/preludec
PLUFLAGS=-aer
CC=gcc
CFLAGS=-I$(PTASK_SOURCE_FOLDER)/src -I$(USER_C_FOLDER) -I$(PRELUDE_PROGRAM_FOLDER)/$(PRELUDE_PROGRAM_NAME)_c -I$(PRELUDE_LIB_FOLDER)/prelude -Wall -g
LDFLAGS=-lptask -L$(PTASK_SOURCE_FOLDER)/build/src -pthread -lrt
EXEC=$(PRELUDE_PROGRAM_NAME)
.PHONY: all clean
all: $(EXEC)
$(EXEC): $(OBJS)
$(CC) -o $(EXEC) $^ $(LDFLAGS)
$(PRELUDE_C_PROGRAM).c $(EXTERN_BUFFERS).c: $(PRELUDE_PROGRAM)
$(PRELUDEC) $(PLUFLAGS) -node $(PRELUDE_NODE_NAME) $(PRELUDE_PROGRAM)
%.o: %.c
$(CC) -o $@ -c $< $(CFLAGS)
clean:
rm -rf *.o *~ $(EXEC) $(PRELUDE_C_FOLDER) $(PTASK_WRAPPER).o
......@@ -125,7 +125,8 @@ let pp_lwrite_allocs_task out_f types_f task static =
if static then
fprintf out_f "static ";
pp_tuple_type types_f task;
fprintf out_f "%s %s;@ " (outstruct_type task.task_id)
fprintf out_f "%s %s;@ "
(outstruct_type task.task_id)
(outstruct_name task.task_id)
end
else if List.length task.task_outputs = 1 then (* use a scalar *)
......@@ -141,65 +142,29 @@ let pp_lwrite_allocs_task out_f types_f task static =
let pp_lwrite_allocs out_f types_f task_set =
Hashtbl.iter (fun _ task -> pp_lwrite_allocs_task out_f types_f task true) task_set
(** Produce the read communication protocol for communication [vref_pred->vin] *)
let pp_read_proto out_f tid no_init (vin,vref_pred,proto) =
if proto.rbuf_size > 1 then
(** Print an array*)
let pp_array out_f ty_str name length =
fprintf out_f "%s %s[%i];@ " ty_str name length
(** Generic protocol printer*)
let pp_proto_struct out_f struct_type proto_name no_init tid vid pref pat =
let pref_length, pat_length =
(Array.length proto.change_pref),
(Array.length proto.change_pat) in
if (pref_length > 1) || (pat_length > 1) then
(Array.length pref),
(Array.length pat) in
if pref_length > 1 || pat_length > 1 then
begin
let proto_name = read_proto_name tid vin.var_id in
fprintf out_f "static struct %s %s" struct_type proto_name;
if no_init then
fprintf out_f "struct read_proto_t %s;@ " proto_name
else
begin
fprintf out_f "static struct read_proto_t %s =@ { " proto_name;
(* Prefix *)
fprintf out_f ";@ ";
if pref_length > 0 then
begin
fprintf out_f "(int [])";
print_array_litteral out_f
(fun out_f v -> fprintf out_f "%s" (cstring_of_bool v))
(cstring_of_bool false)
(fun v -> v=false)
proto.change_pref;
fprintf out_f ", "
end
else
fprintf out_f "NULL, ";
fprintf out_f "%i, " pref_length;
(* Pattern *)
pp_array out_f "static int" (proto_array_name proto_name true) pref_length;
if pat_length > 0 then
begin
fprintf out_f "(int [])";
print_array_litteral out_f
(fun out_f v -> fprintf out_f "%s" (cstring_of_bool v))
(cstring_of_bool false)
(fun v -> v=false)
proto.change_pref;
fprintf out_f ", "
end
else (* no protocol needed *)
fprintf out_f "NULL, ";
fprintf out_f "%i };@ " pat_length
end
pp_array out_f "static int" (proto_array_name proto_name false) pat_length;
end
(** Produce the write communication protocol for communication [vout->vref_succ] *)
let pp_write_proto out_f tid vout vref_succ proto no_init =
if proto.wbuf_size > 1 then
let pref_length, pat_length =
(Array.length proto.write_pref),
(Array.length proto.write_pat) in
if (pref_length > 1) || (pat_length > 1) then
begin
let proto_name = write_proto_name tid vout.var_id vref_succ in
if no_init then
fprintf out_f "struct write_proto_t %s;@ " proto_name
else
begin
fprintf out_f "static struct write_proto_t %s =@ { " proto_name;
fprintf out_f " =@ {";
(* Prefix *)
if pref_length > 0 then
begin
......@@ -208,13 +173,11 @@ let pp_write_proto out_f tid vout vref_succ proto no_init =
(fun out_f v -> fprintf out_f "%s" (cstring_of_bool v))
(cstring_of_bool false)
(fun v -> v=false)
proto.write_pref;
fprintf out_f ", "
pref
end
else
fprintf out_f "NULL, ";
fprintf out_f "%i, " pref_length;
(* Pattern *)
else (* no prefix protocol needed *)
fprintf out_f "NULL";
fprintf out_f ", %i, " pref_length;
if pat_length > 0 then
begin
fprintf out_f "(int[])";
......@@ -222,15 +185,38 @@ let pp_write_proto out_f tid vout vref_succ proto no_init =
(fun out_f v -> fprintf out_f "%s" (cstring_of_bool v))
(cstring_of_bool false)
(fun v -> v=false)
proto.write_pat;
fprintf out_f ", "
pat
end
else (* no protocol needed *)
fprintf out_f "NULL, ";
fprintf out_f "%i };@ " pat_length
else (* no pattern protocol needed *)
fprintf out_f "NULL";
fprintf out_f ", %i};@ " pat_length
end
end
(** Produce the read communication protocol for communication [vref_pred->vin] *)
let pp_read_proto out_f tid no_init (vin,vref_pred,proto) =
if proto.rbuf_size > 1 then
pp_proto_struct out_f
read_proto_struct_name
(read_proto_name tid vin.var_id)
no_init
tid
vin.var_id
proto.change_pref
proto.change_pat
(** Produce the write communication protocol for communication [vout->vref_succ] *)
let pp_write_proto out_f tid vout vref_succ proto no_init =
if proto.wbuf_size > 1 then
pp_proto_struct out_f
write_proto_struct_name
(write_proto_name tid vout.var_id vref_succ)
no_init
tid
vout.var_id
proto.write_pref
proto.write_pat
(** Produce the write communication protocols for all the [readers] of [vout] *)
let pp_write_protos out_f tid no_init (vout,readers) =
List.iter
......@@ -267,20 +253,20 @@ let pp_buffer_indices out_f task_set =
(** Generate buffer addresses for [task]. For buffers in extern memory. *)
let pp_buffer_addr_task out_f task =
Print.list_printer_from_printer "" "" ""
Print.list_printer_from_printer "" "@ " ""
(fun out_f (vin,vref_from,read_proto) ->
let vref_to = vref_of_task_var task vin in
fprintf out_f " (void *) ";
if read_proto.rbuf_size = 1 then
fprintf out_f "&";
fprintf out_f "%s,@ " (combuffer_name vref_from vref_to);
fprintf out_f "%s," (combuffer_name vref_from vref_to);
)
out_f task.task_inputs
(** Generate buffer addresses for the whole [task_set]. For buffers in extern memory. *)
let pp_buffer_addrs out_f task_set =
fprintf out_f "void * buffer_addresses [%s] =@ " nb_buffers_name;
Print.hashtbl_printer_from_printer "@[<v 2>{@ " "" "@]@ };"
Print.hashtbl_printer_from_printer "@[<v 2>{@ " "@ " "@]@ };"
(fun ouf_f (_,task) -> pp_buffer_addr_task out_f task)
out_f task_set;
fprintf out_f "@."
......
......@@ -139,9 +139,14 @@ let pp_task_params out_f task =
fprintf out_f "%s, " (fun_name_A task.task_id);
fprintf out_f "%s, " (fun_name_E task.task_id);
if task.task_kind = Actuator then
fprintf out_f "NULL"
fprintf out_f "NULL, "
else
fprintf out_f "%s, " (fun_name_R task.task_id);
let needs_idx, needs_sidx = C_task_functions.needs_idxs task in
if task.task_kind <> CstTask && (needs_idx || needs_sidx) then
fprintf out_f "%s" (fun_name_init task.task_id)
else
fprintf out_f "%s" (fun_name_R task.task_id);
fprintf out_f "NULL";
fprintf out_f "}"
end
else
......
......@@ -52,6 +52,10 @@ let buffer_struct_name = "buffer_desc"
let com_struct_name = "com_t"
let read_proto_struct_name = "read_proto_t"
let write_proto_struct_name = "write_proto_t"
let task_name (nid,ntag) =
nid^(string_of_int ntag)
......@@ -207,6 +211,9 @@ let read_proto_pref_size_name = "rpref_size"
let read_proto_pat_name = "change_pat"
let read_proto_pat_size_name = "rpat_size"
let proto_array_name proto_name pref =
proto_name^(if pref then "_pref" else "_pat")
let nb_tasks_name = "PLUD_TASK_NUMBER"
let static_task_set_name = "static_task_set"
......
......@@ -29,6 +29,24 @@ open Format
let array_collapse_threshold = 4
let would_collapse array =
let (last_v, c, res) =
Array.fold_left
(fun (prec_v, cpt, res) v ->
match res,prec_v with
| true,_ -> prec_v,cpt,true
| _,None -> Some v, 1, res
| _,Some pv ->
if pv = v then
Some v, cpt+1, res
else
Some v, 1, res || cpt >= array_collapse_threshold)
(None,0,false) array
in
match last_v with
| None -> res
| Some lv -> res || (c >= array_collapse_threshold)
let collapse_array array =
let (last_v,cpt,l) =
Array.fold_left
......@@ -47,6 +65,32 @@ let collapse_array array =
| None -> List.rev l
| Some lv -> List.rev ((lv,cpt)::l)
let any_uses_read_proto inputs = List.exists (fun (_,_,x) -> uses_read_protocol x) inputs
let any_uses_write_proto outputs trace_instances =
List.exists
(fun (_,x) -> uses_write_protocol x)
(List.concat (List.map (fun (_,x) -> x) outputs)) ||
(trace_instances && Options.trace_instances ())
let needs_idxs task =
let needs_idxr = any_uses_read_proto task.task_inputs in
let needs_idxw = any_uses_write_proto task.task_outputs false in
let needs_idx = needs_idxr || needs_idxw in
let protos =
List.map
(fun (_,_,p) -> [p.change_pat;p.change_pref])
task.task_inputs
@
List.map
(fun (_,p) -> [p.write_pat;p.write_pref])
(List.concat (List.map (fun (_,x) -> x) task.task_outputs))
|>
List.concat
in
let needs_sidx = List.exists would_collapse protos in
needs_idx, needs_sidx
let pp_array_slice printer out_f (v,repeat) =
if repeat < array_collapse_threshold then
begin
......@@ -69,14 +113,6 @@ let pp_init_array out_f printer array =
Print.list_printer_from_printer "" "@ " "@ "
(fun out_f (v,repeat) -> pp_array_slice printer out_f (v,repeat)) out_f col_array
let any_uses_read_proto inputs = List.exists (fun (_,_,x) -> uses_read_protocol x) inputs
let any_uses_write_proto outputs =
List.exists
(fun (_,x) -> uses_write_protocol x)
(List.concat ((List.map (fun (_,x) -> x)) outputs)) ||
Options.trace_instances ()
(** Generates the initialization function for the buffer of
communication [vref_from->vref_to]. For multi-core architectures. *)
let pp_buffer_init_fun out_f task ty read_proto vref_from vref_to =
......@@ -90,6 +126,7 @@ let pp_buffer_init_fun out_f task ty read_proto vref_from vref_to =
| Some cst ->
fprintf out_f "void %s()@ {@[<v 2>@ " funname;
fprintf out_f "int %s;@ " init_idx;
if buf_size >= array_collapse_threshold then
fprintf out_f "int %s;@ " init_sidx;
fprintf out_f "%s %s[%i];@ " ty bname buf_size;
pp_init_array out_f
......@@ -222,18 +259,80 @@ let pp_write_protos_init_fun out_f tid (vout,readers) =
(fun (vref_succ,proto) -> pp_write_proto_init_fun out_f tid vout vref_succ proto)
readers
let pp_proto_array_assign out_f pref_length pat_length pref_name pat_name proto_name buf_size pref_array pat_array =
if buf_size > 1 then
if pref_length > 1 then
fprintf out_f "%s.%s = %s;@ " proto_name pref_name pref_array;
if pat_length > 1 then
fprintf out_f "%s.%s = %s;@ " proto_name pat_name pat_array
let pp_rproto_array_assign out_f tid (vin,vref,proto) =
let proto_name = read_proto_name tid vin.var_id in
pp_proto_array_assign
out_f
(Array.length proto.change_pref)
(Array.length proto.change_pat)
read_proto_pref_name
read_proto_pat_name
proto_name
proto.rbuf_size
(proto_array_name proto_name true)
(proto_array_name proto_name false)
let pp_wproto_array_assign out_f tid (vout,readers) =
List.iter
(fun (vref_succ,proto) ->
let proto_name = write_proto_name tid vout.var_id vref_succ in
pp_proto_array_assign
out_f
(Array.length proto.write_pref)
(Array.length proto.write_pat)
write_proto_pref_name
write_proto_pat_name
proto_name
(proto.wbuf_size)
(proto_array_name proto_name true)
(proto_array_name proto_name false))
(** Generates communication protocol and buffer initialization functions for the
inputs and outputs of [task] *)
let pp_init_funs_task out_f task =
let pp_init_funs_task out_f task needs_idx needs_sidx =
pp_buffer_init_funs_task out_f task;
fprintf out_f "int %s()@ @[<v 2>{@ " (fun_name_init task.task_id);
if needs_idx then
fprintf out_f "int %s=0;@ " init_idx;
if needs_sidx then
fprintf out_f "int %s=0;@ @ " init_sidx;
pp_buffer_init_fun_calls_task out_f task;
fprintf out_f "@ ";
List.iter (fun (vin,vref,proto) ->
let proto_name = read_proto_name task.task_id vin.var_id in
pp_proto_array_assign
out_f
(Array.length proto.change_pref)
(Array.length proto.change_pat)
read_proto_pref_name
read_proto_pat_name
proto_name
(proto.rbuf_size)
(proto_array_name proto_name true)
(proto_array_name proto_name false)) task.task_inputs;
List.iter (fun (vout,readers) ->
List.iter
(fun (vref_succ,proto) ->
let proto_name = write_proto_name task.task_id vout.var_id vref_succ in
pp_proto_array_assign
out_f
(Array.length proto.write_pref)
(Array.length proto.write_pat)
write_proto_pref_name
write_proto_pat_name
proto_name
(proto.wbuf_size)
(proto_array_name proto_name true)
(proto_array_name proto_name false)) readers) task.task_outputs;
List.iter (pp_read_proto_init_fun out_f task.task_id) task.task_inputs;
List.iter (pp_write_protos_init_fun out_f task.task_id) task.task_outputs;
......@@ -246,8 +345,10 @@ let pp_init_funs_task out_f task =
instead of litterals at top-level *)
let pp_init_funs out_f task_set =
Hashtbl.iter
(fun _ t -> if t.task_kind <> CstTask then
pp_init_funs_task out_f t)
(fun _ t ->
let needs_idx, needs_sidx = needs_idxs t in
if (t.task_kind <> CstTask) && (needs_idx || needs_sidx) then
pp_init_funs_task out_f t needs_idx needs_sidx)
task_set;
fprintf out_f "@ "
......@@ -469,7 +570,8 @@ let pp_write_idx out_f (vout,readers) =
(fun (vref_succ,proto) ->
if proto.wbuf_size > 1 then
let init_cell = match proto.wbuf_init with | Some _ -> 1 | None -> 0 in
fprintf out_f "static int %s=%i;@ " (write_cell_pointer_name vout vref_succ)
fprintf out_f "static int %s=%i;@ "
(write_cell_pointer_name vout vref_succ)
init_cell)
readers
......@@ -484,7 +586,7 @@ let pp_task_body out_f types_f task =
List.iter (pp_read_idx out_f) task.task_inputs;
List.iter (pp_write_idx out_f) task.task_outputs;
(* if any task uses protocol in ntask.task_inputs @ task.task_outputs *)
let needs_instance_var = any_uses_read_proto task.task_inputs || any_uses_write_proto task.task_outputs in
let needs_instance_var = any_uses_read_proto task.task_inputs || any_uses_write_proto task.task_outputs true in
if needs_instance_var then
fprintf out_f "static int %s=0;@ @ " inst_cpt_name;
C_traces.pp_trace_buf_alloc out_f task;
......@@ -556,7 +658,7 @@ let pp_task_R out_f task =
fprintf out_f "int %s(void* args)@ " (fun_name_R task.task_id);
fprintf out_f "@[<v 2>{@ ";
let uses_protocol = any_uses_write_proto task.task_outputs in
let uses_protocol = any_uses_write_proto task.task_outputs true in
List.iter (pp_write_idx out_f) task.task_outputs;
if uses_protocol then
fprintf out_f "static int %s=0;@ @ " inst_cpt_name;
......
......@@ -102,7 +102,7 @@ let compile basename =
if !Options.print_tasks_simple_precs then
Task_set.pp_task_set_simple_precs task_set;
(* Produce C code *)
if (!Options.aer_format) then
if !Options.aer_format then
begin
To_c.pp_prog_aer task_set gred basename;
Xml_wcc.pp_prog task_set basename
......@@ -114,6 +114,7 @@ let anonymous filename =
if Filename.check_suffix filename extension
then
let basename = Filename.chop_suffix filename extension in
let basename = Filename.basename basename in
compile basename
else
raise (Arg.Bad ("Can only compile *.plu files"))
......
......@@ -138,6 +138,8 @@ let pp_prog_aer task_set task_graph basename =
pp_types_header types_f;
pp_header out_f basename;
fprintf out_f "@ ";
C_buffers.pp_buffer_indices types_f task_set;
C_buffers.pp_lread_allocs out_f task_set;
fprintf out_f "@ ";
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment