📄 tasking.c
字号:
rc_state->datalen = decl_temp1 (get_identifier ("datalen"), integer_type_node, 0, integer_zero_node, 0, 0); rc_state->else_clause = decl_temp1 (get_identifier ("else_clause"), integer_type_node, 0, integer_zero_node, 0, 0); /* wait_signal will store the signal number in here */ sigcodename = get_identifier ("received_signal"); rc_state->received_signal = decl_temp1 (sigcodename, chill_integer_type_node, 0, NULL_TREE, 0, 0); /* wait_buffer will store the buffer address in here */ sigcodename = get_unique_identifier ("received_buffer"); rc_state->received_buffer = decl_temp1 (sigcodename, ptr_type_node, 0, NULL_TREE, 0, 0); /* now jump to the end of RECEIVE CASE actions, to set up variables for them. */ emit_jump (rc_state->rcsetup); /* define the __rcdoit label. We come here after initialization of all variables, to execute the actions. */ emit_label (rc_state->rcdoit); filename = force_addr_of (get_chill_filename ()); linenumber = get_chill_linenumber (); /* Argument list for calling the runtime routine. We'll call it the first time we call build_receive_case_label, when we know whether to call wait_signal or wait_buffer. NOTE: at this time the first argument will be set. */ rc_state->actuallist = tree_cons (NULL_TREE, NULL_TREE, tree_cons (NULL_TREE, rc_state->n_sigs, tree_cons (NULL_TREE, rc_state->sig_code, tree_cons (NULL_TREE, rc_state->databufp, tree_cons (NULL_TREE, rc_state->datalen, tree_cons (NULL_TREE, optset, tree_cons (NULL_TREE, rc_state->else_clause, tree_cons (NULL_TREE, rc_state->to_loc, tree_cons (NULL_TREE, filename, tree_cons (NULL_TREE, linenumber, NULL_TREE)))))))))); return current_label_value;}static treebuild_receive_signal_case_label (sigdecl, loclist) tree sigdecl, loclist;{ struct rc_state_type *rc_state = current_rc_state; tree signame = DECL_NAME (sigdecl); tree expr; if (rc_state->bufseen != 0) { error ("SIGNAL in RECEIVE CASE alternative follows"); error (" a BUFFER name on line %d", rc_state->bufseen); return error_mark_node; } rc_state->sigseen = lineno; rc_state->bufseen = 0; if (!IDENTIFIER_SIGNAL_DATA (signame) && loclist != NULL_TREE) { error ("SIGNAL `%s' has no data fields", IDENTIFIER_POINTER (signame)); return error_mark_node; } if (IDENTIFIER_SIGNAL_DATA (signame) && loclist == NULL_TREE) { error ("SIGNAL `%s' requires data fields", IDENTIFIER_POINTER (signame)); return error_mark_node; } if (!rc_state->call_generated) { tree wait_call; TREE_VALUE (rc_state->actuallist) = force_addr_of (rc_state->received_signal); wait_call = build_chill_function_call (lookup_name (get_identifier ("__wait_signal_timed")), rc_state->actuallist);#if 0 chill_expand_assignment (rc_state->received_signal, NOP_EXPR, wait_call);#endif build_timesupervised_call (wait_call, rc_state->to_loc); rc_state->call_generated = 1; } /* build the conditional expression */ expr = build (EQ_EXPR, boolean_type_node, rc_state->received_signal, (tree)DECL_TASKING_CODE_DECL (sigdecl)); if (!rc_state->if_generated) { expand_start_cond (expr, 0); rc_state->if_generated = 1; } else expand_start_elseif (expr); if (IDENTIFIER_SIGNAL_DATA (signame)) { /* copy data from signal buffer to user's variables */ tree typelist = TYPE_FIELDS (TREE_TYPE (sigdecl)); tree valtail, typetail; int parmno = 1; tree pointer_type = build_chill_pointer_type (TREE_TYPE (sigdecl)); tree pointer = convert (pointer_type, rc_state->databufp); for (valtail = nreverse (loclist), typetail = typelist; valtail != NULL_TREE && typetail != NULL_TREE; parmno++, valtail = TREE_CHAIN (valtail), typetail = TREE_CHAIN (typetail)) { register tree actual = valtail ? TREE_VALUE (valtail) : 0; register tree type = typetail ? TREE_TYPE (typetail) : 0; register tree assgn; char place[30]; sprintf (place, "signal field %d", parmno); assgn = build_component_ref (build1 (INDIRECT_REF, TREE_TYPE (sigdecl), pointer), DECL_NAME (typetail)); if (!CH_TYPE_NONVALUE_P (type)) /* don't assign to non-value type. Error printed at signal definition */ chill_expand_assignment (actual, NOP_EXPR, assgn); } if (valtail == NULL_TREE && typetail != NULL_TREE) error ("too few data fields provided for `%s'", IDENTIFIER_POINTER (signame)); if (valtail != NULL_TREE && typetail == NULL_TREE) error ("too many data fields provided for `%s'", IDENTIFIER_POINTER (signame)); } /* last action here */ emit_line_note (input_filename, lineno); return build_tree_list (loclist, signame);}static treebuild_receive_buffer_case_label (buffer, loclist) tree buffer, loclist;{ struct rc_state_type *rc_state = current_rc_state; tree buftype = buffer_element_mode (TREE_TYPE (buffer)); tree expr, var; tree pointer_type, pointer, assgn; int had_errors = 0; tree x, y, z, bufaddr; if (rc_state->sigseen != 0) { error ("BUFFER in RECEIVE CASE alternative follows"); error (" a SIGNAL name on line %d", rc_state->sigseen); return error_mark_node; } rc_state->bufseen = lineno; rc_state->sigseen = 0; if (! CH_REFERABLE (buffer)) { error ("BUFFER in RECEIVE CASE alternative must be a location."); return error_mark_node; } if (TREE_CHAIN (loclist) != NULL_TREE) { error ("buffer receive alternative requires only 1 defining occurence."); return error_mark_node; } if (!rc_state->call_generated) { tree wait_call; /* here we change the mode of rc_state->sig_code to REF ARRAY (0:65535) REF __tmp_DESCR_type. This is neccesary, cause we cannot evaluate the buffer twice (once here where we compare against the address of the buffer and second in build_receive_buffer_case_end, where we use the address build the descriptor, which gets passed to __wait_buffer). So we change the comparison from if (rc_state->received_buffer == &buffer) to if (rc_state->received_buffer == rc_state->sig_codep->[rc_state->bufcnt]->datap). This will evaluate the buffer location only once (in build_receive_buffer_case_end) and therefore doesn't confuse our machinery. */ tree reftmpdescr = build_chill_pointer_type ( TREE_TYPE (lookup_name ( get_identifier ("__tmp_DESCR_type")))); tree idxtype = build_chill_range_type (NULL_TREE, integer_zero_node, build_int_2 (65535, 0)); /* should be enough, probably use ULONG */ tree arrtype = build_chill_array_type (reftmpdescr, tree_cons (NULL_TREE, idxtype, NULL_TREE), 0, NULL_TREE); tree refarrtype = build_chill_pointer_type (arrtype); TREE_VALUE (rc_state->actuallist) = force_addr_of (rc_state->received_buffer); wait_call = build_chill_function_call ( lookup_name (get_identifier ("__wait_buffer")), rc_state->actuallist);#if 0 chill_expand_assignment (rc_state->received_buffer, NOP_EXPR, wait_call);#endif build_timesupervised_call (wait_call, rc_state->to_loc); /* do this after the call, otherwise there will be a mode mismatch */ TREE_TYPE (rc_state->sig_code) = refarrtype; /* now we are ready to generate the call */ rc_state->call_generated = 1; } x = build_chill_indirect_ref (rc_state->sig_code, NULL_TREE, 0); y = build_chill_array_ref (x, tree_cons (NULL_TREE, build_int_2 (rc_state->bufcnt, 0), NULL_TREE)); z = build_chill_indirect_ref (y, NULL_TREE, 0); bufaddr = build_chill_component_ref (z, get_identifier ("datap")); /* build the conditional expression */ expr = build (EQ_EXPR, boolean_type_node, rc_state->received_buffer, bufaddr); /* next buffer in list */ rc_state->bufcnt++; if (!rc_state->if_generated) { expand_start_cond (expr, 0); rc_state->if_generated = 1; } else expand_start_elseif (expr); /* copy buffer's data to destination */ var = TREE_VALUE (loclist); if (buftype != NULL_TREE && TREE_CODE (buftype) == ERROR_MARK) had_errors = 1; else if (! CH_COMPATIBLE (var, buftype)) { error ("incompatible modes in receive buffer alternative."); had_errors = 1; } if (! CH_LOCATION_P (var)) { error ("defining occurence in receive buffer alternative must be a location."); had_errors = 1; } if (! had_errors) { pointer_type = build_chill_pointer_type (TREE_TYPE (var)); pointer = convert (pointer_type, rc_state->databufp); /* no need to check this pointer being NULL */ assgn = build_chill_indirect_ref (pointer, NULL_TREE, 0); chill_expand_assignment (var, NOP_EXPR, assgn); } /* last action here */ emit_line_note (input_filename, lineno); return build_tree_list (loclist, buffer);}/* * SIGNAME is the signal name or buffer location, * LOCLIST is a list of possible locations to store data in */treebuild_receive_case_label (signame, loclist) tree signame, loclist;{ /* now see what we have got and do some checks */ if (TREE_CODE (signame) == TYPE_DECL && CH_DECL_SIGNAL (signame)) return build_receive_signal_case_label (signame, loclist); if (TREE_TYPE (signame) != NULL_TREE && CH_IS_BUFFER_MODE (TREE_TYPE (signame))) { if (loclist == NULL_TREE) { error ("buffer receive alternative without `IN location'."); return error_mark_node; } return build_receive_buffer_case_label (signame, loclist); } error ("RECEIVE CASE alternative must specify a SIGNAL name or BUFFER location."); return error_mark_node;}/* * LABEL_CNT is the case-label counter passed from build_receive_case_start. * ELSE_CLAUSE defines if the RECEIVE CASE action had an ELSE(1) or not(0). * BUF_LIST is a tree-list of tree-lists, where TREE_VALUE defines the * BUFFER location and TREE_PURPOSE defines the defining occurence. */static voidbuild_receive_buffer_case_end (buf_list, else_clause) tree buf_list, else_clause;{ struct rc_state_type *rc_state = current_rc_state; tree alist; tree field_decls = NULL_TREE; /* list of all buffer types, for the union */ int buffer_cnt = 0; tree descr_type = lookup_name (get_identifier ("__tmp_DESCR_type")); tree tuple = NULL_TREE; /* constructors for array of ptrs */ tree union_type_node = NULL_TREE; /* walk thru all the buffers */ for (alist = buf_list; alist != NULL_TREE; buffer_cnt++, alist = TREE_CHAIN (alist)) { tree value = TREE_VALUE (alist); tree buffer = TREE_VALUE (value); /* this is the buffer */ tree data = TREE_VALUE (TREE_PURPOSE (value)); /* the location to receive in */ tree buffer_descr; tree buffer_descr_init; tree buffer_length; tree field; char fldname[20]; /* build descriptor for buffer */ buffer_length = max_queue_size (TREE_TYPE (buffer)); if (buffer_length == NULL_TREE) buffer_length = infinite_buffer_event_length_node; buffer_descr_init = build_nt (CONSTRUCTOR, NULL_TREE, tree_cons (NULL_TREE, force_addr_of (buffer), tree_cons (NULL_TREE, buffer_length, NULL_TREE))); buffer_descr = decl_temp1 (get_unique_identifier ("RCbuffer"), TREE_TYPE (descr_type), 0, buffer_descr_init, 0, 0); tuple = tree_cons (NULL_TREE, force_addr_of (buffer_descr), tuple); /* make a field for the union */ sprintf (fldname, "fld%03d", buffer_cnt); field = grok_chill_fixedfields ( tree_cons (NULL_TREE, get_identifier (fldname), NULL_TREE), TREE_TYPE (data), NULL_TREE); if (field_decls == NULL_TREE) field_decls = field; else chainon (field_decls, field); } /* generate the union */ if (field_decls != NULL_TREE) { tree data_id = get_identifier ("databuffer"); tree data_decl; union_type_node = finish_struct ( start_struct (UNION_TYPE, NULL_TREE), field_decls); data_decl = decl_temp1 (data_id, union_type_node, 0, NULL_TREE, 0, 0); chill_expand_assignment (rc_state->databufp, NOP_EXPR, force_addr_of (data_decl)); chill_expand_assignment (rc_state->datalen, NOP_EXPR, size_in_bytes (TREE_TYPE (data_decl))); } /* tell runtime system if we had an else or not */ chill_expand_assignment (rc_state->else_clause, NOP_EXPR, else_clause); /* generate the array of pointers to all buffers */ { tree array_id = get_identifier ("buf_ptr_array"); tree array_type_node = build_chill_array_type (ptr_type_node, tree_cons (NULL_TREE, build_chill_range_type (NULL_TREE, integer_one_node, build_int_2 (buffer_cnt, 0)), NULL_TREE), 0, NULL_TREE); tree constr = build_nt (CONSTRUCTOR, NULL_TREE, nreverse (tuple)); tree array_decl = decl_temp1 (array_id, array_type_node, 0, constr, 0, 0); chill_expand_assignment (build_chill_cast (ptr_type_node, rc_state->sig_code), NOP_EXPR, force_addr_of (array_decl)); chill_expand_assignment (rc_state->n_sigs, NOP_EXPR, build_int_2 (buffer_cnt, 0)); }}/* * SIG_LIST is a tree list. The TREE_VALUEs are VAR_DECLs of * __tmp_%s_code variables, and the TREE_PURPOSEs are the * TYPE_DECLs of the __tmp_%s_struct types. LABEL_CNT is the * case-label counter passed from build_receive_case_start. */static voidbuild_receive_signal_case_end (sig_list, else_clause) tree sig_list, else_clause;{ struct rc_state_type *rc_state = current_rc_state; tree alist, temp1; tree union_type_node = NULL_TREE; tree field_decls = NULL_TREE; /* list of signal structure, for the union */ tree tuple = NULL_TREE; /* constructor for array of ptrs */ int signal_cnt = 0; int fldcnt = 0; /* for each list of locations, validate it against the corresponding signal's list of fields. */ { for (alist = sig_list; alist != NULL_TREE; signal_cnt++, alist = TREE_CHAIN (alist)) { tree value = TREE_VALUE (alist); tree signame =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -