/*----------------------------------------------------------------------------- * dt_in_back_ex *---------------------------------------------------------------------------*/ void dt_in_back_ex(BUFFER_CB *buf, uint32_t src_spu, SPU_ADDRESS src_buf_data, uint32_t num_bytes) { OUT_DTCB out_dtcb; #if CHECK // Validate buffer alignment. pcheck(((src_buf_data & CACHE_MASK) == 0) && (num_bytes != 0)); // Debug tail pointer should be synchronized. assert(buf->otail == buf->tail); // Make sure back of buffer is free. *-in is allowed. check(buf->back_action == BUFFER_ACTION_NONE); #if !DT_ALLOW_UNALIGNED // Make sure data is aligned on qword boundary. pcheck((num_bytes & QWORD_MASK) == 0); check((buf->tail & QWORD_MASK) == 0); #endif // Make sure enough space is available. head and tail must be off by at least // 1 and cannot be non-zero offsets in the same qword. check(((buf->head - (buf->head & QWORD_MASK ? : 1) - buf->tail) & buf->mask) >= num_bytes); #endif // Set up description of region in destination buffer that source SPU will // write to. Data/space in source/destination buffers must have same offset // within cache line (128 bytes) - destination buffer does not automatically // adjust pointers if empty. out_dtcb.head = buf->tail; out_dtcb.tail = (buf->tail + num_bytes) & buf->mask; // Reserve space for data to be transferred. IF_CHECK(buf->otail = out_dtcb.tail); #if DT_ALLOW_UNALIGNED IF_CHECK(buf->back_action = BUFFER_ACTION_IN); // Save transfer size. buf->in_back_buffered_bytes = num_bytes; #else buf->tail = out_dtcb.tail; #endif // Write transfer info to source SPU. write64((uint64_t *)buf_get_dt_field_addr(spu_addr(src_spu, src_buf_data), front_in_dtcb), out_dtcb.data); }
/*----------------------------------------------------------------------------- * dt_out_front_ex *---------------------------------------------------------------------------*/ void dt_out_front_ex(BUFFER_CB *buf, uint32_t dest_spu, SPU_ADDRESS dest_buf_data, uint32_t num_bytes) { OUT_DTCB out_dtcb; #if CHECK // Validate alignment. pcheck(((dest_buf_data & CACHE_MASK) == 0) && (num_bytes != 0)); // Debug head pointer should be synchronized. assert(buf->ihead == buf->head); // Make sure front of buffer is free. out-out is disallowed. check((buf->front_action == BUFFER_ACTION_NONE) && (buf->back_action != BUFFER_ACTION_OUT)); // Make sure enough data is available. check(((buf->tail - buf->head) & buf->mask) >= num_bytes); #endif // Set up source buffer's head/tail pointers for region to be transferred. out_dtcb.head = buf->head; out_dtcb.tail = (buf->head + num_bytes) & buf->mask; buf->head = out_dtcb.tail; IF_CHECK(buf->ihead = buf->head); // Write transfer info to destination SPU. write64((uint64_t *)buf_get_dt_field_addr(spu_addr(dest_spu, dest_buf_data), back_in_dtcb), out_dtcb.data); }
static t_block *block_initial(t_block **start, const int fd) { t_block *temp; temp = *start; while (temp && temp->fd != fd) temp = temp->next; if (!temp) { IF_CHECK(temp = (t_block *)ft_memalloc(sizeof(t_block))); temp->fd = fd; IF_CHECK(temp->str = ft_strnew(0)); temp->next = (t_block *)*start; *start = temp; } return (temp); }
/*----------------------------------------------------------------------------- * ppu_finish_dt_out_front *---------------------------------------------------------------------------*/ static INLINE void ppu_finish_dt_out_front(PPU_DT_PARAMS *cmd) { BUFFER_CB *buf = cmd->buf; buf->head = (buf->head + cmd->num_bytes) & buf->mask; IF_CHECK(buf->front_action = BUFFER_ACTION_NONE); }
END_SPU_COMMAND /*----------------------------------------------------------------------------- * spu_filter_unload *---------------------------------------------------------------------------*/ DECLARE_SPU_COMMAND(filter_unload, FILTER_UNLOAD, SPU_ADDRESS filt) { cmd->filt = spu_lsa(g->spu_id, filt); IF_CHECK(cmd->detach_only = FALSE); cmd->state = 0; }
END_SPU_COMMAND /*----------------------------------------------------------------------------- * spu_filter_run *---------------------------------------------------------------------------*/ DECLARE_SPU_COMMAND(filter_run, FILTER_RUN, SPU_ADDRESS filt, uint32_t iters, uint32_t loop_iters) { cmd->filt = spu_lsa(g->spu_id, filt); cmd->iters = iters; cmd->loop_iters = loop_iters; IF_CHECK(cmd->state = 0); }
/*----------------------------------------------------------------------------- * finish_dt_in_back_ex_tail *---------------------------------------------------------------------------*/ void finish_dt_in_back_ex_tail(BUFFER_CB *buf) { uint32_t ua_bytes; check(buf->back_action == BUFFER_ACTION_IN); ua_bytes = buf->tail & QWORD_MASK; if ((ua_bytes != 0) && (buf->in_back_buffered_bytes >= ua_bytes)) { vec_stvrx(vec_lvrx(ua_bytes, &buf->back_in_dtcb_2.ua_data), buf->tail, (uint8_t *)buf->data); } IF_CHECK(buf->back_action = BUFFER_ACTION_NONE); }
/*----------------------------------------------------------------------------- * ppu_finish_dt_in_back *---------------------------------------------------------------------------*/ static INLINE void ppu_finish_dt_in_back(PPU_DT_PARAMS *cmd) { BUFFER_CB *buf = cmd->buf; #if DT_ALLOW_UNALIGNED uint32_t tail_offset = buf->tail & QWORD_MASK; // Write unaligned data to buffer. if (tail_offset != 0) { vec_stvlx(vec_lvlx(tail_offset, &buf->back_in_dtcb.ua_data), buf->tail, (uint8_t *)buf->data); } #endif buf->tail = (buf->tail + cmd->num_bytes) & buf->mask; IF_CHECK(buf->back_action = BUFFER_ACTION_NONE); }
/*----------------------------------------------------------------------------- * dt_out_front *---------------------------------------------------------------------------*/ void dt_out_front(BUFFER_CB *buf, uint32_t dest_spu, SPU_ADDRESS dest_buf_data, uint32_t num_bytes, uint32_t spu_cmd_id, uint32_t tag) { OUT_DTCB out_dtcb; PPU_DT_PARAMS *cmd; #if CHECK // Validate alignment. pcheck(((dest_buf_data & CACHE_MASK) == 0) && (num_bytes != 0)); // Debug head pointer should be synchronized. assert(buf->ihead == buf->head); // Make sure front of buffer is free. out-out is disallowed. check((buf->front_action == BUFFER_ACTION_NONE) && (buf->back_action != BUFFER_ACTION_OUT)); buf->front_action = BUFFER_ACTION_OUT; // Make sure enough data is available. check(((buf->tail - buf->head) & buf->mask) >= num_bytes); #endif // Set up source buffer's head/tail pointers for region to be transferred. out_dtcb.head = buf->head; out_dtcb.tail = (buf->head + num_bytes) & buf->mask; IF_CHECK(buf->ihead = out_dtcb.tail); // Set data transfer to wait on the SPU command ID. This must be done before // writing transfer info to SPU. cmd = ppu_dt_wait_spu(dest_spu, spu_cmd_id, tag); cmd->type = PPU_CMD_DT_OUT_FRONT; cmd->buf = buf; cmd->num_bytes = num_bytes; // Write transfer info to destination SPU. write64((uint64_t *)buf_get_dt_field_addr(spu_addr(dest_spu, dest_buf_data), back_in_dtcb), out_dtcb.data); }