where's definition of __SetPageReferenced in kernel sources - c

I try to port some functionality from newest stable kernel (4.6.3) to older one for whatever reason I've got for doing so. Everything went pretty good but I keep getting mm/filemap.c:1183:4: error: implicit declaration of function '__SetPageReferenced'
I cannot find oryginal definition of
static inline void __SetPageReferenced(struct page *page) which is funny considering that oryginal 4.6.3 compiles no problem despite fact I can't find that definition in it's sources
Forgot to mention, there are similar declarations in include/linux/page-flags.h I would just copy and paste it right here if I knew where to find it. Unfortunately I wasn't able to find any useful mention of it anywhere online.
So thanks to the conversation in comment section, especially to #LPs input I came up with sort of a hack where I define:
#define __SetPageReferenced(page) set_bit(PG_referenced, &(page)->flags) which get rid of the implicit declaration problem. I'll post whether it works or not when I finally port my functionality and base on the results might reopen or close the question.
Cheers!
Side note:
Found out that you can use extern void mark_page_accessed(struct page *); instead while fixing different problem.

Declare macro __SETPAGEFLAG here, use it for referenced bit here
Result:
static __always_inline void __SetPageReferenced(struct page *page) \
{ __set_bit(PG_referenced, &PF_HEAD(page, 1)->flags); }

Related

typedef struct: unknown name

