How to check for computer power loss? - c

Hopefully this is a simple question to answer.
Basically I would like to use C to see if there was a power loss in my computer. This will decide how a program runs. If there was a power loss then it would go one way. Otherwise it would respond another way:
#include nopower.h
#include power.h
//------------------------
if(!powerloss){
power_procedure();
}
else no_power_procedure();
//--------------------------
I'm running Ubuntu 12.04 LTS. I'm hoping that this can be run directly on the computer running this code. In otherwords is there a way to check a registry status to see if power was loss. The operating system knows when there is an improper shutdown, and I'd like to know if I can tap into the same or a similar resource. I'd rather not constantly write to a file.

int main()
{
printf ("power is currently on");
}
Coding the "power is currently off" case is somewhat trickier.
Alternately if you want to know the time since the last boot, and put up a message if it was recent, then see Uptime under linux in C

Related

How to call an event after x minutes while still running?

I'm quite new in programming, so please bear with me.
I'm working with a microcontroller, therefore I'm using Microchip Studio.
My code is simplified build up like this:
While(1){
if(ErrorFlag==1)
timer_restart++;
else
timer_restart=0;
if (time_restart == 600000)
restart()
//Remaining code
} // EndWhile
My problem is that I would like to call restart() after around 5 minutes. Right now I have no clue how long it takes. Is there a better way to implement that?
I've tried to find out what time one-WhileLoop-Rotation requires with the clock() function. But I'm getting a ErrorMessage "undefined reference". I think that Microchip Studio does not know those functions.
I maybe could use something like:
while(1){
while(ErrorFlag==1){
delay_ms(5000);
restart();
ErrorFlag=0;
}}
But then the rest of the code is interrupted. Is there any advice someone can give me?
"Busy-while" or "busy-delay" are rarely ever the correct solution. Apart from being inaccurate, they also lock up your CPU at 100% and consuming current needlessly.
You need to use the actual on-chip hardware peripheral timers, either by polling a timer flag on regular basis or by using interrupts. As for how to do that, it depends on the specific MCU.

What is the difference between reboot arguments RB_HALT_SYSTEM and RB_POWER_OFF?

What is the real difference between the LINUX_REBOOT_CMD_HALT and LINUX_REBOOT_CMD_POWER_OFF arguments to the reboot() system call (resp. the RB_HALT_SYSTEM and RB_POWER_OFF arguments given to its wrapper function)?
The reboot(2) manual page has the following descriptions (differences emphasized):
RB_HALT_SYSTEM
LINUX_REBOOT_CMD_HALT
(RB_HALT_SYSTEM, 0xcdef0123; since Linux 1.1.76). The message "System halted." is printed, and the system is halted. Control is given to the ROM monitor, if there is one. If not preceded by a sync(2), data will be lost.
LINUX_REBOOT_CMD_POWER_OFF
(RB_POWER_OFF, 0x4321fedc; since Linux 2.1.30).
The message "Power down." is printed, the system is stopped, and all power is removed from the system, if possible. If not preceded by a sync(2), data will be lost.
Reading the descriptions, a few questions come up:
What is the difference between halted and stopped?
Would a reboot(RB_HALT_SYSTEM) call not remove power from the
system?
Where would the "System halted." and "Power down." messages be printed?
I don't think there is a difference; those words are synonyms in common English and I think this documentation is just using their English meaning, not as specific technical terms.
correct, that's exactly what the docs are trying to tell you.
on the console and/or kernel log, duh. Where kernel messages are normally printed, like during bootup.
You can easily try these for yourself to see what they do; the user-space shutdown(8) command has -H (halt) and -P / -h (poweroff) options, as well as -r. Read the man page. I assume it eventually makes a reboot(2) system call, or causes init to make one, after a sync.
And yes, the traditional shutdown -h command is halt + power off, i.e. POWER_OFF. Back in the old days, computers didn't used to be able to power themselves off, but these days that's usually what people think of as a non-reboot shutdown. Especially on systems where the kernel can't "return" to a BIOS / firmware command interface.
On a PC, one of the few use-cases I could imagine for halt without poweroff would be to insert a USB drive or CD before pressing the reset button (or ctrl+alt+delete). But maybe you don't want the currently-booted Linux kernel to react to the new hardware at all, so you want to halt Linux first.
You could poweroff to do this, but you don't need to and there's no need to start/stop your rotating disks and put extra wear on their motors.

Why doesn't Linux prevent spawning infinite number of processes and crashing?

