Our customer provided source code has portions of code that will be executed based on tool type. A sample code portion is given below. The function has common portions and tool specific(hardware platform) portions. The code is written in C and runs in VxWorks. Addition or deletion of new tool type has code modification. The customer wants addition or deletion new tool type with minimal code change and testing effort
int vsp_recv(char *const recv_text)
{
int rc = 0;
const int type = get_tool_type();
// Common Code
if (MODEL_CR == type)
{
rc = beamoff(recv_text);
}
else
{
rc = vsp_set(recv_text);
}
return(rc);
}
Is it the right technique to separate the code to two methods as given below, keep them in separate source files and define separate make files to generate tool specific binary? Is there any better ways to do this?
Tool type MODEL_CR code
int vsp_recv_tool_speccific(char *const recv_text)
{
return beamoff(recv_text);
}
Tool type MODEL_CV code
int vsp_recv_tool_speccific(char *const recv_text)
{
return vsp_set(recv_text);
}
Refactored method
int vsp_recv(char *const recv_text)
{
int rc = 0;
const int type = get_tool_type();
// Common Code
rc = vsp_recv_tool_speccific(recv_text);
}
Define a shared library for each tool and a configuration file that defines what functions get called for each tool. Load the shared libraries at startup and provide a signal catcher to reload if the configuration file changes.
the OPs question (and posted code) says that 3 places will need to be modified.
the function: get_tool_type()
the header file with the definitions of MODEL_CV, MODEL_CR, etc
the if-then-else list.
were it me, I would implement a table of function pointers, have get_tool_type() return an index into that table. Then all the if/then/else code would become a single statement that invokes a function from the table.
Then any updates would be additions to the table, modifications to 'get_too_type(), and the additional functions likebeam_off()`
The loss of a tool type would not require any code change.
the addition of a tool type would require appending an entry to the table, mod to get_tool_type() to recognize the new tool, and the new function to process the new tool type.
Of course, this could result in code that is never executed.
Related
The problem
I am following a guide from the Microsoft Documentation and the examples there are given in C++. I could've just used the default samples in C++, but I wanted to further understand how the API works so I decided to rewrite the default C++ sample in C.
The problem I encountered is that I can easily call D2D1CreateFactory and create an ID2D1Factory, though when I was previously reading the documentation, it was stated that you have to always release the COM object after you've used it and don't need it anymore. The fact is that in C++ there's an inherited method Release from IUnknown. In C though there's no even a lpVtbl, which as far as I understand is usually needed for that purpose. The ID2D1Factory is just provided as a typedef and is an incomplete type.
And now I'm stuck, because I don't know how to release pointer. I've spent a couple of hours searching for ways to do that in C.
Is it even possible?
The header file: d2d1.h
The Code
Window Procedure simplified:
switch (uMessage)
{
case WM_CREATE:
{
HRESULT hResult = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, &pFactory);
if (FAILED(hResult))
{
return -1;
}
return 0;
}
...
}
Obviously pFactory is of an ID2D1Factory* type in global scope. It is zero-initialized by default (if that helps).
long time listener, first time caller.
I've been backporting features from upstream code as recent as 4.12-rc-whatever to a 3.4-base kernel for an older Qualcomm SoC board (apq8064, ridiculous undertaking I know).
Thus far I've been successful in almost every core api, with any compatibility issues solved by creative shims and ducttape, with the exception of cpufreq.
Keep in mind that I'm still using legacy platform drivers and clocking, no dt's or common clock frame work.
My issue begins with the inclusion of stuct cpufreq_frequency_table into struct cpufreq_policy, as part of the move from percpu to per-policy in the api. In 3.13, registering a platform's freq_table becomes more difficult for unique cases, as using cpufreq_frequency_table_get_attr is no longer an option.
In my case, the cpufreq_driver's init is generic, and relies on my platform's scaling driver (acpuclock-krait) to register the freq_table, which is fine for the older api, but becomes incompatible with the per-policy setup. The upstream so I requires the driver to manually initialize policy->freq_table and mine uses both a cpu, and an array of 35 representing the tables in the platform code. As well, it accounts for the 6 different speedbin/pvs values when choosing a table. I'm considering either dropping the "cpu" param from it and using cpumask_copy, and perhaps even combining the two drivers into one and making the clock driver a probe, but yeah, thus far init is a mystery for me. Here is the snippet of my table registration, if anyone can think of something hackable, I'd be eternally grateful...
ifdef CONFIG_CPU_FREQ_MSM
static struct cpufreq_frequency_table.freq_table[NR_CPUS][35];
extern int console_batt_stat;
static void __init cpufreq_table_init(void)
{
int cpu;
int freq_cnt = 0;
for_each_possible_cpu(cpu) {
int i;
/* Construct the freq_table tables from acpu_freq_tbl. */
for (i = 0, freq_cnt = 0; drv.acpu_freq_tbl[i].speed.khz != 0
&& freq_cnt < ARRAY_SIZE(*freq_table)-1; i++) {
if (drv.acpu_freq_tbl[i].use_for_scaling) {
freq_table[cpu][freq_cnt].index = freq_cnt;
freq_table[cpu][freq_cnt].frequency
= drv.acpu_freq_tbl[i].speed.khz;
freq_cnt++;
}
}
/* freq_table not big enough to store all usable freqs. */
BUG_ON(drv.acpu_freq_tbl[i].speed.khz != 0);
freq_table[cpu][freq_cnt].index = freq_cnt;
freq_table[cpu][freq_cnt].frequency = CPUFREQ_TABLE_END;
/* Register table with CPUFreq. */
cpufreq_frequency_table_get_attr(freq_table[cpu], cpu);
}
dev_info(drv.dev, "CPU Frequencies Supported: %d\n", freq_cnt);
}
UPDATE!!! I wanted to update the initial registration BEFORE merging all the core changes back in, and am pretty certain that I've done so. Previously, the array in question referenced a percpu dummy array that looked like this: freq_table[NR_CPUS][35] that required the cpu parameter to be listed as part of the table. I've made some changes here that allows me a percpu setup AND the platform-specific freq management( which cpufreq doesn't need to see), but with a dummy table representing the "index," which cpufreq does need to see. Commit is here, next one fixed obvious mistakes: https://github.com/robcore/machinex/commit/59d7e5307104c2396a2e4c2a5e0b07f950dea10f
I spent quite a lot of time in looking for the full documentation of all the C API XLM Functions without success.
I found this page which illustrate a few of them:
http://msdn.microsoft.com/en-us/library/office/bb687910%28v=office.12%29.aspx
But for instance I wanted to understand and use xlfAddMenu, and I cannot find a page on MSDN that explain me.
Do you know if there is any documentation available? Apparently it is not so easy to get there.
There is no exhaustive official documentation for all C API XLM functions. However, as the documentation says following regarding C API XLM functions:
Many more functions are exposed by Excel via the C API that are useful
when you are developing XLLs. They correspond to the Excel worksheet
functions and functions and commands that are available from XLM macro
sheets."
Also, the EXAMPLE.[C,H] files which comme with the installation of the SDK use some of these functions and you can use it to learn how to use them. For instance, the xlfAddMenu is used in the xlAutoOpen callback function.
// In the following block of code, the Generic drop-down menu is created.
// Before creation, a check is made to determine if Generic already
// exists. If not, it is added. If the menu needs to be added, memory is
// allocated to hold the array of menu items. The g_rgMenu[] table is then
// transferred into the newly created array. The array is passed as an
// argument to xlfAddMenu to actually add the drop-down menu before the
// help menu. As a last step the memory allocated for the array is
// released.
//
// This block uses TempStr12() and TempNum12(). Both create a temporary
// XLOPER12. The XLOPER12 created by TempStr12() contains the string passed to
// it. The XLOPER12 created by TempNum12() contains the number passed to it.
// The Excel12f() function frees the allocated temporary memory. Both
// functions are part of the framework library.
Excel12f(xlfGetBar, &xTest, 3, TempInt12(10), TempStr12(L"Generic"), TempInt12(0));
if (xTest.xltype == xltypeErr)
{
hMenu = GlobalAlloc(GMEM_MOVEABLE,sizeof(XLOPER12) * g_rgMenuCols * g_rgMenuRows);
px = pxMenu = (LPXLOPER12) GlobalLock(hMenu);
for (i=0; i < g_rgMenuRows; i++)
{
for (j=0; j < g_rgMenuCols; j++)
{
px->xltype = xltypeStr;
px->val.str = TempStr12(g_rgMenu[i][j])->val.str;
px++;
}
}
xMenu.xltype = xltypeMulti;
xMenu.val.array.lparray = pxMenu;
xMenu.val.array.rows = g_rgMenuRows;
xMenu.val.array.columns = g_rgMenuCols;
Excel12f(xlfAddMenu,0,3,TempNum12(10),(LPXLOPER12)&xMenu,TempStr12(L"Help"));
GlobalUnlock(hMenu);
GlobalFree(hMenu);
}
According to me the best documentation (but not updated..) is the following book : Financial Applications using Excel Add-in Development in C / C++, 2nd Edition by Steve Dalton. You can find description of the xlfAddMenu function page 332. You can also find some useful information in the chm file of the Microsoft Excel XLL Software Development Kit, including codes examples (note I did not found the xlfAddMenu in it so I guess it is a depreciated function).
can anyone in this forum give an example in C how two threads process data from one textfile.
As an example, I have one textfile that contains a paragraph. I have two threads that will process the data in the said file. One thread will count the number of lines in the paragraph. The second thread will count the numeric characters.
thanks
If you asked in C++ I could give you a code example, but I havent done ANSI C in a very long time so I will give you the design and pseudo code.
Please keep in mind this is really bad pseudo code that is meant to give an example. I'm not questioning WHY you would want to do this. For all I know it could be an excercise with threads or because you "feel like it".
Example 1
int integerCount = 0;
int lineCount = 0;
numericThread()
{
// By flagging the file as readonly you should
// be able to open it as many times as you wish
handle h = openfile ("textfile.txt". readonly);
while (!eof(h)) {
String word = readWord (h);
int outInteger
if (stringToInteger(word, outInteger)) {
++integerCount;
}
}
}
lineThread()
{
// By flagging the file as readonly you should
// be able to open it as many times as you wish
handle h = openfile ("textfile.txt". readonly);
while (!eof(h)) {
String word = readWord (h);
if (word.equals("\n") {
++lineCount ;
}
}
}
If for some reason you aren't able to open the file twice in readonly you will need to maintain a queue for each thread, having the main thread put words into each threads queue. The threads will then pull from the queue.
Example 2
int integerCount = 0;
int lineCount = 0;
queue numericQueue;
queue lineQueue;
numericThread()
{
while (!numericQueue.closed()) {
String word = numericQueue.pop();
int outInteger
if (stringToInteger(word, outInteger)) {
++integerCount;
}
}
}
lineThread()
{
while (!lineQueue.closed()) {
String word = lineQueue.pop();
if (word.equals("\n") {
++lineCount ;
}
}
}
mainThread()
{
handle h = openfile ("textfile.txt". readonly);
while (!eof(h)) {
String word = readWord(h);
numericQueue.push(word);
lineQueue.push(word);
}
numericQueue.close();
lineQueue.close();
}
There are lots of ways to do this. You can make different design decisions depending on how fast or simple or elegant or overengineered you want this to be. One way, as posted by Andrew Finnell is to have each thread open the file and read it completely independently. In theory this isn't great because you are doing expensive IO twice but in practice it's probably fine because the OS has likely cached the contents of whichever read executes first. Double IO is still more expensive than average because it involves a lot of needless system calls, but again in practice it will be irrelevant unless you have a very large file.
Another model of how to do this would be for each thread to have an input queue, or a shared global queue. The main thread reads the file and places each line in turn on the queue(s), and perhaps main doubles as one of your worker threads. This is more complicated because access to the queue(s) must be synchronized, or some lockless queue implementation must be used. In the case of a shared global queue, there is less duplication of data but now the lifecycle of that data is more complicated.
Just to point out how many ways such a simple thing can be done, you could go the overengineering route and make each thread generic. Instead of placing data on the queue(s) you place both data (or pointers to data) and function pointers and let each thread execute the callback. This kind of model might might sense if you plan on adding lots more kind of things to compute but want to limit the number of threads you will use.
I don't think you will see much performance difference in using 2 threads over one. Either way, you don't want both threads to read the file. Read the file first, then pass a COPY of the stream to the methods you want and process both. The threads will not have access to the same stream of data at the same time so you'll need to use 2 copies of the textfile.
P.S. It's possible that depending on the size of the file, you will actually loose performance using 2 threads.
I'm a bit confused about how to implement my state machine.
I already know it's hierarchical since some states share the same action.
I determine what I need to do by these parameters:
Class (Values are: Base, Derived, Specific)
OpCode
Parameter 1 - optional
Parameter 2 - optional
My hierarchy is determined by the Class and the OpCode represents the action.
Derived can use the OpCodes of Base and Specific can use OpCodes of both Base and Derived.
The naive implementation is the following:
void (*const state_table [MAX_CLASSES][MAX_OPCODES]) (state *) {
{base_state1, base_state2, NULL, NULL},
{base_state1, base_state2, derived_state1, NULL},
{base_state1,base_state2, derived_state1, specific_state3},
};
void dispatch(state *s)
{
if (state_table[s->Class][s->OpCode] != NULL)
state_table[s->Class][s->OpCode](s);
}
This will turn unmaintainable really quick.
Is there another way to map the state to a superclass?
EDIT:
Further calcualtion leads me to think that I'll probably use most if not all OpCodes but I will not use all of the Classes available to me.
Another clarification:
Some OpCodes might be shared through multiple derived and base Classes.
For example:
I have a Class called Any
which is a Base class. It has the
OpCodes: STATE_ON, STATE_OFF, STATE_SET.
I have another Class called
MyGroup which is a Derived class. It has the OpCodes:
STATE_FLIP, STATE_FLOP.
The third Class is a Specific
class called ThingInMyGroup which
has the OpCode:
STATE_FLIP_FLOP_AND_FLOOP.
So a message with class Any is sent from the server, recieved in all clients and processed.
A message with class MyGroup is sent from the server, recieved in all clients and processed only on clients that belong to MyGroup, any OpCodes that are valid for the Any class are valid for the MyGroup class.
A message with class ThingInMyGroup is sent from the server, recieved in all clients and processed only on clients that belong to MyGroup and are a ThingInMyGroup*, any **OpCodes that are valid for the Any class and MyGroup class are valid for the ThingInMyGroup class.
After a message is received the client will ACK/NACK accordingly.
I prefer not to use switch cases or const arrays as they will become unmaintainable when they get bigger.
I need a flexible design that allows me:
To specify which OpCodes are available
for each Class.
To specify a superclass for each Class and through that specification to allow me to call the function pointer that is represented by the current OpCode.
There are several ways to deal with this. Here is one:
edit -- with general purpose hierarchy added
typedef unsigned op_code_type;
typedef void (*dispatch_type)(op_code_type);
typedef struct hierarchy_stack hierarchy_stack;
struct hierarchy_stack {
dispatch_type func;
hierarchy_stack *tail;
};
void dispatch(state *s, hierarchy_stack *stk) {
if (!stk) {
printf("this shouldn't have happened");
} else {
stk->func(s, stk->tail);
}
}
void Base(state *s, hierarchy_stack *stk ) {
switch (s->OpCode) {
case bstate1:
base_state1(s);
break;
case bstate2:
base_state(2);
break;
default:
dispatch(s, stk);
}
}
void Derived(state *s, hierarchy_stack *stk ) {
switch(s->opcode) {
case dstate1:
deriveds_state1(s);
break;
default:
dispatch(s, stk);
}
}
...
NOTE : All function calls are tail calls.
This localizes your "class"es a good bit so that if you decide that Derived needs 100 more methods/opcodes then you only have to edit methods and the enum (or whatever) that you use to define opcodes.
Another, more dynamic way, to deal with this would be to have a parent pointer within each "class" that pointed to the "class" that would handle anything that it could not handle.
The 2D table approach is fast and flexible (Derived could have a different handler than Base for opcode 0), but it grows fast.
I wrote a little tool that generates code similar to your naive implementation based on a mini-language. The language just specified the state-opcode-action relationships, all of the actions were just C functions conforming to a typedef.
It didn't handle the HSM aspect, but this would be relatively easy to add to a language.
I'd recommend taking this approach -- create a little language that gives you a clean way to describe the state machine, and then generate code based on that machine description. That way when you need to insert a new state a month from now, the whole thing isn't a tangled mess to edit.
Let me know if you want the code and I'll make sure it's still available somewhere.