00001 00006 #include "libmgk.h" 00007 00008 mgk_nodep 00009 mgk_current_node(void) 00010 { 00011 return (__mgk_running_node); 00012 } 00013 00014 void * 00015 mgk_receive(unsigned int port, mgk_data_type * typep) 00016 { 00017 mgk_inport *ip; 00018 mgk_value *vp; 00019 void *result; 00020 if (!__mgk_running_node) { 00021 mgk_errno = E_NOTRUNNING; 00022 *typep = T_NODATA; 00023 return (NULL); 00024 } 00025 if (port >= __mgk_running_node->nin) { 00026 mgk_errno = E_BADPORTIX; 00027 *typep = T_NODATA; 00028 return (NULL); 00029 } 00030 ip = &__mgk_running_node->ins[port]; 00031 if (!(vp = ip->head)) { 00032 mgk_errno = E_SUCCESS; 00033 *typep = T_NODATA; 00034 return (NULL); 00035 } 00036 ip->head = vp->next; 00037 ip->qlen--; 00038 result = __mgk_extract_value(vp, typep, &ip->scalar_val); 00039 if (*typep & T_BUFFER) { 00040 mgk_buffer *bp = __mgk_checked_buffer_header(vp->value); 00041 if (bp && !bp->refval) { 00042 bp->next = __mgk_running_node->buffer_list; 00043 __mgk_running_node->buffer_list = bp; 00044 } 00045 } 00046 return (result); 00047 } 00048 00049 mgk_error_code 00050 mgk_propagate(unsigned int port, 00051 void *data, 00052 mgk_data_type type) 00053 { 00054 mgk_value *vp, *remval = NULL; 00055 mgk_outport *op; 00056 mgk_link *lp; 00057 int refcnt = 0; 00058 if (!__mgk_running_node) { 00059 return (mgk_errno = E_NOTRUNNING); 00060 } 00061 if (port >= __mgk_running_node->nout) { 00062 return (mgk_errno = E_BADPORTIX); 00063 } 00064 if (!(op = &__mgk_running_node->outs[port])->links) { 00065 return (mgk_errno = E_PORTCONN); 00066 } 00067 if (!(vp = __mgk_build_value(data, type))) { 00068 return (mgk_errno); 00069 } 00070 for (lp = op->links; lp; lp = lp->l.l2l.nextout) { 00071 mgk_value *sendval; 00072 mgk_node *dst; 00073 mgk_inport *ip; 00074 switch (lp->type) { 00075 case LINK_L2L: 00076 sendval = (lp == op->links) ? vp : __mgk_copy_value(vp); 00077 dst = lp->l.l2l.dst; 00078 ip = &dst->ins[lp->dstidx]; 00079 if (ip->head) { 00080 ip->tail->next = sendval; 00081 } 00082 else { 00083 ip->head = sendval; 00084 } 00085 ip->tail = sendval; 00086 sendval->next = NULL; 00087 ip->qlen++; 00088 if ((ip->head == ip->tail) && 00089 (dst->status == WAITING) && 00090 (dst->priority > MGK_NODE_STOP_PRIORITY)) { 00091 __mgk_update(dst); 00092 } 00093 break; 00094 case LINK_L2R: 00095 if (!remval) { 00096 remval = (lp == op->links) ? vp : __mgk_copy_value(vp); 00097 } 00098 sendval = __mgk_alias_value_autofree(remval, &refcnt); 00099 if (lp->l.l2r.head) { 00100 lp->l.l2r.tail->next = sendval; 00101 } 00102 else { 00103 lp->l.l2r.head = sendval; 00104 } 00105 lp->l.l2r.tail = sendval; 00106 sendval->next = NULL; 00107 lp->l.l2r.qlen++; 00108 if (!lp->l.l2r.active) { 00109 __mgk_remote_propagate(lp); 00110 } 00111 break; 00112 default: 00113 return (mgk_errno = E_GENERROR); 00114 } 00115 } 00116 return (mgk_errno = E_SUCCESS); 00117 } 00118 00119 mgk_error_code 00120 mgk_protect_buffer(void *buffer) 00121 { 00122 mgk_buffer *bp = __mgk_checked_buffer_header(buffer); 00123 if (bp) { 00124 if (!__mgk_running_node) { 00125 return (mgk_errno = E_NOTRUNNING); 00126 } 00127 if (bp->refval) { 00128 return (mgk_errno = E_BUFFERUSED); 00129 } 00130 bp->refval = __mgk_running_node; 00131 return (mgk_errno = E_SUCCESS); 00132 } 00133 return (mgk_errno = E_NOTBUFFER); 00134 } 00135 00136 mgk_error_code 00137 mgk_unprotect_buffer(void *buffer) 00138 { 00139 mgk_buffer *bp = __mgk_checked_buffer_header(buffer); 00140 if (bp) { 00141 if (!__mgk_running_node) { 00142 return (mgk_errno = E_NOTRUNNING); 00143 } 00144 if (bp->refval != __mgk_running_node) { 00145 return (mgk_errno = E_BUFFERUSED); 00146 } 00147 bp->refval = NULL; 00148 return (mgk_errno = E_SUCCESS); 00149 } 00150 return (mgk_errno = E_NOTBUFFER); 00151 } 00152 00153 void 00154 mgk_abort_node(int code) 00155 { 00156 if (__mgk_running_node) { 00157 longjmp(__mgk_node_abort_context, code); 00158 } 00159 mgk_errno = E_NOTRUNNING; 00160 } 00161 00162 unsigned int 00163 mgk_ifany_trigger(void) 00164 { 00165 unsigned int i, tport; 00166 mgk_inport *ip; 00167 if (!__mgk_running_node) { 00168 mgk_errno = E_NOTRUNNING; 00169 return ((unsigned int)(-1)); 00170 } 00171 if (__mgk_running_node->tmode != AT_IFANY) { 00172 mgk_errno = E_BADTRIGGER; 00173 return ((unsigned int)(-1)); 00174 } 00175 mgk_errno = E_SUCCESS; 00176 tport = __mgk_running_node->last_ifany_port; 00177 for (i = 0, ip = __mgk_running_node->ins; 00178 i < __mgk_running_node->nin; 00179 i++, ip++) { 00180 tport = (tport + 1) % __mgk_running_node->nin; 00181 if (ip->links && ip->head) { 00182 __mgk_running_node->last_ifany_port = tport; 00183 return (tport); 00184 } 00185 } 00186 return (MGK_U_BADVAL); 00187 } 00188 00189 mgk_error_code 00190 mgk_trigger_mask(mgk_portmask mask) 00191 { 00192 int i; 00193 if (!__mgk_running_node) { 00194 return (mgk_errno = E_NOTRUNNING); 00195 } 00196 for (i = 0; i < itemsof(__mgk_running_node->data_mask); i++) { 00197 mask[i] = __mgk_running_node->data_mask[i]; 00198 } 00199 return (mgk_errno = E_SUCCESS); 00200 }