📄 tasking.c
字号:
DECL_SOURCE_LINE (decl) = 0; dataptr = force_addr_of (decl); datalen = size_in_bytes (TREE_TYPE (decl)); } /* build descriptor pointing to signal data */ { tree decl, tuple; tree tasking_message_var = get_unique_identifier ( IDENTIFIER_POINTER (signame)); tree tasking_code = (tree)DECL_TASKING_CODE_DECL (lookup_name (signame)); mark_addressable (tasking_code); tuple = build_nt (CONSTRUCTOR, NULL_TREE, tree_cons (NULL_TREE, build1 (ADDR_EXPR, build_chill_pointer_type (chill_integer_type_node), tasking_code), tree_cons (NULL_TREE, datalen, tree_cons (NULL_TREE, dataptr, NULL_TREE)))); decl = decl_temp1 (tasking_message_var, TREE_TYPE (tasking_message_type), 0, tuple, 0, 0); /* prevent granting of this type */ DECL_SOURCE_LINE (decl) = 0; tuple = force_addr_of (decl); return tuple; } }}voidexpand_send_signal (sigmsgbuffer, optroutinginfo, optsendto, optpriority, signame) tree sigmsgbuffer; tree optroutinginfo; tree optsendto; tree optpriority; tree signame;{ tree routing_size, routing_addr; tree filename, linenumber; tree sigdest = IDENTIFIER_SIGNAL_DEST (signame); /* check the presence of priority */ if (optpriority == NULL_TREE) { if (send_signal_prio == NULL_TREE) { /* issue a warning in case of -Wall */ if (extra_warnings) { warning ("Signal sent without priority"); warning (" and no default priority was set."); warning (" PRIORITY defaulted to 0"); } optpriority = integer_zero_node; } else optpriority = send_signal_prio; } /* check the presence of a destination. optdest either may be an instance location or a process declaration */ if (optsendto == NULL_TREE) { if (sigdest == NULL_TREE) { error ("SEND without a destination instance"); error (" and no destination process specified"); error (" for the signal"); optsendto = convert (instance_type_node, null_pointer_node); } else { /* build an instance [sigdest; -1] */ tree process_name = DECL_NAME (sigdest); tree copy_number = fold (build (MINUS_EXPR, integer_type_node, integer_zero_node, integer_one_node)); tree tasking_code = (tree)DECL_TASKING_CODE_DECL ( lookup_name (process_name)); optsendto = build (CONSTRUCTOR, instance_type_node, NULL_TREE, tree_cons (NULL_TREE, tasking_code, tree_cons (NULL_TREE, copy_number, NULL_TREE))); /* as our system doesn't allow that and Z.200 specifies it, we issue a warning */ warning ("SEND to ANY copy of process `%s'.", IDENTIFIER_POINTER (process_name)); } } else if (! CH_IS_INSTANCE_MODE (TREE_TYPE (optsendto))) { error ("SEND TO must be an INSTANCE mode"); optsendto = convert (instance_type_node, null_pointer_node); } else optsendto = check_non_null (convert (instance_type_node, optsendto)); /* check the routing stuff */ if (optroutinginfo != NULL_TREE) { tree routing_name; tree decl; if (TREE_TYPE (optroutinginfo) == NULL_TREE) { error ("SEND WITH must have a mode"); optroutinginfo = integer_zero_node; } routing_name = get_unique_identifier ("RI"); decl = decl_temp1 (routing_name, TREE_TYPE (optroutinginfo), 0, optroutinginfo, 0, 0); /* prevent granting of this type */ DECL_SOURCE_LINE (decl) = 0; routing_addr = force_addr_of (decl); routing_size = size_in_bytes (TREE_TYPE (decl)); } else { routing_size = integer_zero_node; routing_addr = null_pointer_node; } /* get filename and linenumber */ filename = force_addr_of (get_chill_filename ()); linenumber = get_chill_linenumber (); /* Now (at last!) we can call the runtime */ expand_expr_stmt ( build_chill_function_call (lookup_name (get_identifier ("__send_signal")), tree_cons (NULL_TREE, sigmsgbuffer, tree_cons (NULL_TREE, optsendto, tree_cons (NULL_TREE, optpriority, tree_cons (NULL_TREE, routing_size, tree_cons (NULL_TREE, routing_addr, tree_cons (NULL_TREE, filename, tree_cons (NULL_TREE, linenumber, NULL_TREE)))))))));}#if 0 * The following code builds a RECEIVE CASE action, which actually * has 2 different functionalities: * * 1) RECEIVE signal CASE action * which looks like this: * * SIGNAL advance; * SIGNAL terminate = (CHAR); * SIGNAL sig1 = (CHAR); * * DCL user, system INSTANCE; * DCL count INT, char_code CHAR; * DCL instance_loc INSTANCE; * * workloop: * RECEIVE CASE SET instance_loc; * (advance): * count + := 1; * (terminate IN char_code): * SEND sig1(char_code) TO system; * EXIT workloop; * ELSE * STOP; * ESAC; * * Because we don''t know until we get to the ESAC how * many signals need processing, we generate the following * C-equivalent code: * * /* define the codes for the signals */ * static short __tmp_advance_code; * static short __tmp_terminate_code; * static short __tmp_sig1_code; * * /* define the types of the signals */ * typedef struct * { * char fld0; * } __tmp_terminate_struct; * * typedef struct * { * char fld0; * } __tmp_sig1_struct; * * static INSTANCE user, system, instance_loc; * static short count; * static char char_code; * * { /* start a new symbol context */ * int number_of_sigs; * short *sig_code []; * void *sigdatabuf; * int sigdatalen; * short sigcode; * * goto __rcsetup; * * __rcdoit: ; * int timedout = __wait_signal (&sigcode * number_of_sigs, * sig_code, * sigdatabuf, * sigdatalen, * &instance_loc); * if (sigcode == __tmp_advance_code) * { * /* code for advance alternative's action_statement_list */ * count++; * } * else if (sigcode == __tmp_terminate_code) * { * /* copy signal's data to where they belong, * with range-check, if enabled */ * char_code = ((__tmp_terminate_struct *)sigdatabuf)->fld0; * * /* code for terminate alternative's action_statement_list */ * __send_signal (sig1 ..... ); * goto __workloop_end; * } * else * { * /* code here for the ELSE action_statement_list */ * __stop_process (); * } * goto __rc_done; * * __rcsetup: * union { __tmp_terminate_struct terminate; * __tmp_sig1_struct } databuf; * short *sig_code_ptr [2] = { &__tmp_advance_code, * &__tmp_terminate_code }; * sigdatabuf = &databuf; * sigdatalen = sizeof (databuf); * sig_code = &sig_code_ptr[0]; * number_of_sigs = 2; * goto __rcdoit; * * __rc_done: ; * } /* end the new symbol context */ * __workloop_end: ; * * * 2) RECEIVE buffer CASE action: * which looks like this: * * NEWMODE m_s = STRUCT (mini INT, maxi INT); * DCL b1 BUFFER INT; * DCL b2 BUFFER (30) s; * * DCL i INT, s m_s, ins INSTANCE; * DCL count INT; * * workloop: * RECEIVE CASE SET ins; * (b1 IN i): * count +:= i; * (b2 in s): * IF count < s.mini OR count > s.maxi THEN * EXIT workloop; * FI; * ELSE * STOP; * ESAC; * * Because we don''t know until we get to the ESAC how * many buffers need processing, we generate the following * C-equivalent code: * * typedef struct * { * short mini; * short maxi; * } m_s; * * static void *b1; * static void *b2; * static short i; * static m_s s; * static INSTANCE ins; * static short count; * * workloop: * { /* start a new symbol context */ * int number_of_sigs; * void *sig_code []; * void *sigdatabuf; * int sigdatalen; * void *buflocation; * int timedout; * * goto __rcsetup; * * __rcdoit: * timedout = __wait_buffer (&buflocation, * number_of_sigs, * sig_code, * sigdatabuf, * sigdatalen, * &ins, ...); * if (buflocation == &b1) * { * i = ((short *)sigdatabuf)->fld0; * count += i; * } * else if (buflocation == &b2) * { * s = ((m_s)*sigdatabuf)->fld1; * if (count < s.mini || count > s.maxi) * goto __workloop_end; * } * else * __stop_process (); * goto __rc_done; * * __rcsetup: * typedef struct * { * void *p; * unsigned maxqueuesize; * } Buffer_Descr; * union { short b1, * m_s b2 } databuf; * Buffer_Descr bufptr [2] = * { * { &b1, -1 }, * { &b2, 30 }, * }; * void * bufarray[2] = { &bufptr[0], * &bufptr[1] }; * sigdatabuf = &databuf; * sigdatalen = sizeof (databuf); * sig_code = &bufarray[0]; * number_of_sigs = 2; * goto __rcdoit; * * __rc_done; * } /* end of symbol context */ * __workloop_end: *#endifstruct rc_state_type{ struct rc_state_type *enclosing; rtx rcdoit; rtx rcsetup; tree n_sigs; tree sig_code; tree databufp; tree datalen; tree else_clause; tree received_signal; tree received_buffer; tree to_loc; int sigseen; int bufseen; tree actuallist; int call_generated; int if_generated; int bufcnt;};struct rc_state_type *current_rc_state = NULL;/* * this function tells if there is an if to terminate * or not */intbuild_receive_case_if_generated(){ if (!current_rc_state) { error ("internal error: RECEIVE CASE stack invalid."); abort (); } return current_rc_state->if_generated;}/* build_receive_case_start returns an INTEGER_CST node containing the case-label number to be used by build_receive_case_end to generate correct labels */treebuild_receive_case_start (optset) tree optset;{ /* counter to generate unique receive_case labels */ static int rc_lbl_count = 0; tree current_label_value = build_int_2 ((HOST_WIDE_INT)rc_lbl_count, 0); tree sigcodename, filename, linenumber; struct rc_state_type *rc_state = (struct rc_state_type*) xmalloc (sizeof (struct rc_state_type)); rc_state->rcdoit = gen_label_rtx (); rc_state->rcsetup = gen_label_rtx (); rc_state->enclosing = current_rc_state; current_rc_state = rc_state; rc_state->sigseen = 0; rc_state->bufseen = 0; rc_state->call_generated = 0; rc_state->if_generated = 0; rc_state->bufcnt = 0; rc_lbl_count++; if (optset == NULL_TREE || TREE_CODE (optset) == ERROR_MARK) optset = null_pointer_node; else { if (CH_IS_INSTANCE_MODE (TREE_TYPE (optset)) && CH_LOCATION_P (optset)) optset = force_addr_of (optset); else { error ("SET requires INSTANCE location"); optset = null_pointer_node; } } rc_state->to_loc = build_timeout_preface (); rc_state->n_sigs = decl_temp1 (get_identifier ("number_of_sigs"), integer_type_node, 0, integer_zero_node, 0, 0); rc_state->sig_code = decl_temp1 (get_identifier ("sig_codep"), ptr_type_node, 0, null_pointer_node, 0, 0); rc_state->databufp = decl_temp1 (get_identifier ("databufp"), ptr_type_node, 0, null_pointer_node, 0, 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -