Subject: [sv-cc] Final proposal for user data management
From: Warmke, Doug (doug_warmke@mentorg.com)
Date: Thu Mar 27 2003 - 09:53:48 PST
Team,
After lots of round-the-clock phone calls and mails,
we seem to have converged on an acceptable scheme for
handling user data. All use models that we've considered
appear to be addressed, and "separation of concerns"
appears to be satisfied.
Problem Summary:
We need to give user code relatively fine-grained control
over addressing user data. Some use models would like to
share user data across a set of context import functions
in the same declarative scope. Other use models would like
to have separate user data for each ontext import function.
Both shared and separate user data should be allowable using
a simple-to-understand API and semantics.
Separate user data is mandatory for handling context import
functions provided by different IP authors, since such functions
couldn't possibly know of each other's existence in the same
declarative scope.
In order to support separate user data storage, a secondary
key is needed in addition to the context import function's scope.
Together, the two keys fully determine the address of user data.
If the same secondary key is used for different context import
functions, then all such functions will effectively share user
data. If different keys are used, then the functions will have
unique user data storage. The scheme provides no way to share
user data across different scopes.
Here is a new put/get user data API with primary and secondary keys:
void svPutUserData(svScope scope, void* userKey, void* userData);
void* svGetUserData(svScope scope, void* userKey);
int svIsUserKeyInUse(void* userKey);
Note that there are no more ID's of any type retrieved by the system.
Recall, all previous proposals (except maybe Andrzej's) required such
an ID for use as a secondary key. We have been through:
1) const char* "functionName"
2) svFunctionScope
3) int svFunctionId
All of these were somewhat controversial, complex or confusing.
Controversial in that there was a trade-off between performance and
usability which appeared unresolvable due to different opinions.
Complex due to constraints upon the user for static storage of the
system-provided ID's. Also complex due to constraints upon the
implementation for generating a rational set of ID's in all cases.
Confusing due to all of the above.
This new proposal only has one drawback. In the case of multiple
context import functions declared in the same scope, there will need
to be some kind of dynamic search based on secondary key.
Joao's contention is that such a search will be relatively cheap.
In most cases there is only one context import function per scope.
In other cases there will be a small number, say 2 or 3 per scope.
In such cases a simple linear search can be used to determine the
correct stored data based on key. It does seem cheap.
In cases where lots of context import functions in a given scope,
the implementation can elect to use a more complex search criteria,
such as a binary tree search or a hash. We could advise users
that there is some cost to using many secondary user data keys
for independent context import functions in the same scope.
Later today (just after our meeting) I will write this up in more
formal LRM form. The 3 API function return values and behavior
will be described in detail.
Here is John's example recoded to use this new API.
Note that the svIsUserKeyInUse() function is not needed here,
since we have guaranteed that the user key will be unique by
merit of C linkage artifacts (i.e. there can't be more than
one identical symbol address in a given C program image).
This use model is the expected mainstream method by which
users will generate secondary keys.
SV Side:
[...]
C Side:
// Define the function and model class on the C++ side:
class MyCModel {
private:
int locallyMapped(int portID); // Does something interesting...
public:
// Constructor
MyCModel(const char* instancePath) {
svScope scope = svGetScopeFromName(instancePath);
// Associate "this" with the corresponding SV scope for
// fast retrieval during runtime.
svPutUserData(scope, (void*)MyCFunc, this);
}
friend int MyCFunc(int portID);
};
// Implementation of context import function callable in SV
int MyCFunc(int portID) {
// Retrieve SV module instance scope (i.e. this function's context).
svScope scope = svGetScope();
// Retrieve and make use of this function's user data stored in SV scope
MyCModel* me = (MyCModel*)svGetUserData(scope, (void*)MyCFunc);
return me->locallyMapped(portID);
}
Thanks and regards,
Doug
This archive was generated by hypermail 2b28 : Thu Mar 27 2003 - 09:55:06 PST