Im currently writing a small c program that makes repeated calls to lua functions in a tight loop - and im using luajit to speed things up. One of my requirements is to restrict the standard libraries available to the script. According to this answer, using lua_call to call luaopen_* is the way to do this, however this results in a massive performance hit over using luaL_openlibs.
A small test case of this:
test.c
// gcc -Wall -O3 -o test test.c -lm $(pkg-config --cflags --libs luajit)
#include <luajit.h>
#include <lualib.h>
#include <luaconf.h>
#include <lauxlib.h>
lua_State *LUA = NULL;
int lua_setup(char *filename) {
LUA = luaL_newstate();
// lua_pushcfunction(LUA, luaopen_math);
// lua_pushstring(LUA, LUA_MATHLIBNAME);
// lua_call(LUA, 1, 0);
luaL_openlibs(LUA);
luaL_loadfile(LUA, filename);
lua_pcall(LUA, 0, 0, 0);
return 1;
}
int main() {
lua_setup("test.lua");
for (int i = 0; i < 10000; i++) {
lua_getglobal(LUA, "test");
lua_call(LUA, 0, 1);
float ret = lua_tonumber(LUA, -1);
lua_pop(LUA, 1);
}
lua_close(LUA);
}
test.lua
function test()
r = 0
for i=0,10000 do
r = r + math.sin(i);
r = r % 2;
end
return r
end
results:
> time ./test
real 0m1.696s
user 0m1.650s
sys 0m0.000s
after replacing the luaL_openlibs with the commented-out lines
> time ./test
real 0m6.409s
user 0m6.239s
sys 0m0.004s
Could someone tell me why this occurs? Thanks.
Ok turns out im an idiot. Luajit includes a lua library that needs to be loaded. Adding the following fixed the problem.
lua_pushcfunction(LUA, luaopen_jit);
lua_pushstring(LUA, LUA_JITLIBNAME);
lua_call(LUA, 1, 0);
Related
I'm trying to implement an error handler using the clock() function from the "time.h" library. The code runs inside an embeeded system (Colibri IMX7 - M4 Processor). The function is used to monitor a current value within a specific range, if the value of the current isn't correct the function should return an error message.
The function will see if the error is ocurring and in the first run it will save the first appearance of the error in a clock_t as reference, and then in the next runs if the error is still there, it will compare the current time using clock() with the previous reference and see if it will be longer than a specific time.
The problem is that the function clock() is always returning -1. What should I do to avoid that? Also, why can't I declare a clock_t variable as static (e.g. static clock_t start_t = clock()?
Please see below the function:
bool CrossLink_check_error_LED_UV_current_clock(int current_state, int current_at_LED_UV)
{
bool has_LED_UV_current_deviated = false;
static int current_number_of_errors_Current_LED_CANNON = 0;
clock_t startTimeError = clock();
const int maximum_operational_current_when_on = 2000;
const int minimum_turned_on_LED_UV_current = 45;
if( (current_at_LED_UV > maximum_operational_current_when_on)
||(current_state!=STATE_EMITTING && (current_at_LED_UV > minimum_turned_on_LED_UV_current))
||(current_state==STATE_EMITTING && (current_at_LED_UV < minimum_turned_on_LED_UV_current)) ){
current_number_of_errors_Current_LED_CANNON++;
if(current_number_of_errors_Current_LED_CANNON > 1) {
if (clock() - startTimeError > 50000){ // 50ms
has_LED_UV_current_deviated = true;
PRINTF("current_at_LED_UV: %d", current_at_LED_UV);
if(current_state==STATE_EMITTING){
PRINTF(" at state emitting");
}
PRINTF("\n\r");
}
}else{
if(startTimeError == -1){
startTimeError = clock();
}
}
}else{
startTimeError = 0;
current_number_of_errors_Current_LED_CANNON = 0;
}
return has_LED_UV_current_deviated;
}
Edit: I forgot to mention before, but we are using GCC 9.3.1 arm-none-eabi compiler with CMake to build the executable file. We have an embedeed system (Colibri IMX7 made by Toradex) that consists in 2 A7 Processors that runs our Linux (more visual interface) and the program that is used to control our device runs in a M4 Processor without an OS, just pure bare-metal.
For a lot of provided functions in the c standard library, if you have the documentation installed (usually it gets installed with the compiler), you can view documentation using the man command in the shell. With man clock, it tells me that:
NAME
clock - determine processor time
SYNOPSIS
#include <time.h>
clock_t clock(void);
DESCRIPTION
The clock() function returns an approximation of processor time used by the program.
RETURN VALUE
The value returned is the CPU time used so far as a clock_t; to get the number of seconds used, divide by
CLOCKS_PER_SEC. If the processor time used is not available or its value cannot be represented, the function
returns the value (clock_t) -1.
etc.
This tells us that -1 means that the processor time (CLOCK_PROCESS_CPUTIME_ID) is unavailable. The solution is to use CLOCK_MONOTONIC instead. We can select the clock we want to use with clock_gettime.
timespec clock_time;
if (clock_gettime(CLOCK_MONOTONIC, &clock_time)) {
printf("CLOCK_MONOTONIC is unavailable!\n");
exit(1);
}
printf("Seconds: %d Nanoseconds: %ld\n", clock_time.tv_sec, clock_time.tv_nsec);
To answer the second part of your question:
static clock_t start_time = clock();
is not allowed because the return value of the function clock() is not known until runtime, but in C the initializer of a static variable must be a compile-time constant.
You can write:
static clock_t start_time = 0;
if (start_time == 0)
{
start_time = clock();
}
But this may or may not be suitable to use in this case, depending on whether zero is a legitimate return value of the function. If it could be, you would need something like:
static bool start_time_initialized = false;
static clock_t start_time;
if (!start_time_initialized)
{
start_time_initialized = true;
start_time = clock();
}
The above is reliable only if you cannot have two copies of this function running at once (it is not re-entrant).
If you have a POSIX library available you could use a pthread_once_t to do the same as the above bool but in a re-entrant way. See man pthread_once for details.
Note that C++ allows more complicated options in this area, but you have asked about C.
Note also that abbreviating "start time" as start_t is a very bad idea, because the suffix _t means "type" and should only be used for type names.
in the end the problem was that since we are running our code on bare metal, the clock() function wasn't working. We ended up using an internal timer on the M4 Processor that we found, so now everything is fine. Thanks for the answers.
I have installed mipsel-linux-gcc in the pictrue
Now I have a file simd.c
#include<stdio.h>
#include"simdType.h"
int main()
{
v4i32 m,t;
v4f32 a,b,c,s;
a=b+c;
t=b<c;
s = __builtin_shuffle(b,c,m);
return 0;
}
then I run this command:
mipsel-linux-gcc -S simd.c -mfp64 -Wa,-mmsa -mhard-float
then I get simd.s, but it's not in simd format.
Who can help me ? Thanks!
I want to change the font size when my application window moves from one monitor to another depending on the underlying dpi of destination monitor.
I played with xrandr, xdpyinfo and xlib. I looked at the source code but I couldn't find a way to associate the monitor on which the window (window id) is placed.
Qt has QDesktopWidget, which provides physicalDpiX/Y but only (so it seems) for the primary monitor.
xrandr.h contains XRROutputInfo which delivers mm_width and mm_height, but how can I make the connection to a window id?
Since this question got some attention, I want so share my research. I haven not found a perfect solution. It looks like it's not possible.
But playing with the following code snip will probably help you. The idea is to calculate the underlying display by comparing the window position. If the position is larger then the first screen's resolution, and must be the 2nd monitor. Pretty straight forward.
#include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h>
#include <stdio.h>
#include <stdlib.h>
// compile: g++ screen_dimension.cpp -lX11 -lXrandr
int main()
{
int wid = atoi( getenv( "WINDOWID" ) );
printf("window id: %i\n", wid);
Display * dpy = XOpenDisplay(NULL);
int screen = DefaultScreen(dpy);
Window root = DefaultRootWindow(dpy);
XRRScreenResources * res = XRRGetScreenResourcesCurrent(dpy, root);
XRROutputInfo * output_info;
for (int i = 0; i < res->noutput; i++)
{
output_info = XRRGetOutputInfo (dpy, res, res->outputs[i]);
if( output_info->connection ) continue; // No connection no crtcs
printf(" (%lu %lu) mm Name: %s connection: %i ncrtc: %i \n", output_info->mm_width
, output_info->mm_height
, output_info->name
, output_info->connection
, output_info->ncrtc
);
}
printf("crtcs:\n");
for( int j = 0; j < output_info->ncrtc; j++ ) {
XRRCrtcInfo * crtc_info = XRRGetCrtcInfo( dpy, res, res->crtcs[ j ] );
if( not crtc_info->noutput ) continue;
printf("%i w: %5i h: %5i x: %5i y: %i\n", j
, crtc_info->width
, crtc_info->height
, crtc_info->x
, crtc_info->y
);
}
}
There are actually 2 functions to query resources about the screens:
XRRGetScreenResourcesCurrent and XRRGetScreenResources. The first one returns some cached value, while the latter one asks the server which may introduce polling. The description (search for RRGetScreenResources):
https://www.x.org/releases/X11R7.6/doc/randrproto/randrproto.txt
Someone went through the trouble timing it:
https://github.com/glfw/glfw/issues/347
XRRGetScreenResourcesCurrent: Tipically from 20 to 100 us. h
XRRGetScreenResources: Typically from 13600 to 13700 us.
Ok, since there is no further discussion here and I am convinced my little program (see above) works, I declare it now as: Answered!
Compile instructions are
g++ screen_dimension.cpp -lX11 -lXrandr
(also added as comment above)
Why so complicated ?! Just get the info from screen where your window is attached.
double dDisplayDPI_H,dDisplayDPI_V;
dDisplayDPI_H = ((double)DisplayWidth( dpy, scr ))/(((double)DisplayWidthMM( dpy, scr ))/25.4);
dDisplayDPI_V = ((double)DisplayHeight( dpy, scr ))/(((double)DisplayHeightMM( dpy, scr ))/25.4);
Why would I need this?
The location of a datum keeps changing because input data varies too much, so other than printing it, sleeping for 30 seconds so I can manually enter it into GDB, then continuing the program, it might be useful to just let the program tell GDB where to watch.
But is such a thing possible?
You can get close; assuming for simplicity C/C++ language
Define a function that returns a reference to your datum to track:
// debug.h
extern "C" mydatastruct* GetDatumForDebug();
// debug.cpp
mydatastruct* GetDatumForDebug()
{
if (s_initialized)
return &some_complicated_address_lookup_perhaps_in_Cpp_or_java_orwhatever();
return (mydatastruct*) 0;
}
You can then subsequently just
(gdb) display GetDatumForDebug()
or even
(gdb) display GetDatumForDebug()->s
I assume it will be possible to use the result of GetDatumForDebug() in your debug watches, I'm not sure what you do/how you do that :)
Here is a working example, crammed in a single source (test.cpp) for speed: compile with g++ -g test.cpp -o test:
static bool s_initialized = false;
struct mydatastruct { const char* s; };
static mydatastruct& some_complicated_address_lookup_perhaps_in_Cpp_or_java_orwhatever()
{
static mydatastruct s_instance = { "hello world" };
s_initialized = true;
return s_instance;
}
extern "C" mydatastruct* GetDatumForDebug();
// debug.cpp
mydatastruct* GetDatumForDebug()
{
if (s_initialized)
return &some_complicated_address_lookup_perhaps_in_Cpp_or_java_orwhatever();
return (mydatastruct*) 0;
}
int main()
{
// force initialize for demo purpose:
some_complicated_address_lookup_perhaps_in_Cpp_or_java_orwhatever();
return 42;
}
Automate gdb commands
Append the following to .gdbinit in your working directory:
break main
run
call some_complicated_address_lookup_perhaps_in_Cpp_or_java_orwhatever()
display GetDatumForDebug()? GetDatumForDebug()->s : ""
This will automatically execute these commands on launching gdb in that directory
How to check whether a system is big endian or little endian?
In C, C++
int n = 1;
// little endian if true
if(*(char *)&n == 1) {...}
See also: Perl version
In Python:
from sys import byteorder
print(byteorder)
# will print 'little' if little endian
Another C code using union
union {
int i;
char c[sizeof(int)];
} x;
x.i = 1;
if(x.c[0] == 1)
printf("little-endian\n");
else printf("big-endian\n");
It is same logic that belwood used.
A one-liner with Perl (which should be installed by default on almost all systems):
perl -e 'use Config; print $Config{byteorder}'
If the output starts with a 1 (least-significant byte), it's a little-endian system. If the output starts with a higher digit (most-significant byte), it's a big-endian system. See documentation of the Config module.
In C++20 use std::endian:
#include <bit>
#include <iostream>
int main() {
if constexpr (std::endian::native == std::endian::little)
std::cout << "little-endian";
else if constexpr (std::endian::native == std::endian::big)
std::cout << "big-endian";
else
std::cout << "mixed-endian";
}
If you are using .NET: Check the value of BitConverter.IsLittleEndian.
In Rust (no crates or use statements required)
In a function body:
if cfg!(target_endian = "big") {
println!("Big endian");
} else {
println!("Little endian");
}
Outside a function body:
#[cfg(target_endian = "big")]
fn print_endian() {
println!("Big endian")
}
#[cfg(target_endian = "little")]
fn print_endian() {
println!("Little endian")
}
This is what the byteorder crate does internally: https://docs.rs/byteorder/1.3.2/src/byteorder/lib.rs.html#1877
In Powershell
[System.BitConverter]::IsLittleEndian
In Linux,
static union { char c[4]; unsigned long mylong; } endian_test = { { 'l', '?', '?', 'b' } };
#define ENDIANNESS ((char)endian_test.mylong)
if (ENDIANNESS == 'l') /* little endian */
if (ENDIANNESS == 'b') /* big endian */
A C++ solution:
namespace sys {
const unsigned one = 1U;
inline bool little_endian()
{
return reinterpret_cast<const char*>(&one) + sizeof(unsigned) - 1;
}
inline bool big_endian()
{
return !little_endian();
}
} // sys
int main()
{
if(sys::little_endian())
std::cout << "little";
}
In Rust (byteorder crate required):
use std::any::TypeId;
let is_little_endian = TypeId::of::<byteorder::NativeEndian>() == TypeId::of::<byteorder::LittleEndian>();
Using Macro,
const int isBigEnd=1;
#define is_bigendian() ((*(char*)&isBigEnd) == 0)
In C
#include <stdio.h>
/* function to show bytes in memory, from location start to start+n*/
void show_mem_rep(char *start, int n)
{
int i;
for (i = 0; i < n; i++)
printf("%2x ", start[i]);
printf("\n");
}
/*Main function to call above function for 0x01234567*/
int main()
{
int i = 0x01234567;
show_mem_rep((char *)&i, sizeof(i));
return 0;
}
When above program is run on little endian machine, gives “67 45 23 01” as output , while if it is run on big endian machine, gives “01 23 45 67” as output.
A compilable version of the top answer for n00bs:
#include <stdio.h>
int main() {
int n = 1;
// little endian if true
if(*(char *)&n == 1) {
printf("Little endian\n");
} else {
printf("Big endian\n");
}
}
Stick that in check-endianness.c and compile and run:
$ gcc -o check-endianness check-endianness.c
$ ./check-endianness
This whole command is a copy/pasteable bash script you can paste into your terminal:
cat << EOF > check-endianness.c
#include <stdio.h>
int main() {
int n = 1;
// little endian if true
if(*(char *)&n == 1) {
printf("Little endian\n");
} else {
printf("Big endian\n");
}
}
EOF
gcc -o check-endianness check-endianness.c \
&& ./check-endianness \
&& rm check-endianness check-endianness.c
The code is in a gist here if you prefer. There is also a bash command that you can run that will generate, compile, and clean up after itself.
In Nim,
echo cpuEndian
It is exported from the system module.
In bash (from How to tell if a Linux system is big endian or little endian?):
endian=`echo -n "I" | od -to2 | head -n1 | cut -f2 -d" " | cut -c6`
if [ "$endian" == "1" ]; then
echo "little-endian"
else
echo "big-endian"
fi
C logic to check whether your processor follows little endian or big endian
unsigned int i =12345;
char *c = (char *)&i; // typecast int to char* so that it points to first bit of int
if(*c != 0){ // If *c points to 0 then it is Big endian else Little endian
printf("Little endian");
}
else{
printf("Big endian");
}
Hope this helps. Was one of the question asked in my interview for the role of embedded software engineer role
All the answers using a program to find endianess at runtime is wrong! The fact whether a machine is big endian or little endian is hidden from the programmer, by the compiler. On a big-endian machine the typecast will again return 1, because the compiler knows that the machine is big endian and the casting will fetch the higher memory address. Only way to find the endianess is to fetch the system's configuration or environment variable. Similar to some of the answers above like the one liner perl answer etc.