Commit be88fe46 authored by Swann Perarnau's avatar Swann Perarnau

[feature] make scratchpad track its own tiles

Move the scratchpad tiles into an internal concern:
- the scratchpad does the allocation
- the scratchpad tracks available tiles internally
- the user can ask for the scratch baseptr.

This is necessary to abstract move-based scratchs, and to remove from the
user responsibility of maintaining tiling and baseptr tracking.

We still fail-hard when tiles are not available, and the design is not
thread safe. But we are getting there.
parent 73b57ae5
......@@ -664,6 +664,7 @@ struct aml_scratch_ops {
struct aml_scratch_request *req);
int (*wait_request)(struct aml_scratch_data *scratch,
struct aml_scratch_request *req);
void *(*baseptr)(struct aml_scratch_data *scratch);
};
struct aml_scratch {
......@@ -681,7 +682,7 @@ int aml_scratch_wait(struct aml_scratch *scratch,
struct aml_scratch_request *req);
int aml_scratch_cancel(struct aml_scratch *scratch,
struct aml_scratch_request *req);
void* aml_scratch_baseptr(struct aml_scratch *scratch);
/*******************************************************************************
* Sequential scratchpad API:
* Scratchpad uses calling thread to trigger dma movements.
......@@ -701,11 +702,14 @@ struct aml_scratch_request_seq {
};
struct aml_scratch_seq_data {
struct aml_area *srcarea, *scratcharea;
struct aml_tiling *srctiling, *scratchtiling;
struct aml_area *src_area, *sch_area;
struct aml_tiling *tiling;
struct aml_dma *dma;
size_t nbrequests;
struct aml_scratch_request_seq *requests;
size_t sch_nbtiles;
void * sch_ptr;
int *tilemap;
};
struct aml_scratch_seq_ops {
......@@ -715,6 +719,7 @@ struct aml_scratch_seq_ops {
struct aml_scratch_request_seq **req);
int (*remove_request)(struct aml_scratch_seq_data *scratch,
struct aml_scratch_request_seq **req);
int (*tilemap_find)(struct aml_scratch_seq_data *scratch, int tid);
};
struct aml_scratch_seq {
......
......@@ -79,3 +79,9 @@ int aml_scratch_wait(struct aml_scratch *scratch, struct aml_scratch_request *re
assert(req != NULL);
return scratch->ops->wait_request(scratch->data, req);
}
void *aml_scratch_baseptr(struct aml_scratch *scratch)
{
assert(scratch != NULL);
return scratch->ops->baseptr(scratch->data);
}
......@@ -72,16 +72,30 @@ int aml_scratch_seq_remove_request(struct aml_scratch_seq_data *data,
return 0;
}
int aml_scratch_seq_tilemap_find(struct aml_scratch_seq_data *data, int tid)
{
assert(data != NULL);
for(int i = 0; i < data->sch_nbtiles; i++)
{
if(data->tilemap[i] == tid)
return i;
}
return -1;
}
struct aml_scratch_seq_ops aml_scratch_seq_inner_ops = {
aml_scratch_seq_doit,
aml_scratch_seq_add_request,
aml_scratch_seq_remove_request,
aml_scratch_seq_tilemap_find,
};
/*******************************************************************************
* Public API
******************************************************************************/
/* TODO: not thread-safe */
int aml_scratch_seq_create_request(struct aml_scratch_data *d,
struct aml_scratch_request **r,
int type, va_list ap)
......@@ -110,13 +124,15 @@ int aml_scratch_seq_create_request(struct aml_scratch_data *d,
scratchid = va_arg(ap, int);
/* find destination tile */
//scratch->ops.scratch2src(scratch->data, scratchid, srcid);
*srcid = scratchid;
assert(scratchid < scratch->data.sch_nbtiles);
int slot = scratch->data.tilemap[scratchid];
assert(slot != -1);
*srcid = slot;
/* init request */
aml_scratch_request_seq_init(req, type, scratch->data.srctiling,
aml_scratch_request_seq_init(req, type, scratch->data.tiling,
srcptr, *srcid,
scratch->data.scratchtiling,
scratch->data.tiling,
scratchptr, scratchid);
}
else if(type == AML_SCRATCH_REQUEST_TYPE_PULL)
......@@ -132,14 +148,18 @@ int aml_scratch_seq_create_request(struct aml_scratch_data *d,
srcid = va_arg(ap, int);
/* find destination tile */
//scratch->ops.src2scratch(scratch->data, scratchid, srcid);
*scratchid = srcid;
int slot = scratch->ops.tilemap_find(&scratch->data, srcid);
if(slot == -1)
slot = scratch->ops.tilemap_find(&scratch->data, -1);
assert(slot != -1);
scratch->data.tilemap[slot] = srcid;
*scratchid = slot;
/* init request */
aml_scratch_request_seq_init(req, type,
scratch->data.scratchtiling,
scratch->data.tiling,
scratchptr, *scratchid,
scratch->data.srctiling,
scratch->data.tiling,
srcptr, srcid);
}
scratch->ops.doit(&scratch->data, req);
......@@ -162,6 +182,10 @@ int aml_scratch_seq_destroy_request(struct aml_scratch_data *d,
aml_dma_cancel(scratch->data.dma, req->dma_req);
aml_scratch_request_seq_destroy(req);
scratch->ops.remove_request(&scratch->data, &req);
if(req->type == AML_SCRATCH_REQUEST_TYPE_PUSH)
scratch->data.tilemap[req->srcid] = -1;
else if(req->type == AML_SCRATCH_REQUEST_TYPE_PULL)
scratch->data.tilemap[req->dstid] = -1;
return 0;
}
......@@ -180,13 +204,25 @@ int aml_scratch_seq_wait_request(struct aml_scratch_data *d,
/* destroy a completed request */
aml_scratch_request_seq_destroy(req);
scratch->ops.remove_request(&scratch->data, &req);
if(req->type == AML_SCRATCH_REQUEST_TYPE_PUSH)
scratch->data.tilemap[req->srcid] = -1;
else if(req->type == AML_SCRATCH_REQUEST_TYPE_PULL)
scratch->data.tilemap[req->dstid] = -1;
return 0;
}
void *aml_scratch_seq_baseptr(struct aml_scratch_data *d)
{
assert(d != NULL);
struct aml_scratch_seq *scratch = (struct aml_scratch_seq *)d;
return scratch->data.sch_ptr;
}
struct aml_scratch_ops aml_scratch_seq_ops = {
aml_scratch_seq_create_request,
aml_scratch_seq_destroy_request,
aml_scratch_seq_wait_request,
aml_scratch_seq_baseptr,
};
/*******************************************************************************
......@@ -220,18 +256,27 @@ int aml_scratch_seq_vinit(struct aml_scratch *d, va_list ap)
scratch->ops = aml_scratch_seq_inner_ops;
scratch->data.scratcharea = va_arg(ap, struct aml_area *);
scratch->data.scratchtiling = va_arg(ap, struct aml_tiling *);
scratch->data.srcarea = va_arg(ap, struct aml_area *);
scratch->data.srctiling = va_arg(ap, struct aml_tiling *);
scratch->data.sch_area = va_arg(ap, struct aml_area *);
scratch->data.src_area = va_arg(ap, struct aml_area *);
scratch->data.dma = va_arg(ap, struct aml_dma *);
scratch->data.tiling = va_arg(ap, struct aml_tiling *);
scratch->data.sch_nbtiles = va_arg(ap, size_t);
/* allocate request array */
scratch->data.nbrequests = va_arg(ap, size_t);
scratch->data.requests = calloc(scratch->data.nbrequests,
sizeof(struct aml_scratch_request_seq));
for(int i = 0; i < scratch->data.nbrequests; i++)
scratch->data.requests[i].type = AML_SCRATCH_REQUEST_TYPE_INVALID;
/* scratch init */
scratch->data.tilemap = calloc(scratch->data.sch_nbtiles, sizeof(int));
for(int i = 0; i < scratch->data.sch_nbtiles; i++)
scratch->data.tilemap[i] = -1;
size_t tilesize = aml_tiling_tilesize(scratch->data.tiling, 0);
scratch->data.sch_ptr = aml_area_calloc(scratch->data.sch_area,
scratch->data.sch_nbtiles,
tilesize);
return 0;
}
int aml_scratch_seq_init(struct aml_scratch *d, ...)
......@@ -248,5 +293,7 @@ int aml_scratch_seq_destroy(struct aml_scratch *d)
{
struct aml_scratch_seq *scratch = (struct aml_scratch_seq *)d->data;
free(scratch->data.requests);
free(scratch->data.tilemap);
aml_area_free(scratch->data.sch_area, scratch->data.sch_ptr);
return 0;
}
......@@ -39,16 +39,13 @@ int main(int argc, char *argv[])
/* allocate some memory */
src = aml_area_malloc(&area, TILESIZE*PAGE_SIZE*NBTILES);
assert(src != NULL);
dst = aml_area_malloc(&area, TILESIZE*PAGE_SIZE*NBTILES);
assert(dst != NULL);
memset(src, 42, TILESIZE*PAGE_SIZE*NBTILES);
memset(dst, 24, TILESIZE*PAGE_SIZE*NBTILES);
/* create scratchpad */
assert(!aml_scratch_seq_init(&scratch, &area, &tiling, &area, &tiling,
&dma, NBTILES));
assert(!aml_scratch_seq_init(&scratch, &area, &area, &dma, &tiling,
NBTILES, NBTILES));
dst = aml_scratch_baseptr(&scratch);
/* move some stuff */
for(int i = 0; i < NBTILES; i++)
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment