int dthread_port_send_term(dthread_t* thr, dthread_t* source, ErlDrvTermData target, ErlDrvTermData* spec, int len) { if (thr->smp_support) return DSEND_TERM(thr, target, spec, len); else { dmessage_t* mp; int xsz = dterm_dyn_size(spec, len); if (xsz < 0) return -1; mp = dmessage_create(DTHREAD_SEND_TERM,(char*)spec, len*sizeof(ErlDrvTermData)); if (xsz > 0) { char* xptr = DALLOC(xsz); if ((dterm_dyn_copy((ErlDrvTermData*)mp->buffer, len, xptr)) == NULL) return -1; mp->udata = xptr; mp->release = release_xptr_func; } mp->to = target; // dterm_dump(stderr, (ErlDrvTermData*) mp->buffer, mp->used / sizeof(ErlDrvTermData)); return dthread_send(thr, source, mp); } }
dthread_t* dthread_start(ErlDrvPort port, void* (*func)(void* arg), void* arg, int stack_size) { ErlDrvThreadOpts* opts = NULL; dthread_t* thr = NULL; if (!(thr = DALLOC(sizeof(dthread_t)))) return 0; if (dthread_init(thr, port) < 0) goto error; if (!(opts = erl_drv_thread_opts_create("dthread_opts"))) goto error; opts->suggested_stack_size = stack_size; thr->arg = arg; if (erl_drv_thread_create("dthread", &thr->tid, func, thr, opts) < 0) goto error; erl_drv_thread_opts_destroy(opts); return thr; error: dthread_finish(thr); if (opts) erl_drv_thread_opts_destroy(opts); dthread_finish(thr); DFREE(thr); return 0; }
// auxillary space void* dterm_link_alloc_data(dterm_t* p, size_t size) { dterm_link_t* lp = DALLOC(sizeof(dterm_link_t)+size); lp->next = p->head; p->head = lp; return (void*) &lp->data[0]; }
// dynamic allocation of dterm_t structure, the data part is // can be less the DTERM_FIXED in this case dterm_t* dterm_alloc(size_t size) { size_t sz = (sizeof(dterm_t) - DTERM_FIXED*sizeof(ErlDrvTermData)) + size*sizeof(ErlDrvTermData); dterm_t* p; if ((p = DALLOC(sz)) != NULL) { p->dyn_alloc = 1; p->dyn_size = size; p->base = p->data; p->ptr = p->data; p->ptr_end = p->data + p->dyn_size; p->head = 0; p->mark = 0; } return p; }
int dterm_expand(dterm_t* p, size_t n) { ErlDrvTermData* new_base; size_t old_size = dterm_allocated_size(p); size_t new_size = old_size + n; size_t old_sz = old_size * sizeof(ErlDrvTermData); size_t new_sz = new_size * sizeof(ErlDrvTermData); ptrdiff_t offset = p->ptr - p->base; // offset of ptr if (p->base == p->data) { if ((new_base = DALLOC(new_sz)) == NULL) return 0; memcpy(new_base, p->base, old_sz); } else if ((new_base = DREALLOC(p->base, new_sz)) == NULL) return 0; p->base = new_base; p->ptr = p->base + offset; p->ptr_end = new_base + new_size; p->base = new_base; return 1; }
/*------------------------------------------------------------------- * init_xfer -- initialize the transfer tables by transferring coarse * control points from an ICC ResponseRecord * and interpolating the fine tables from them; * returns +1 for success, -1 for failure to * allocate memory for coarse table *------------------------------------------------------------------- */ PTErr_t init_xfer ( xfer_p xferp, ResponseRecord_p rrp) { PTErr_t PTErr = KCP_SUCCESS; double val; /* input variables */ KpInt32_t numcoarse; /* number of input control points */ double_p coarse[2]; /* storage for control points */ KpInt32_t i; /* control-point index */ KpInt32_t hint; KpUInt16_t *pCurveData = NULL; /* Verify inputs: */ if (xferp == (xfer_p)NULL) return KCP_SYSERR_0; if (rrp == (ResponseRecord_p)NULL) return KCP_SYSERR_0; if (PARA_TYPE_SIG == rrp->TagSig) { pCurveData = (KpUInt16_p) allocBufferPtr (MFV_CURVE_TBL_ENT*sizeof(KpUInt16_t)); /* get memory for curve data */ if (NULL == pCurveData) { return KCP_NO_MEMORY; } makeCurveFromPara (rrp->ParaFunction, rrp->ParaParams, pCurveData, MFV_CURVE_TBL_ENT); rrp->CurveCount = MFV_CURVE_TBL_ENT; rrp->CurveData = pCurveData; } if (rrp->CurveCount < 2) { PTErr = KCP_SYSERR_0; goto ErrOut; } if (rrp->CurveData == (KpUInt16_p)NULL) { PTErr = KCP_SYSERR_0; goto ErrOut; } /* Allocate space for coarse tables: */ numcoarse = rrp->CurveCount - 1; /* skip zero entry to avoid infinity in logarithm */ coarse[0] = (double_p)ALLOC (numcoarse, sizeof(double)); if (coarse[0] == NULL) { PTErr = KCP_NO_MEMORY; goto ErrOut; } coarse[1] = (double_p)ALLOC (numcoarse, sizeof(double)); if (coarse[1] == NULL) { DALLOC (coarse[0]); /* release storage */ PTErr = KCP_NO_MEMORY; goto ErrOut; } /* Build coarse tables from ResponseRecord: */ for (i = 0; i < numcoarse; i++) { val = (double)(i + 1) / (double)numcoarse; /* skip zero to avoid infinite log */ coarse[0][i] = -log10 (val); val = (double)rrp->CurveData[i + 1] / SCALEDOT16; val = MAX (val, 1.0e-12); /* clip to avoid infinite log */ coarse[1][i] = -log10 (val); } /* Build fine tables by interpolating in coarse tables: */ hint = 1; for (i = 0; i < NUMFINE; i++) /* spaced code values */ { double code; code = (double)i * 2.4 / (double)(NUMFINE - 1); /* equally spaced in [0, 2.4] */ xferp->nonlinear[i] = code; xferp->linear[i] = f4l (code, coarse[0], coarse[1], numcoarse, &hint); } /* Delete coarse tables: */ DALLOC (coarse[0]); DALLOC (coarse[1]); ErrOut: if (NULL != pCurveData) { freeBufferPtr (pCurveData); } return PTErr; }