what is do_nanosleep() in C - c

I came across a method named do_nanosleep() in C that I don't understand how it is used? One thing I know that it has to do with the suspending the execution of the calling thread, but that task is handled by nanosleep() in C. If that's true, then what is the need of do_nanosleep() here and how it is different from nanosleep()?
For reference, this is what it does.
/* arguments are seconds and nanoseconds */
inline void
do_nanosleep(time_t tv_sec, long tv_nsec)
{
struct timespec req;
req.tv_sec = tv_sec;
req.tv_nsec = tv_nsec;
nanosleep(&req, NULL);
}

Since do_nanosleep() is not a standard function, you will have to track it in your source code, or in the manuals for your system, to see what it does. It might be a portability wrapper which uses nanosleep() when it is available, and something else (usleep() or even sleep()) when it is not. It might do something completely unrelated to sleeping, too — but it probably does do what its name suggests.
Google has not (yet — 5 minutes after it was asked) indexed your question, and it does not know anything about do_nanosleep(). That suggests the code should be in your source somewhere, rather than in a system manual.
With the function definition in the question, we can see that instead of requiring the user to create a struct timespec, they can call do_nanosleep() with two arguments, the first for the seconds and the second for the fractions of a second (0..999,999,999 measured in nanoseconds). It then calls nanosleep(). So, in the minds of the people who wrote the software, do_nanosleep() presents a slightly more convenient interface to the underlying nanosleep() function. Since it is inline, the declarations for struct timespec must still be in scope, so I'm not convinced I agree with the authors, but it is not automatically a wrong decision.

It looks like it's just a simplified (and crippled) wrapper around POSIX nanosleep.
The first parameter is the number of seconds, and the second is the number of nanoseconds.
Like, do_nanosleep(3, 500000000) would (hopefully) sleep for 3 and a half seconds.
Since the function completely ignores return values... Your mileage may vary.

Related

What is the reason that some functions in standard library just appear to be wrappers or aliases?