I am confused by my actual problem... Could also be my mistake
Short description with code:
rtc.h
#ifndef RTC_H_
#define RTC_H_
typedef struct timestamp_t
{
uint8_t year,month,day,hour,minute,second;
}timestamp_t;
#endif /* RTC_H_ */
lpwa.h
#ifndef LPWA_H_
#define LPWA_H_
#include "rtc.h"
timestamp_t lpwa_ntp_to_stamp(char*); //shows error: unknown name timestamp_t
#endif /* LPWA_H_ */
lpwa.c
#include "lpwa.h"
timestamp_t lpwa_ntp_to_stamp(char *text) //no problem
{
...
}
If I copy the typedef struct to lpwa.h it says "confliction types for timestamp_t"
Am I missing something or is this just not possible?
This is an answer compiled from my debugging recommendations which helped OP to find the actual problem:
The shown code should not exhibit the described problem. This actually is helpful information, because it means that the structure of your actual code is different and you need to find that difference to trace the problem to the root.
The problem is probably in the include order, aka include tree, being different than you think.
Inserting #error Header A is compiled #error Header B is compiled generously in all likely and unlikely places of your project will give you an idea of the actual include tree, allowing you to look for differences to the imagined include tree. (Use #warning if your compiler supports it, then you get more than only the first #error encountered.)
The constructive way to debug this is to make a StackOverflow-style minimal reproducible example.
If making a classic MRE/MCVE ( http://stackoverflow.com/help/mcve ) seems too much work (it is not, trust me), then try making a MRE of what you think happens, from scratch. That will at least show you that what you think happens is NOT what actually happens. This is also helpful information, though making use of it requires experience and discipline. (Thanks for not feeling mocked here.)
Keep in mind that each source code file "*.c" is the root of another include tree.
Playing with #error will also alert you of the possible problem that you look at different files (e.g. in your editor) than the compiler actually processes. (Again, not mocking. That happens more often, to me, than I'd like to admit....)
Above is general.
Specifically in your case, I suspect that there is a hidden/indirect #include "lwpa.h" inside rtc.h, between the shown include and the shown typedef. (And I think you confirmed that.)

How can I maintain correlation between structure definitions and their construction / destruction code?

When developing and maintaining code, I add a new member to a structure and sometimes forget to add the code to initialize or free it which may later result in a memory leak, an ineffective assertion, or run-time memory corruption.
I try to maintain symmetry in the code where things of the same type are structured and named in a similar manner, which works for matching Construct() and Deconstruct() code but because structures are defined in separate files I can't seem to align their definitions with the functions.
Question: is there a way through coding to make myself more aware that I (or someone else) has changed a structure and functions need updating?
Efforts:
The simple:
-Have improved code organization to help minimize the problem
-Have worked to get into the habit of updating everything at once
-Have used comments to document struct members, but this just means results in duplication
-Do use IDE's auto-suggest to take a look and compare suggested entries to implemented code, but this doesn't detect changes.
I had thought that maybe structure definitions could appear multiple times as long as they were identical, but that doesn't compile. I believe duplicate structure names can appear as long as they do not share visibility.
The most effective thing I've come up with is to use a compile time assertion:
static_assert(sizeof(struct Foobar) == 128, "Foobar structure size changed, reevaluate construct and destroy functions");
It's pretty good, definitely good enough. I don't mind updating the constant when modifying the struct. Unfortunately compile time assertions are very platform (compiler) and C Standard dependent, and I'm trying to maintain the backwards compatibility and cross platform compatibility of my code.
This is a good link regarding C Compile Time Assertions:
http://www.pixelbeat.org/programming/gcc/static_assert.html
Edit:
I just had a thought; although a structure definition can't easily be relocated to a source file (unless it does not need to be shared with other source files), I believe a function can actually be relocated to a header file by inlining it.
That seems like a hacked way to make the language serve my unintended purpose, which is not what I want. I want to be professional. If the professional practice is not to approach this code-maintainability issue this way, then that is the answer.
I've been programming in C for almost 40 years, and I don't know of a good solution to this problem.
In some circles it's popular to use a set of carefully-contrived macro definitions so that you can write the structure once, not as a direct C struct declaration but as a sequence of these macros and then, by defining the macro differently and re-expanding, turn your "definition" into either a declaration or a definition or an initialization. Personally, I feel that these techniques are too obfuscatory and are more trouble than they're worth, but they can be used to decent effect.
Otherwise, the only solution -- though it's not what you're looking for -- is "Be careful."
In an ideal project (although I realize full well there's no such thing) you can define your data structures first, and then spend the rest of your time writing and debugging the code that uses them. If you never have occasion to add fields to structs, then obviously you won't have this problem. (I'm sorry if this sounds like a facetious or unhelpful comment, but I think it's part of the reason that I, just as #CoffeeTableEspresso mentioned in a comment, tend not to have too many problems like this in practice.)
It's perhaps worth noting that C++ has more or less the same problem. My biggest wishlist feature in C++ was always that it would be possible to initialize class members in the class declaration. (Actually, I think I've heard that a recent revision to the C++ standard does allow this -- in which case another not-necessarily-helpful answer to your question is "Use C++ instead".)
C doesn't let you have benign struct redefinitions but it does let you have benign macro redefinitions.
So as long as you
save the struct body in a macro (according to a fixed naming convention)
redefine the macro at the point of your constructor
you will get a warning if the struct body changes and you haven't updated the corresponding constructor.
Example:
header.h:
#define MC_foo_bod \
int x; \
double y; \
void *p
struct foo{ MC_foo_bod; };
foo__init.c
#include "header.h"
#ifdef MC_foo_bod
//try for a silent redefinition
//if it wasn't silent, the macro changed and so should this code
#define MC_foo_bod \
int x; \
double y; \
void *p
#else
#error ""
//oops--not a redefinition
//perhaps a typo in the macro name or a failure to include the header?
#endif
void foo__init(struct foo*X)
{
//...
}

Is there a syntax error in this function declaration?

This is from a textbook:
/* This function locates the address of where a new structure
should be inserted within an existing list.
It receives the address of a name and returns the address of a
structure of type NameRec
*/
struct NameRec *linear Locate(char *name)
{
...
}
I understand it returns a pointer to a struct NameRec. Why is "linear" there and why is there a space between "linear" and "Locate"?
#define linear
will make it syntactically correct even if it wasn't before (though, technically, you'd probably want a #undef linear beforehand to avoid possible conflicting macro definitions).
It depends entirely on the context of the code, which you haven't shown. As it stands now, with no header inclusions or definitions like -Dlinear= on the compiler command line, it would not compile in a standards-conformant environment without extensions.
The best way to tell, of course, is to just try to actually compile the thing and see what happens :-)
Given that the solutions link for chapter 13 (the one you're asking about) has no mention of the linear word in the solution, I'd say it's a safe bet to assume your book is incorrect. I'd consider contacting the author (apparently currently working at FDU in New Jersey) to clear it up.
It's a typo in the book. See the locate function here:
https://users.ipfw.edu/chansavj/ACY2017/ANSI_C/ANSI_C_4thEd/Solutions%20to%20Exercises%20(Windows)/Solutions/83556-0s/Ch13/pgm13-5ex3.c
(Posted by ta.speot.is in the comments)

How should I include variable defined with extern in c file

I am having trouble compiling the demonstration code for the STM32F4-Discovery using the arm-none-eabi toolchain. The error is occuring in linking and this is the [first] error I'm receiving.
template/obj/stm32f4xx_it.o: In function `OTG_FS_IRQHandler':
template/src/stm32f4xx_it.c:192: undefined reference to `hpcd'
I've been trying to figure this out on and off for several months so I've created this github repository to track the project. The variable hpcd is defined in template/src/usbd_conf.c. My knowledge of C/C++ is unfortunately full of holes, so I'm hoping someone may help me both narrow down the problem and the suggest the proper way to fix it.
I have two questions.
hpcd is included in the file usbd_conf.c. It is used in many files, but none of these files actually include usbd_conf.c, only usbd_conf.h. The question is, by only including the header, can a file which declares a variable as extern PCD_HandleTypeDef hpcd; use the variable without specifically including the .c file?
Assuming the answer to question 1 is yes, why is it the function OTG_FS_IRQHandler isn't finding hpcd? The chain of includes from stm32f4xx_it is main.h -> usbd_core.h -> usbd_conf.h.
I'm assuming the answer to question 1 is yes because this is the demonstration code I believe was running on the board when I purchased it. I can only assume the poblem is with the way I'm building it. Would anyone be willing to help me troubleshoot this problem? I would be happy to provide more details if relevant or to better structure this question, but I'm trying to avoid posting a full USB stack in my question. Thank you.
It might help if you put extern PCD_HandleTypeDef hpcd; in one of the headers that gets included by everyone involved (main.h would do, I think).
Example for how the extern stuff works normally:
A file that does define a variable you want to use elsewhere contains
include "a_header.h";
// ...
int some_variable = 42;
The header a_header.h contains
extern some_variable;
The file where you want to use that variable contains
include "a_header.h";
extern some_variable;
//...
foo = some_variable;
some_variable = 47;
such that the linker knows excactly what to do with it.

Bool reported as undefined. When typedef added; error that Bool is already defined

I'm writing embedded software for the ti C5515 in ccstudio, using the CSL libraries. I'm having trouble with type definitions. In specific, I get this error:
#20 identifier "Bool" is undefined in csl_intc.h
Taking a look at the header, I find the bool definition in tistdtypes.h; within scope, as far as I can tell. In desperation, I add a typedef to the top of the file. However, then it complains that bool is already defined.
I've made sure that the case is the same, and that there isn't another tistdtypes.h somewhere overriding the definition. How is it possible that it complains that there is no typedef, but when I add one, it says that there is one already?
Here are the two errors, one after the other:
#20 identifier "Bool" is undefined TMS320C5515 line 992, external location: ... csl_intc.h
#102 "Bool" has already been declared in the current scope TMS320C5515 line 914, external location: ... csl_intc.h
The file path is exactly the same. I can also paste the lines between 992 and 914 if necessary. There isn't much.
There is a #ifndef STD_ around the definition. Do you know what defines are passed by your compiler/other includes ?
One way to find out it to turn up the verbosity of the preprocessor to see all the code which is parsed. Maybe that will give you some insight why that is being skipped.
With gcc that would be gcc -E to stop after preprocessing and dump the parsed content. You might want to find the option for your compiler if you use a different one.
When I use the file in question:
#include "tistdtypes.h"
int main(){
Bool something = 0;
and run this program via gcc -Werror -Wall, I'm not seeing any such errors. So unless your version is different from the one I linked to, I'd say there's something wrong with how it's being compiled into your program.
Could you add some more details regarding how it's included, if your version of tistdtypes.h is different than when I linked to, and how the target is being compiled?
As a "worst case" backup at least you know that a Bool is really a unsigned short, so you could always modify your code to just not use the typedef.
EDIT:
I just took a look at csl_intc.h. It uses Bool in that file without including the definition of it. What happens if you include tistdtypes.h in this file?

Resources