/** * Write into a buffer to send via TCP. * @param devptr TCP device table entry * @param buf buffer to read octets into * @param len size of the buffer * @return count of octets written */ devcall tcpWrite(device *devptr, void *buf, uint len) { uint count = 0; uchar ch; struct tcb *tcbptr; uchar *buffer = buf; int check; tcbptr = &tcptab[devptr->minor]; /* Handle states for which data can never be sent */ wait(tcbptr->mutex); check = stateCheck(tcbptr); if (check != OK) { signal(tcbptr->mutex); return check; } signal(tcbptr->mutex); /* Put each octet from the buffer into output buffer */ while (count < len) { /* Wait for space and write as much as possible into the output * buffer; Preserve the circular buffer */ wait(tcbptr->writers); wait(tcbptr->mutex); /* Returned if changed to a state where no data can be sent */ check = stateCheck(tcbptr); if (check != OK) { signal(tcbptr->writers); return check; } while ((tcbptr->ocount < TCP_OBLEN) && (count < len)) { ch = *buffer++; tcbptr->out[((tcbptr->ostart + tcbptr->ocount) % TCP_OBLEN)] = ch; tcbptr->ocount++; count++; } /* If space remains, another writer can write */ if (tcbptr->ocount < TCP_OBLEN) { signal(tcbptr->writers); } if ((TCP_ESTAB == tcbptr->state) || (TCP_CLOSEWT == tcbptr->state)) { tcpSendData(tcbptr); } signal(tcbptr->mutex); } return count; }
static void stateSet(IceTEnum pname, IceTSizeType num_entries, IceTEnum type, const IceTVoid *data) { IceTSizeType type_width = icetTypeWidth(type); void *datacopy = stateAllocate(pname, num_entries, type, icetGetState()); stateCheck(pname, icetGetState()); memcpy(datacopy, data, num_entries * type_width); stateCheck(pname, icetGetState()); }
void icetGetIntegerv(IceTEnum pname, IceTInt *params) { struct IceTStateValue *value = icetGetState() + pname; int i; stateCheck(pname, icetGetState()); copyArray(IceTInt, params, value->type, value->data, value->num_entries); }
static void *icetUnsafeStateGet(IceTEnum pname, IceTEnum type) { stateCheck(pname, icetGetState()); if (icetGetState()[pname].type != type) { icetRaiseError("Mismatched types in unsafe state get.", ICET_SANITY_CHECK_FAIL); return NULL; } return icetGetState()[pname].data; }
void icetGetEnumv(IceTEnum pname, IceTEnum *params) { struct IceTStateValue *value = icetGetState() + pname; int i; stateCheck(pname, icetGetState()); if ((value->type == ICET_FLOAT) || (value->type == ICET_DOUBLE)) { icetRaiseError("Floating point values cannot be enumerations.", ICET_BAD_CAST); } copyArray(IceTEnum, params, value->type, value->data, value->num_entries); }
void icetStateCheckMemory(void) { #ifdef ICET_STATE_CHECK_MEM IceTState state = icetGetState(); IceTEnum pname; for (pname = ICET_STATE_ENGINE_START; pname < ICET_STATE_ENGINE_END; pname++) { stateCheck(pname, state); } #endif }
static ixx getTileState(doeE env, dcPathFiller pf) { dcPathFillerData* p = (dcPathFillerData*)pf; Run r; ixx lscount; LeftSide ls; if (!stateCheck(p, setOutputAreaDone)) { doeError_set(env, dcPRError, dcPRError_UNEX_getTileState); return -1; } /* "fast output" situations are never trivial */ if (p->fastOutput) { return dcPathFiller_TILE_IS_GENERAL; } /* two conditions must be met for a tile to be trivial: 1. the tile itself must contain no runs 2. the list lsEffects must consist exclusively of "full height" left sides */ r = p->tileRuns[p->tileXI][p->tileYI]; if (r != NULL) { return dcPathFiller_TILE_IS_GENERAL; } lscount = 0; for (ls = p->lsEffects; ls != NULL; ls = ls->next) { if (ls->y0 == 0.0F && ls->y1 == p->rowHTiF) { lscount++; continue; } if (ls->y1 == 0.0F && ls->y0 == p->rowHTiF) { lscount--; continue; } return dcPathFiller_TILE_IS_GENERAL; } if (p->fillmode == dcPathFiller_EOFILL) lscount &= 1; return (lscount != 0)? dcPathFiller_TILE_IS_ALL_1 : dcPathFiller_TILE_IS_ALL_0; }
static void stateFree(IceTEnum pname, IceTState state) { stateCheck(pname, state); if ((state[pname].type != ICET_NULL) && (state[pname].num_entries > 0)) { #ifdef ICET_STATE_CHECK_MEM free(STATE_DATA_PRE_PADDING(pname, state)); #else free(state[pname].data); #endif state[pname].type = ICET_NULL; state[pname].num_entries = 0; state[pname].data = NULL; state[pname].mod_time = 0; } }
static void setFillMode(doeE env, dcPathFiller pf, ixx fillmode) { dcPathFillerData* p = (dcPathFillerData*)pf; if (stateCheck(p, setFillModeDone)) { doeError_set(env, dcPRError, dcPRError_UNEX_setUsage); return; } if (fillmode != dcPathFiller_NZFILL && fillmode != dcPathFiller_EOFILL) { doeError_set(env, dcPRError, dcPRError_UNK_fillmode); return; } p->redundantReset = FALSE; p->fillmode = fillmode; stateSet(p, setFillModeDone); }
void icetGetPointerv(IceTEnum pname, IceTVoid **params) { struct IceTStateValue *value = icetGetState() + pname; int i; stateCheck(pname, icetGetState()); if (value->type == ICET_NULL) { char msg[256]; sprintf(msg, "No such parameter, 0x%x.", (int)pname); icetRaiseError(msg, ICET_INVALID_ENUM); } if (value->type != ICET_POINTER) { char msg[256]; sprintf(msg, "Could not cast value for 0x%x.", (int)pname); icetRaiseError(msg, ICET_BAD_CAST); } copyArrayGivenCType(IceTVoid *, params, IceTVoid *, value->data, value->num_entries); }
void icetStateDump(void) { IceTEnum pname; IceTState state; state = icetGetState(); printf("State dump:\n"); for (pname = ICET_STATE_ENGINE_START; pname < ICET_STATE_ENGINE_END; pname++) { stateCheck(pname, state); if (state->type != ICET_NULL) { printf("param = 0x%x\n", pname); printf("type = 0x%x\n", (int)state->type); printf("num_entries = %d\n", (int)state->num_entries); printf("data = %p\n", state->data); printf("mod = %d\n", (int)state->mod_time); } state++; } }
static void writeAlpha16( doeE env, dcPathFiller pf, u16* alpha, i32 xstride, i32 ystride, i32 pix0offset) { dcPathFillerData* p = (dcPathFillerData*)pf; dcLLFiller ll; if (!stateCheck(p, setOutputAreaDone)) { doeError_set(env, dcPRError, dcPRError_UNEX_writeAlpha); return; } if (alpha == NULL || xstride <= 0 || ystride <= 0 || pix0offset < 0) { doeError_set(env, dcPRError, dcPRError_BAD_alphadest); return; } ll = dcLLFiller_get(env); if (doeError_occurred(env)) return; if (p->fastOutput) { FastOutputPC fopc = p->fastOutputPC; dcFastPathProducer fpp = p->thisFPP; (*ll)->setParams(env, ll, p->fillmode, p->outW, p->outH); (*fopc)->setUpAlpha16( env, fopc, ll, -p->outLoX, -p->outLoY, alpha, xstride, ystride, pix0offset); (*fpp)->sendTo(env, fpp, (dcPathConsumer)fopc); } else { i32 tilew = MIN(p->outW - ((p->tileXI - 1) << dcPathFiller_tileSizeL2S), dcPathFiller_tileSize); (*ll)->setParams(env, ll, p->fillmode, tilew, p->rowH); sendTileToLLFiller(env, pf, ll); (*ll)->writeAlpha16(env, ll, alpha, xstride, ystride, pix0offset); } dcLLFiller_release(env, ll); nextTile(env,pf); }
/** * Read into a buffer from TCP. * @param devptr TCP device table entry * @param buf buffer to read octets into * @param len size of the buffer * @return count of octets read */ devcall tcpRead(device *devptr, void *buf, uint len) { int count = 0; struct tcb *tcbptr; int check; char *buffer = buf; tcbptr = &tcptab[devptr->minor]; wait(tcbptr->mutex); /* Handle states for which no data will ever be received */ check = stateCheck(tcbptr); if (check != OK) { return SYSERR; // return check; } signal(tcbptr->mutex); /* Put each octet into the buffer from the input buffer */ while (count < len) { /* Wait for input or FIN */ wait(tcbptr->readers); wait(tcbptr->mutex); /* Return if changed to a state where no data will ever be recvd */ check = stateCheck(tcbptr); if (check != OK) { return SYSERR; // return check; } /* Read as much as possible from the input buffer * Preserve the circular buffer */ while ((tcbptr->icount > 0) && (count < len)) { *buffer++ = tcbptr->in[tcbptr->istart]; tcbptr->imark[tcbptr->istart] = FALSE; tcbptr->istart = (tcbptr->istart + 1) % TCP_IBLEN; tcbptr->icount--; count++; } #ifdef TCP_GRACIOUSACK /* Send gracious acknowledgement if window has increaed */ if (seqlte(tcbptr->rcvwnd, tcbptr->rcvnxt)) { if (tcpSendWindow(tcbptr) > 0) { tcpSendAck(tcbptr); } } #endif /* If data remains, another reader can read */ if ((tcbptr->icount > 0) && (semcount(tcbptr->readers) < 1)) { signal(tcbptr->readers); } signal(tcbptr->mutex); } return count; }
IceTSizeType icetStateGetNumEntries(IceTEnum pname) { stateCheck(pname, icetGetState()); return icetGetState()[pname].num_entries; }
static void nextTile(doeE env, dcPathFiller pf) { dcPathFillerData* p = (dcPathFillerData*)pf; if (!stateCheck(p, setOutputAreaDone)) { doeError_set(env, dcPRError, dcPRError_UNEX_nextTile); return; } if (p->fastOutput) { stateReset(p, setOutputAreaDone); return; } /* advance x tile index */ p->tileXI++; if (p->tileXI > p->outWTi) { /* tileXI in [1, outWITi] */ /* clear left side effects */ LeftSide_releaseList(env, p->lsEffects); p->lsEffects = NULL; p->tileXI = 1; /* 0 is left-open tile */ p->tileYI++; if (p->tileYI >= p->outHTi) { stateReset(p, setOutputAreaDone); return; } p->rowH = p->outH - (p->tileYI << dcPathFiller_tileSizeL2S); if (p->rowH > dcPathFiller_tileSize) p->rowH = dcPathFiller_tileSize; p->rowHTiF = (f32)p->rowH / dcPathFiller_tileSizeF; } /* update left side effects */ { Run r; for (r = p->tileRuns[p->tileXI - 1][p->tileYI]; r != NULL; r = r->next) { f32 rspy0 = r->rspy0; f32 rspy1 = r->rspy1; LeftSide ls, lslink, tmp; /* no rightside projection? */ if (rspy1 == rspyImpossibleTss) { continue; } /* constrain [rsp] to the interval [0,rowHTiF] */ if (rspy0 < 0.0F) rspy0 = 0.0F; if (rspy1 < 0.0F) rspy1 = 0.0F; if (rspy0 > p->rowHTiF) rspy0 = p->rowHTiF; if (rspy1 > p->rowHTiF) rspy1 = p->rowHTiF; /* for each [ls] in [lsEffects] check whether [rsp] extends it; if so, modify [rsp] accordingly and remove [ls] from [lsEffects] */ ls = p->lsEffects; lslink = NULL; while (ls != NULL) { if (rspy1 == ls->y0 || rspy0 == ls->y1) { if (rspy1 == ls->y0) rspy1 = ls->y1; else rspy0 = ls->y0; if (lslink == NULL) p->lsEffects = ls->next; else lslink->next = ls->next; tmp = ls->next; ls->next = NULL; LeftSide_releaseList(env, ls); ls = tmp; } else { lslink = ls; ls = ls->next; } } /* if [rsp] still produces an effect, insert it in [lsEffect] */ if (rspy0 != rspy1) { ls = LeftSide_create(env, p->poolLeftSide); if (ls == NULL) return; ls->y0 = rspy0; ls->y1 = rspy1; ls->next = p->lsEffects; p->lsEffects = ls; } } } }
IceTTimeStamp icetStateGetTime(IceTEnum pname) { stateCheck(pname, icetGetState()); return icetGetState()[pname].mod_time; }
IceTEnum icetStateGetType(IceTEnum pname) { stateCheck(pname, icetGetState()); return icetGetState()[pname].type; }
static IceTVoid *stateAllocate(IceTEnum pname, IceTSizeType num_entries, IceTEnum type, IceTState state) { IceTVoid *buffer; stateCheck(pname, state); if ( (num_entries == state[pname].num_entries) && (type == state[pname].type) ) { /* Return the current buffer. */ state[pname].mod_time = icetGetTimeStamp(); buffer = state[pname].data; } else if (num_entries > 0) { stateFree(pname, state); /* Create a new buffer. */ buffer = malloc(STATE_DATA_ALLOCATE(type, num_entries)); if (buffer == NULL) { icetRaiseError("Could not allocate memory for state variable.", ICET_OUT_OF_MEMORY); return NULL; } #ifdef ICET_STATE_CHECK_MEM /* Skip past padding. */ buffer = (IceTByte *)buffer + STATE_PADDING_SIZE; #endif state[pname].type = type; state[pname].num_entries = num_entries; state[pname].data = buffer; state[pname].mod_time = icetGetTimeStamp(); #ifdef ICET_STATE_CHECK_MEM /* Set padding data. */ { IceTSizeType i; IceTByte *padding; padding = STATE_DATA_PRE_PADDING(pname, state); for (i = 0; i < STATE_PADDING_SIZE; i++) { padding[i] = g_pre_padding[i]; } padding = STATE_DATA_POST_PADDING(pname, state); for (i = 0; i < STATE_PADDING_SIZE; i++) { padding[i] = g_post_padding[i]; } } #endif } else { /* num_entries <= 0 */ buffer = NULL; state[pname].type = type; state[pname].num_entries = 0; state[pname].data = buffer; state[pname].mod_time = icetGetTimeStamp(); } #ifdef ICET_STATE_CHECK_MEM memset(buffer, 0xDC, STATE_DATA_WIDTH(type, num_entries)); #endif return buffer; }