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 }