Instance Proxies [message #1727866] |
Mon, 28 March 2016 17:27 |
Chris H Messages: 11 Registered: September 2014 |
Junior Member |
|
|
Thanks to a tip from James Lockwood, I was able to create generic peripheral drivers that could reference multiple modules with the same target code implementation. To do this I created an interface module for the driver in question and one or more concrete implementations that inherit from the interface. In the target code a call is made to the interface functions with instance handles declared in the Instance_State struct. An example implementation for UART is contained in this thread. This works due to a vtable like implementation:
IUART.h
static inline xdc_Int drivers_IUART_read( drivers_IUART_Handle __inst, xdc_Void *buffer, xdc_SizeT size )
{
return __inst->__fxns->read((void*)__inst, buffer, size);
}
While this is perfectly acceptable it does rely on function pointers. The compiler will not be able to optimize this call so you incur additional overhead. This is in contrast to a proxy/delegate implementation where calls are made to module function directly:
xdc_Int drivers_UART_UARTProxy_read__E( drivers_UART_UARTProxy_Handle __inst, xdc_Void *buffer, xdc_SizeT size )
{
return csl_host_UART_read((csl_host_UART_Handle)__inst, buffer, size);
}
The optimizer can remove this intermediate call saving the runtime overhead. It is for this reason that I would like to add support for instance proxies. We already have all the information necessary to make this happen. My intermediate proxy module generates an object table for each instance I create:
drivers_UART_Object__ drivers_UART_Object__table__V[1] = {
{/* instance#0 */
&drivers_UART_Module__FXNS__C,
(drivers_UART_UARTProxy_Handle)&csl_host_UART_Object__table__V[0], /* pinst */
},
};
Armed with this information we could feasibly generate the proxy call like this:
xdc_Int drivers_UART_UARTProxy_read__E( drivers_UART_UARTProxy_Handle __inst, xdc_Void *buffer, xdc_SizeT size )
{
if (__inst == (drivers_UART_UARTProxy_Handle) &csl_host_UART_Object__table__V[0])
{
return csl_host_UART_read((csl_host_UART_Handle)__inst, buffer, size);
}
else if (__inst == (drivers_UART_UARTProxy_Handle) &<some_other>_UART_Object__table__V[<inst_num>])
{
return some_other_UART_read((some_other_UART_Handle)__inst, buffer, size);
}
// More IUart else ifs...
else
{
/* Handle runtime created/constructed instances */
return __inst->__fxns->read((void*)__inst, buffer, size);
}
}
Although this looks ugly the optimizer can remove this intermediate call in all cases except runtime created/constructed instances. In the later cases the overhead is expected. Most of the other generated functions in the PROXY BODY section can be extended in a straightforward manner except Object__create__S and Params__init__S. It may be possible to use/add information in the params structure to test what instance is being created/initialized. My first guess would be if a field in the params was set to &<Pkg>_<Mod>_Object__PARAMS__C then a test could be performed. This would not work if the client explicitly initialized their params without calling the appropriate Params_init function. However it's unlikely that __self was set by the user in this case and the call to Core_createObject would assert. Perhaps __self could be assigned to od->prmsInit instead which should be the same as &<Pkg>_<Mod>_Object__PARAMS__C? The only problem I see there is the call to Core_assignParams would wipe out __self, but this could be fixed easily.
Looking at the documentation there may be significant overlap between my proposal and instance factories. The biggest difference is my proposal is one proxy to many delegates whereas factories is one proxy to one delegate with many choices for that delegate. Not having the implementation of factories available makes it hard to judge how much ground work is in place, but I don't see why both concepts couldn't coexist. I would love to get everyone's input on this proposal and some pointers on how I would go about prototyping the implementation.
Thanks,
Chris
|
|
|
|
|
Re: Instance Proxies [message #1742149 is a reply to message #1740460] |
Wed, 31 August 2016 18:39 |
Sasha Slijepcevic Messages: 115 Registered: July 2009 |
Senior Member |
|
|
Chris,
sorry for not responding earlier, it seems I am getting email notifications only for new threads not for new posts.
Since you are only rebuilding the core Java packages, the quickest way to do it is to start from an installation and then just drop the sources from git into the core Java packages that you want to rebuild.
Then, you need to define the environment variable JDK to point to your JDK installation, to the directory that contains 'bin', 'include', 'lib', etc.
Finally, you'll have to reference some jar files in custom.mak in the package you are trying to build. You'll probably have to do a little bit of trial and error to find out which packages are missing, but I think if you just add whatever I added to JCPATH in custom.mak for xdc.services.intern.gen, you should be fine:
JCPATH := $(PKGROOT)$(PATHCHAR)$(RHINO)$(PATHCHAR)$(ANTLR)$(PATHCHAR)$(ECLIPSE)$(PATHCHAR)$(XDCROOT)/packages/xdc/services/global/java/package.jar$(PATHCHAR)$(XDCROOT)/packages/xdc/services/spec/java/package.jar$(PATHCHAR)$(XDCROOT)/packages/xdc/services/intern/xsr/java/package.jar$(PATHCHAR)$(XDCROOT)/packages/xdc/services/intern/cmd/java/package.jar
Let me know how it goes, and I'll try to fix my notifications so I'll respond sooner.
|
|
|
|
Powered by
FUDForum. Page generated in 0.04779 seconds