When I have looked into the source of glibc, I sometimes stumbles over functions that are wrappers that does nothing and only works as an alias. For example:
int
rand (void)
{
return (int) __random ();
}
What is the reason for things like this? Why not just take the body of __random() and put it in rand()?
This is a very case specific question as there are a variety of reasons for such a behavior. One answer cannot cover all the reasons for all the cases.
For example, some compilers contain a variety of system specific "builtin" implementations, so the source / header files simply tell the compiler to place their implementation in there.
Another reason would be to type cast from a more general function to a standard conforming type.
Some functions contain repeated functionality (think printf vs. fprintf(stdin,...), and using wrappers is a simple way to keep the code more DRY.
Specifically, __random returns a long int and needs to be converted to int (which may or may not be the same, depending on your system).
In addition, __random reuses functionality in __random_r, but adds a lock to make the functionality thread safe.
Reusing the same functionality with minor variations (a global thread-safe state) keeps the code more DRY.

How to know Darwin kernel scheduler time slice?

On Linux, sched.h contains the definition of
int sched_rr_get_interval(pid_t pid, struct timespec * tp);
to get the time slice of a process. However the file shipping with OS X El Capitan doesn't hold that definition.
Is there an alternative for this on OS X?
The API's related to this stuff are pretty byzantine and poorly documented, but here's what I've found.
First, the datatypes related to RR scheduling seem to be in /usr/include/mach/policy.h, around line 155. There's this struct:
struct policy_rr_info {
...
integer_t quantum;
....
};
The quantum is, I think, the timeslice (not sure of units.) Then grepping around for this or related types defined in the same place, I found the file /usr/include/mach/mach_types.def, which says that the type struct thread_policy_t contains a field policy_rr_info_t on line 203.
Next, I found in /usr/include/mach/thread_act.h the public function thread_policy_get, which can retrieve information about a thread's policy into a struct thread_policy_t *.
So, working backwards. I think (but haven't tried at all) that you can
Use the thread_policy_get() routine to return information about the thread's scheduling state into a thread_policy_t
That struct seems to have a policy_rr_info_t sub-substructure
That sub-structure should have a quantum field.
That field appears to be the timeslice, but I don't know about the units.
There are no man pages for this part of the API, but this Apple Developer page explains at least a little bit about how to use this API.
Note that this is all gleaned from just grepping the various kernel headers, and I've definitely not tried to use any of these APIs in any actual code.

Write kernel system call that prints human readable time

I'm trying to print the time within my own custom system call in a human readable format (Jan 29 2015 05:53:12 for example, though any order is fine). I'm using code I know works in a standard C program because I've used it before, but for some reason it doesn't work within a system call.
#include<linux/linkage.h>
#include<linux/kernel.h>
#include<linux/sched.h>
#include<linux/time.h>
asmlinkage long sys_mycall (int someVal)
{
time_t t;
time(&t);
printk("myInt: %d", someVal);
printk("%s", ctime(&t)) ;
return 0 ;
}
I'm getting errors on implicit declaration of functions 'time' and 'ctime', even though I included linux/time.h (I also tried just time.h).
And an error on ctime returning type int when I specified %s.
I know this means that something is going wrong with the time.h, but what exactly is it? Am I not allowed to include that in a sys call?
Thanks!
The kernel coding environment is not a "hosted" implementation of C, which implies that various standard C functions like ctime() might not exist, or if they do, might not behave in the same way as the standard functions. In fact, ctime() does not exist inside the kernel at all.
Instead, you can use time_to_tm() from <linux/time.h> to convert a time_t to a broken-down time in a struct tm, and then print the components of struct tm individually.
Note that you have to supply a timezone offset to time_to_tm(), because there is no overall "current timezone" for the kernel - timezone is a display setting and is therefore handled entirely in userspace. This is one reason why the kernel typically doesn't format times to be "human-readable" itself. If you don't have a good value to supply for the timezone offset, you can use zero which will mean that the broken-down time is in UTC.
Instead of time(), to obtain the current time to seconds granuality inside the kernel use get_seconds().
The ctime() function is not available in the kernel.
In fact, there are very few date/time formatting functions available in the kernel; most of these functions are only available in user space. If you want to generate a timestamp in the kernel, don't try to format it; just return a time_t and let userspace applications handle the formatting.
If that isn't enough and you really want a readable timestamp, you'll need to define the necessary functions yourself.

C function call with too few arguments

I am working on some legacy C code. The original code was written in the mid-90s, targeting Solaris and Sun's C compiler of that era. The current version compiles under GCC 4 (albeit with many warnings), and it seems to work, but I'm trying to tidy it up -- I want to squeeze out as many latent bugs as possible as I determine what may be necessary to adapt it to 64-bit platforms, and to compilers other than the one it was built for.
One of my main activities in this regard has been to ensure that all functions have full prototypes (which many did not have), and in that context I discovered some code that calls a function (previously un-prototyped) with fewer arguments than the function definition declares. The function implementation does use the value of the missing argument.
Example:
impl.c:
int foo(int one, int two) {
if (two) {
return one;
} else {
return one + 1;
}
}
client1.c:
extern foo();
int bar() {
/* only one argument(!): */
return foo(42);
}
client2.c:
extern int foo();
int (*foop)() = foo;
int baz() {
/* calls the same function as does bar(), but with two arguments: */
return (*foop)(17, 23);
}
Questions: is the result of a function call with missing arguments defined? If so, what value will the function receive for the unspecified argument? Otherwise, would the Sun C compiler of ca. 1996 (for Solaris, not VMS) have exhibited a predictable implementation-specific behavior that I can emulate by adding a particular argument value to the affected calls?
EDIT: I found a stack thread C function with no parameters behavior which gives a very succinct and specific, accurate answer. PMG's comment at the end of the answer taks about UB. Below were my original thoughts, which I think are along the same lines and explain why the behaviour is UB..
Questions: is the result of a function call with missing arguments defined?
I would say no... The reason being is that I think the function will operate as-if it had the second parameter, but as explained below, that second parameter could just be junk.
If so, what value will the function receive for the unspecified argument?
I think the values received are undefined. This is why you could have UB.
There are two general ways of parameter passing that I'm aware of... (Wikipedia has a good page on calling conventions)
Pass by register. I.e., the ABI (Application Binary Interface) for the plat form will say that registers x & y for example are for passing in parameters, and any more above that get passed via stack...
Everything gets passed via stack...
Thus when you give one module a definition of the function with "...unspecified (but not variable) number of parameters..." (the extern def), it will not place as many parameters as you give it (in this case 1) in either the registers or stack location that the real function will look in to get the parameter values. Therefore the second area for the second parameter, which is missed out, essentially contains random junk.
EDIT: Based on the other stack thread I found, I would ammended the above to say that the extern declared a function with no parameters to a declared a function with "unspecified (but not variable) number of parameters".
When the program jumps to the function, that function assumes the parameter passing mechanism has been correctly obeyed, so either looks in registers or the stack and uses whatever values it finds... asumming them to be correct.
Otherwise, would the Sun C compiler of ca. 1996 (for Solaris, not VMS) have exhibited a >> predictable implementation-specific behavior
You'd have to check your compiler documentation. I doubt it... the extern definition would be trusted completely so I doubt the registers or stack, depending on parameter passing mechanism, would get correctly initialised...
If the number or the types of arguments (after default argument promotions) do not match the ones used in the actual function definition, the behavior is undefined.
What will happen in practice depends on the implementation. The values of missing parameters will not be meaningfully defined (assuming the attempt to access missing arguments will not segfault), i.e. they will hold unpredictable and possibly unstable values.
Whether the program will survive such incorrect calls will also depend on the calling convention. A "classic" C calling convention, in which the caller is responsible for placing the parameters into the stack and removing them from there, will be less crash-prone in presence of such errors. The same can be said about calls that use CPU registers to pass arguments. Meanwhile, a calling convention in which the function itself is responsible for cleaning the stack will crash almost immediately.
It is very unlikely the bar function ever in the past would give consistent results. The only thing I can imagine is that it is always called on fresh stack space and the stack space was cleared upon startup of the process, in which case the second parameter would be 0. Or the difference between between returning one and one+1 didn't make a big difference in the bigger scope of the application.
If it really is like you depict in your example, then you are looking at a big fat bug. In the distant past there was a coding style where vararg functions were implemented by specifying more parameters than passed, but just as with modern varargs you should not access any parameters not actually passed.
I assume that this code was compiled and run on the Sun SPARC architecture. According to this ancient SPARC web page: "registers %o0-%o5 are used for the first six parameters passed to a procedure."
In your example with a function expecting two parameters, with the second parameter not specified at the call site, it is likely that register %01 always happened to have a sensible value when the call was made.
If you have access to the original executable and can disassemble the code around the incorrect call site, you might be able to deduce what value %o1 had when the call was made. Or you might try running the original executable on a SPARC emulator, like QEMU. In any case this won't be a trivial task!

How do I resolve an "expected expression before 'unsigned'" error?

My code is:
#include <unistd.h>
(void)alarm(unsigned int 0);
error: expected expression before 'unsigned'
But I'm getting the following error:
Error: expected expression before 'unsigned', due to: (void)alarm(unsigned int 0);
I'm not sure if it is my syntax or use of (void) or something else. What's going on?
I'm using Code::Blocks under Windows.
Uh, is this meant to be a function call, or is it meant to be a declaration?
If you meant it to be a declaration, then it should be:
void alarm( unsigned int i );
If you meant it to be a function call, then it should be:
(void) alarm( 0 );
(Back in my C++ days I used to cast function results to void when I wanted to document the fact that I do not care what the function returned.)
EDIT: Then again, if what you are trying to do is to just declare a variable, then try this:
unsigned int alarm = 0;
Or if you are just trying to set a variable to zero, then things are even more simple:
alarm = 0;
8-)
It looks like you are trying to call the POSIX alarm function which takes an unsigned int and returns and unsigned int.
A correct form of the call would be:
alarm(0);
There is not normally a need to cast the return value to void although it can silence a warning on some compilers.
There is normally no need to explicitly cast 0 to unsigned int. The correct form would be (unsigned int)0. It is usually simpler to use a suffix where necessary, e.g. 0U has type unsigned int but in this instance plain 0 will work fine.
Additionally, as a function call is not a declaration it must appear inside a function body.
E.g.
void foo()
{
alarm(0);
}
You're not giving us enough context to figure out just what you're trying to do.
I'm going to assume that you want to call the alarm function with an argument of 0. According to the man page (type man alarm or man 2 alarm, or follow this link), alarm(0) will cancel any existing alarm without setting a new one.
On my system (Ubuntu, a Linux. i.e., Unix-like system), the following compiles, links, and executes without error:
#include <unistd.h>
int main(void) {
alarm(0);
return 0;
}
I saved the program in a file called c.c, and I compiled and linked it with the following command:
gcc c.c -o c
and executed it with:
./c
The implementation of the alarm function happens to be in the standard C library, which is linked by default. That might or might not be the case on your system, but if it's Linux or some other Unix-like system, it probably is.
(This isn't a particularly useful program, but it could be a starting point for something useful.
EDIT :
I see now that you're using Windows. The alarm() function is defined by the POSIX standard, and is (mostly) specific to Unix-like systems. Windows probably doesn't provide it by default. There are Unix-like emulation layers that run under Windows, such as Cygwin.
But if you want to develop code under Windows, you might consider avoiding non-portable constructs that Windows doesn't (directly) support.
Why do you want to call alarm()? Do you have a requirement to do what that particular function does, or are you just trying to learn the basics?
Agreed with Chiron that this belongs to StackOverflow.
You don't need to cast return to void just simply ignore it if you choose but better yet don't
Why are you declaring variable 0 inside the function call? Call should be:
(void)alarm(0);
#include <unistd.h>
int main() {
alarm(0);
}
I think the question is to write a simple program which calls the alarm standard function. (See the comment on #MikeNakis's question).
You can't just copy the code from the man page into a program and compile it. You must make a complete program, like the one I have given here.
Since you've included unistd.h, I'm assuming you're trying to call the alarm() function declared in that header:
unsigned int alarm(unsigned int seconds);
If you want to call alarm with an argument of 0 seconds, simply do alarm(0). You don't need to cast 0 to an unsigned int, but if you really wanted to you would just have alarm( (unsigned)0 );.
If you don't care about the return type, then just don't assign it to a variable. You don't need to add (void) to the start of the function call to ignore the return value. (void)alarm(0); is perfectly legal, but also pointless.
And I'm not sure if your snippet is a chopped up example or your actual code, but you can't just call alarm from outside of a function like that.
Also, from the man pages:
If seconds is zero, no new alarm() is scheduled.
But perhaps you may be wanting to cancel previous alarms:
In any event any previously set alarm() is canceled.
EDIT: Didn't realise until Keith pointed it out a few minutes ago that you're using Windows. alarm() is a *nix function, if you wanted to call it from Windows you could use tools such as Cygwin (which is commonly used) to emulate a *nix environment.

Resources