With the very simple code below, my system (Ubuntu Linux 14.04) simply crashes not even letting my mouse respond. I had to force quit with the power button. I thought Linux is a stable OS tolerable of handling such basic program errors. Did I miss something?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
void check(int isOkay){
if(!isOkay){
printf("error\n");
abort();
}
}
int main(void){
#define n 1000000
int array[n];
sem_t blocker;
int i;
while(1){
if(!fork()){
for(i = 0; i < n; ++i){
array[i] = rand();
}
check(sem_init(&blocker, 0, 0) == 0);
check(sem_wait(&blocker) == 0);
}
}
return 0;
}
Congratulations, you've discovered the fork bomb. There are shell one-liners that can wreak the same sort of havic with a lot less typing on your part.
It is in fact possible to limit the number of processes that a user can spawn using ulimit -- see the bottom of the linked wikipedia articles for details.
A desktop install of Ubuntu is not exactly a hardened server, though. It's designed for usability first and foremost. If you need a locked down system that can't crash, there are better options.
The command ulmit -u shows the maximum number of processes that you can start. However, do not start that many processes in the background: your machine would spend time switching between processes and wouldn't get around to getting actual work done.
The linux does its job of processing your request to create a process, it is for the user to implement his code based on this limit.
The main problem here is determining the best limit. A lot of software doesn't use fork() at all, so do you set the limit to something small like 5? Some software might create a new process whenever it receives a request from network, so do you set the limit to "max. number of network packets"? If you assume most software isn't buggy, then you'd be tempted to set the limit relatively high so that correct software works properly.
The other problem is one of scheduling priorities. In a well designed system things like the GUI would be "high priority" and if it wants CPU time it'd preempt normal/lower priority work immediately. If this was the case, a massive fork bomb running at normal/lower priority would have no effect on the system's ability to respond to the user, and the user would be able to kill the fork bomb without much problem.
Sadly, for a variety of reasons, the scheduler in Linux doesn't work like that. It does support priorities, but to use them you have to be a "real time" process and have to be running as root (which is a massive security disaster). Without sane priorities, Linux assumes that every forked process is as important as everything else, and the CPU/s end up busy doing the forking and there's no CPU time left to respond to the user.

How to prevent linux soft lockup/unresponsiveness in C without sleep

How would be the correct way to prevent a soft lockup/unresponsiveness in a long running while loop in a C program?
(dmesg is reporting a soft lockup)
Pseudo code is like this:
while( worktodo ) {
worktodo = doWork();
}
My code is of course way more complex, and also includes a printf statement which gets executed once a second to report progress, but the problem is, the program ceases to respond to ctrl+c at this point.
Things I've tried which do work (but I want an alternative):
doing printf every loop iteration (don't know why, but the program becomes responsive again that way (???)) - wastes a lot of performance due to unneeded printf calls (each doWork() call does not take very long)
using sleep/usleep/... - also seems like a waste of (processing-)time to me, as the whole program will already be running several hours at full speed
What I'm thinking about is some kind of process_waiting_events() function or the like, and normal signals seem to be working fine as I can use kill on a different shell to stop the program.
Additional background info: I'm using GWAN and my code is running inside the main.c "maintenance script", which seems to be running in the main thread as far as I can tell.
Thank you very much.
P.S.: Yes I did check all other threads I found regarding soft lockups, but they all seem to ask about why soft lockups occur, while I know the why and want to have a way of preventing them.
P.P.S.: Optimizing the program (making it run shorter) is not really a solution, as I'm processing a 29GB bz2 file which extracts to about 400GB xml, at the speed of about 10-40MB per second on a single thread, so even at max speed I would be bound by I/O and still have it running for several hours.
While the posed answer using threads might possibly be an option, it would in reality just shift the problem to a different thread. My solution after all was using
sleep(0)
Also tested sched_yield / pthread_yield, both of which didn't really help. Unfortunately I've been unable to find a good resource which documents sleep(0) in linux, but for windows the documentation states that using a value of 0 lets the thread yield it's remaining part of the current cpu slice.
It turns out that sleep(0) is most probably relying on what is called timer slack in linux - an article about this can be found here: http://lwn.net/Articles/463357/
Another possibility is using nanosleep(&(struct timespec){0}, NULL) which seems to not necessarily rely on timer slack - linux man pages for nanosleep state that if the requested interval is below clock granularity, it will be rounded up to clock granularity, which on linux depends on CLOCK_MONOTONIC according to the man pages. Thus, a value of 0 nanoseconds is perfectly valid and should always work, as clock granularity can never be 0.
Hope this helps someone else as well ;)
Your scenario is not really a soft lock up, it is a process is busy doing something.
How about this pseudo code:
void workerThread()
{
while(workToDo)
{
if(threadSignalled)
break;
workToDo = DoWork()
}
}
void sighandler()
{
signal worker thread to finish
waitForWorkerThreadFinished;
}
void main()
{
InstallSignalHandler;
CreateSemaphore
StartThread;
waitForWorkerThreadFinished;
}
Clearly a timing issue. Using a signalling mechanism should remove the problem.
The use of printf solves the problem because printf accesses the console which is an expensive and time consuming process which in your case gives enough time for the worker to complete its work.

Change priority of the current process in C

On Windows I can do:
HANDLE hCurrentProcess = GetCurrentProcess();
SetPriorityClass(hCurrentProcess, ABOVE_NORMAL_PRIORITY_CLASS);
How can I do the same thing on *nix?
Try:
#include <sys/time.h>
#include <sys/resource.h>
int main(){
setpriority(PRIO_PROCESS, 0, -20);
}
Note that you must be running as superuser for this to work.
(for more info, type 'man setpriority' at a prompt.)
If doing something like this under unix your want to (as root) chmod you task and set the s bit. Then you can change who you are running as, what your priority is, your thread scheduling, etc. at run time.
It is great as long as you are not writing a massively multithreaded app with a bug in it so that you take over a 48 CPU box and nobody can shut you down because your have each CPU spinning at 100% with all thread set to SHED_FIFO (runs to completion) running as root.
Nah .. I wouldn't be speaking from experience ....
# allain Can you lower your own process' priority without being superuser?
Sure. Be aware, however, that this is a one way street. You can't even get back to where you started. And even fairly small reductions in priority can have startlingly large effects on running time when there is significant load on the system.

Resources