diff options
-rw-r--r-- | src/wsbm_cs.c | 36 | ||||
-rw-r--r-- | src/wsbm_cs.h | 9 | ||||
-rw-r--r-- | src/wsbm_driver.h | 11 |
3 files changed, 40 insertions, 16 deletions
diff --git a/src/wsbm_cs.c b/src/wsbm_cs.c index 177bcb8..98eae6b 100644 --- a/src/wsbm_cs.c +++ b/src/wsbm_cs.c @@ -44,7 +44,7 @@ wsbmBOStorage(struct _WsbmBufferObject *buf); struct _ValidateList { - const struct _WsbmDriver *driver; + const struct _WsbmVNodeDriver *driver; unsigned numTarget; unsigned numCurrent; unsigned numOnList; @@ -184,7 +184,7 @@ wsbmPot(unsigned int val) static int validateCreateList(int numTarget, struct _ValidateList *list, - const struct _WsbmDriver *driver) + const struct _WsbmVNodeDriver *driver) { int i; unsigned int shift = wsbmPot(numTarget); @@ -244,8 +244,8 @@ validateResetList(struct _ValidateList *list) struct _WsbmBufferList * wsbmBOCreateList(int target, int hasKernelBuffers, - const struct _WsbmDriver *kernelDriver, - const struct _WsbmDriver *userDriver) + const struct _WsbmVNodeDriver *kernelDriver, + const struct _WsbmVNodeDriver *userDriver) { struct _WsbmBufferList *list = calloc(sizeof(*list), 1); int ret; @@ -317,11 +317,22 @@ wsbmAddValidateItem(struct _ValidateList *list, void *buf, uint64_t flags, } if (!cur) { + int ret; + cur = validateListAddNode(list, buf, hash, flags, mask); if (!cur) return -ENOMEM; + + ret = cur->driver->init(cur); + if (ret != 0) { + WSBMLISTDEL(&cur->head); + WSBMLISTDEL(&cur->hashHead); + list->numOnList--; + WSBMLISTADD(&cur->head, &list->free); + return ret; + } + *newItem = 1; - cur->driver->clear(cur); } else { uint64_t set_flags = flags & mask; uint64_t clr_flags = (~flags) & mask; @@ -342,9 +353,18 @@ wsbmAddValidateItem(struct _ValidateList *list, void *buf, uint64_t flags, return -EINVAL; } - cur->set_flags |= set_flags; - cur->clr_flags |= clr_flags; - cur->set_flags &= ~(cur->clr_flags); + set_flags |= cur->set_flags; + clr_flags |= cur->clr_flags; + set_flags &= ~clr_flags; + + if (cur->driver->reaccount && (set_flags != cur->set_flags)) { + int ret = cur->driver->reaccount(cur, set_flags, clr_flags); + if (ret) + return ret; + } + + cur->set_flags = set_flags; + cur->clr_flags = clr_flags; } *itemLoc = cur->listItem; if (pnode) diff --git a/src/wsbm_cs.h b/src/wsbm_cs.h index 511edce..a8f3029 100644 --- a/src/wsbm_cs.h +++ b/src/wsbm_cs.h @@ -38,10 +38,11 @@ struct _ValidateList; #define WSBM_PLACEMENT_MASK ((uint64_t) 0xFFFFFFFFULL) -extern struct _WsbmBufferList *wsbmBOCreateList(int target, - int hasKernelBuffers, - const struct _WsbmDriver *kernelDriver, - const struct _WsbmDriver *userDriver); +extern struct _WsbmBufferList * +wsbmBOCreateList(int target, + int hasKernelBuffers, + const struct _WsbmVNodeDriver *kernelDriver, + const struct _WsbmVNodeDriver *userDriver); extern int wsbmBOResetList(struct _WsbmBufferList *list); extern int wsbmBOAddListItem(struct _WsbmBufferList *list, diff --git a/src/wsbm_driver.h b/src/wsbm_driver.h index b78549b..8eebf7e 100644 --- a/src/wsbm_driver.h +++ b/src/wsbm_driver.h @@ -87,11 +87,14 @@ extern struct _WsbmThreadFuncs *wsbmCurThreadFunc; #define WSBM_COND_BROADCAST(_cond) \ (_cond)->func->condBroadcast(_cond); -struct _WsbmDriver +struct _WsbmVNodeDriver { - struct _ValidateNode *(*alloc) (const struct _WsbmDriver *); + int driver_id; + struct _ValidateNode *(*alloc) (const struct _WsbmVNodeDriver *); void (*free) (struct _ValidateNode *); - void (*clear) (struct _ValidateNode *); + int (*init) (struct _ValidateNode *); + int (*reaccount) (struct _ValidateNode *, uint64_t new_set_flags, + uint64_t new_clr_flags); }; extern struct _WsbmVNodeFuncs *wsbmCurVNodeFunc; @@ -109,7 +112,7 @@ struct _ValidateNode uint64_t set_flags; uint64_t clr_flags; void *buf; - const struct _WsbmDriver *driver; + const struct _WsbmVNodeDriver *driver; }; static inline struct _WsbmVNodeFuncs * |