summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/wsbm_cs.c36
-rw-r--r--src/wsbm_cs.h9
-rw-r--r--src/wsbm_driver.h11
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 *