i have recently started using threads ,so pretty new to this stuff. please no hate .i was working on a program which would calculate prime numbers till a limit N provided through the command line.
i would distribute this N to num_threads i.e. 4 .lets say the number is 40 and num_threads=4 then each thread should get 10 indexes.i created a structure containing the upper and lower limits for each thread.i passed a pointer of this structure and used the "high" and "low" attributes of this structure to control the flow.
there seems to be some kind of problem.if anyone of you can point out the mistake or tell me if this is the right thing to do i would be pretty grateful :)
geany gives the the following errors:
g++ -Wall -o "prime5000" "prime5000.cpp" (in directory: /home/jarrar/operating systems/threads)
/tmp/ccAHGsIw.o: In function `main':
prime5000.cpp:(.text+0xc9): undefined reference to `pthread_create'
prime5000.cpp:(.text+0xf6): undefined reference to `pthread_join'
collect2: error: ld returned 1 exit status
Compilation failed.
if executed from the terminal using the following command:
g++ prime5000.cpp -lpthread -o 5prime
./5prime
it will give :
Segmentation fault(Core dump)
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#define num_thread 4
void* calc(void* param);
struct fml
{
long low;
long high;
};
fml* x;
int main(int argc,char* argv[])
{
pthread_t threadArray[num_thread];
int thread;
for(thread=0;thread<num_thread;thread++)
{
x->low=thread*atoi(argv[1])/num_thread;
x->high=x->low+(thread+1)*atoi(argv[1])/num_thread;
pthread_create(&threadArray[thread],NULL,calc,&x);
}
int i;
for(i=0;i<num_thread;i++)
{
pthread_join(threadArray[i],NULL);
}
return 0;
}
void* calc(void* param)
{
fml* temp=(fml*)param;
long lowerLimit=temp->low;
long upperLimit=temp->high;
int i;
int j;
for(i=lowerLimit;i<upperLimit;i++)
{
for(j=2;j<i;j++)
{ if(i!=1||i!=0)
{
if(!(i%j==0))
{
printf("%d ",i);
}
}
}
}
pthread_exit(NULL);
}
Related
This is an exercise that I want to implement in real code
I send a signal to my app (x86-64 linux). My app then executes code that walks the stack and prints out instruction pointers. I'm not sure if I want only the last few or everything to main. Anyway, I'm releasing an optimized binary without debug information. I strip symbols before its distributed.
I was wondering, how do I translate it back? I don't need to translate it in the app. I can use the machine I build to go from rip's to functions. I was thinking maybe I should also distribute one with debug information and maybe have the user be able to see the function+line but I think line will be unlikely if its optimized well
Another problem I have is my code doesn't seem to walk past the signal function. backtrace figures it out but I'm trying to do this without libc. Here's some code
#include <signal.h>
#include <cstdio>
typedef unsigned long long u64;
int mybacktrace();
#include <execinfo.h>
#include <unistd.h>
void print_stacktrace(void) {
size_t size;
enum Constexpr { MAX_SIZE = 1024 };
void *array[MAX_SIZE];
size = backtrace(array, MAX_SIZE);
backtrace_symbols_fd(array, size, STDOUT_FILENO);
}
void mysig(int signo) {
mybacktrace();
_exit(1);
}
int mybacktrace() {
u64*p;
p = (u64*)((u64)&p + 16); //seems to work correctly
for (int i = 0; i < 10 && (u64)p >= 1<<16; i++)
{
printf("%d %p\n", i, p[1]);
p = (u64*)(p[0]);
}
print_stacktrace(); return 0;
return 0;
}
int test()
{
return mybacktrace();
}
int main(int argc, char *argv[])
{
signal(SIGILL, mysig);
test();
__builtin_trap();
return 0;
}
I am new to c programming on Linux. My objective is to create an efficient program to monitor free space on a mounted partition (parm1) and put an icon in the tray to represent it showing my name (parm2) for it and the percentage of free space (script to calculate parm3), run that script every xxx seconds (parm4) and refresh the icon if the value changes (icon filename parm5).
For starters I have just copied a sample c program from here and am just trying to get it to compile and run as is, to embed a program with an icon in the tray.
freedesktop XEmbed systray client code in C, Xlib
I tweaked it to incorporate suggested changes and remove errors, and it compiles clean, but appears to need lib(s) added to be able to create an executable.
How do I find out what libraries are needed, and what order to put them in?
/* from: https://stackoverflow.com/questions/45392284/freedesktop-xembed-systray-client-code-in-c-xlib */
#include <X11/Xutil.h>
#include <string.h>
#include <unistd.h>
#define MIN(A, B) ((A) < (B) ? (A) : (B))
/* --------- XEMBED and systray stuff */
#define SYSTEM_TRAY_REQUEST_DOCK 0
#define SYSTEM_TRAY_BEGIN_MESSAGE 1
#define SYSTEM_TRAY_CANCEL_MESSAGE 2
int usleep(useconds_t useconds); //pass in microseconds
static int trapped_error_code = 0;
static int (*old_error_handler) (Display *, XErrorEvent *);
static int
error_handler(Display *display, XErrorEvent *error) {
trapped_error_code = error->error_code;
return 0;
}
void
trap_errors(void) {
trapped_error_code = 0;
old_error_handler = XSetErrorHandler(error_handler);
}
int
untrap_errors(void) {
XSetErrorHandler(old_error_handler);
return trapped_error_code;
}
void
send_systray_message(Display* dpy, long message, long data1, long data2, long data3) {
XEvent ev;
Atom selection_atom = XInternAtom (dpy,"_NET_SYSTEM_TRAY_S0",False);
Window tray = XGetSelectionOwner (dpy,selection_atom);
if ( tray != None)
XSelectInput (dpy,tray,StructureNotifyMask);
memset(&ev, 0, sizeof(ev));
ev.xclient.type = ClientMessage;
ev.xclient.window = tray;
ev.xclient.message_type = XInternAtom (dpy, "_NET_SYSTEM_TRAY_OPCODE", False );
ev.xclient.format = 32;
ev.xclient.data.l[0] = CurrentTime;
ev.xclient.data.l[1] = message;
ev.xclient.data.l[2] = data1; // <--- your window is only here
ev.xclient.data.l[3] = data2;
ev.xclient.data.l[4] = data3;
trap_errors();
XSendEvent(dpy, tray, False, NoEventMask, &ev);
XSync(dpy, False);
usleep(10000);
if (untrap_errors()) {
/* Handle errors */
}
}
/* ------------ Regular X stuff */
int
main(int argc, char **argv) {
int width, height;
XWindowAttributes wa;
XEvent ev;
Display *dpy;
int screen;
Window root, win;
/* init */
if (!(dpy=XOpenDisplay(NULL)))
return 1;
screen = DefaultScreen(dpy);
root = RootWindow(dpy, screen);
if(!XGetWindowAttributes(dpy, root, &wa))
return 1;
width = height = MIN(wa.width, wa.height);
/* create window */
win = XCreateSimpleWindow(dpy, root, 0, 0, width, height, 0, 0, 0xFFFF9900);
/* call send_systray_messsage */
send_systray_message(dpy, SYSTEM_TRAY_REQUEST_DOCK, win, 0, 0); // pass win only once
XMapWindow(dpy, win);
XSync(dpy, False);
/* run */
while(1) {
while(XPending(dpy)) {
XNextEvent(dpy, &ev); /* just waiting until we error because window closed */
}
}
}
$ gcc xmbed_system_tray.c -o xmbed_system_tray
/usr/bin/ld: /tmp/ccs2ZnYg.o: in function `trap_errors':
xmbed_system_tray.c:(.text+0x3a): undefined reference to `XSetErrorHandler'
/usr/bin/ld: /tmp/ccs2ZnYg.o: in function `untrap_errors':
xmbed_system_tray.c:(.text+0x57): undefined reference to `XSetErrorHandler'
/usr/bin/ld: /tmp/ccs2ZnYg.o: in function `send_systray_message':
xmbed_system_tray.c:(.text+0xa8): undefined reference to `XInternAtom'
/usr/bin/ld: xmbed_system_tray.c:(.text+0xc2): undefined reference to `XGetSelectionOwner'
/usr/bin/ld: xmbed_system_tray.c:(.text+0xe8): undefined reference to `XSelectInput'
/usr/bin/ld: xmbed_system_tray.c:(.text+0x131): undefined reference to `XInternAtom'
/usr/bin/ld: xmbed_system_tray.c:(.text+0x1ab): undefined reference to `XSendEvent'
/usr/bin/ld: xmbed_system_tray.c:(.text+0x1bf): undefined reference to `XSync'
/usr/bin/ld: /tmp/ccs2ZnYg.o: in function `main':
xmbed_system_tray.c:(.text+0x1f3): undefined reference to `XOpenDisplay'
/usr/bin/ld: xmbed_system_tray.c:(.text+0x24f): undefined reference to `XGetWindowAttributes'
/usr/bin/ld: xmbed_system_tray.c:(.text+0x2b2): undefined reference to `XCreateSimpleWindow'
/usr/bin/ld: xmbed_system_tray.c:(.text+0x2ed): undefined reference to `XMapWindow'
/usr/bin/ld: xmbed_system_tray.c:(.text+0x2fe): undefined reference to `XSync'
/usr/bin/ld: xmbed_system_tray.c:(.text+0x316): undefined reference to `XNextEvent'
/usr/bin/ld: xmbed_system_tray.c:(.text+0x322): undefined reference to `XPending'
collect2: error: ld returned 1 exit status
I didn't find any videos that showed anything, but I did find a site where he shows possible libraries or maybe locations. Therefore, I am guessing that either my environment is setup wrong so it can't find what it's looking for, or what it's looking for isn't installed.
http://mech.math.msu.su/~nap/2/GWindow/xintro.html
That didn't help, but I eventually found another page that did at:
https://en.wikibooks.org/wiki/X_Window_Programming/Xlib
Their sample program had compile instructions:
To Compile: gcc -O2 -Wall -o test test.c -L /usr/X11R6/lib -lX11 -lm
So for mine I tried:
gcc -o xmbed_system_tray xmbed_system_tray.c -lX11
By removing options one at a time I found the -lX11 parameter not being there before was causing the failure, and now the executable gets created and will run.
The program only consumes about 1 mb of memory compared to 25 to 35 mb for the other programs I found capable of running a program in the tray.
As we all know, perf is the tool to get the CPU performance counter for a program, such as cache-miss, cache-reference, instruction executed etc.
Question :
How to get those performance counters for just a piece of code (such as a function) in one program in c or c++.
For example, my program firstly do some initializing, then do the work, then finalize, i just want to get the performance counter for the work, such as function do_something_1 .
int main(int argc, char ** argv) {
do_initialize();
for (int i = 0;i < 100 ;i ++) {
/* begin profile code */
do_something_1();
/* end profile code */
do_something_2();
}
do_finalize();
}
Finally, i found a library to get those counter for a piece of code.
PAPI
For example, if you want to measure L3 data cache read for some piece of code.
#include "papi.h"
#include <iostream>
#include <glog/logging.h>
#define ASIZE 2684354560
#define event_count (1) // the number of event you want to trace
int main(int argc, char ** argv) {
int events[event_count] = {PAPI_L3_DCR}; // L3 Data Cache Read
int ret;
long long int values[event_count]; // result
int* array = new int [ASIZE ];
/* start counters */
ret = PAPI_start_counters(events, event_count);
CHECK_EQ(ret, PAPI_OK);
size_t tot_cnt = 1;
for(size_t cnt = 0; cnt < tot_cnt; cnt ++) {
for(size_t i = 0;i < ASIZE ;i ++) {
array[i] = i;
}
}
/* read counters */
ret = PAPI_read_counters(values, event_count);
CHECK_EQ(ret, PAPI_OK);
for(size_t i = 0;i < event_count ;i ++) {
LOG(INFO) << " " << values[i];
}
return 0;
}
Makefile :
CXX?=g++
INC?=-I<path to where papi is installed>/include/
LIB?=-L<path to where papi is installed>/lib/ -lpapi -lglog
main : main.cpp
${CXX} -O3 ${INC} -o $# $< ${LIB}
all : main
.PHONY:
clean :
rm -f main
You can use operf (oprofile).
In short:
# Build you program with debugging information
# Start up the profiler
operf /path/to/mybinary
# generate a profile summary
opreport --symbols
# produce some annotated source
opannotate --source --output-dir=/path/to/annotated-source
Example annotated output:
$ opannotate --source --output-dir=/home/moz/src/annotated `which oprofiled`
$ vi /home/moz/src/annotated/home/moz/src/oprofile/daemon/opd_image.c # the annotated source output
...
:static uint64_t pop_buffer_value(struct transient * trans)
254 2.4909 :{ /* pop_buffer_value total: 2105 20.6433 */
: uint64_t val;
:
160 1.5691 : if (!trans->remaining) {
: fprintf(stderr, "BUG: popping empty buffer !\n");
: exit(EXIT_FAILURE);
: }
:
: val = get_buffer_value(trans->buffer, 0);
123 1.2062 : trans->remaining--;
65 0.6374 : trans->buffer += kernel_pointer_size;
: return val;
230 2.2556 :}
Examples
I did do some survey to solving the same problem in my project. I did find another framework called SkyPat (https://skypat.skymizer.com) which can get the PMU counters for a piece of code like PAPI.
I have tried both of PAPI and SkyPat to get the PMU counters for a function. I think the difference between of them is that SkyPat combines unit tests and perf_evnet. It refers the concept of Google Test and provides an interface to access PMU, so it’s easy to integrate with Google Test.
For example, if you want to measure cache references and cache for a function.
#include <unistd.h>
#include "pat/pat.h"
#include "test.h"
PAT_F(MyCase, my_test)
{
int result = 0;
COUNT(pat::CONTEXT_SWITCHES) {
test(10);
}
COUNT(pat::CPU_CLOCK) {
test(10);
}
COUNT(pat::TASK_CLOCK) {
test(10);
}
COUNT(pat::CACHE_REFERENCES) {
test(10);
}
COUNT(pat::CACHE_MISSES) {
test(10);
}
}
int main(int argc, char* argv[])
{
pat::Test::Initialize(&argc, argv);
pat::Test::RunAll();
}
And the result log of SkyPat.
[ pat ] Running 1 tests from 1 cases.
[----------] 1 test from MyCase.
[ RUN ] MyCase.my_test
[ TIME (ns)] 2537 1000 843 1855 1293
[EVENT TYPE] [CTX SWITCH] [CPU CLOCK] [TASK CLOCK] [CACHE REF] [CACHE MISS]
[RESULT NUM] 0 982 818 2 0
[==========] 1 test from 1 cases ran.
[ PASSED ] 1 test.
It sounds you look for profiling.
As you say you are under linux so have a look for gprof toolchain. Simply you have to compiler your prog with some compiler options and start your program. gprof after that inspect the generated profiling data and provide a result which contains information's for each code block.
First: Compile your prog with additional options:
g++ <source> -c -g -pg
...
Second: Link, you also need these options!
g++ <object1> <object2> ... <objectn> -g -pg -o <target>
Third: run your prog
./<target>
After that, get statistics:
gprof <target>
I am facing the same situation as yours and I did some study on this. Here is what I learned. Firstly, perf is included as a part of kernel and you could check its headers in
/usr/src/kernels/$VERSION/include/linux/perf_regs.h
/usr/src/kernels/$VERSION/include/linux/perf_event.h
/usr/src/kernels/$VERSION/include/uapi/linux/perf_event.h
And I think the core file is perf_event.h
You could also check its github website which has some clarification on how to use it. But it is not clear and now I still have many confusions.
In addition, I found a library very useful called pfmlib which is a helper library to program the perf events. It has examples and perf_examples for instructing how to do this in code-level. I am still working on it. Hope this help you. If you have some questions, we could study from each other.
The website of pfmlib is http://perfmon2.sourceforge.net.
#include<stdio.h>
#include<math.h>
#include<pthread.h>
#include<stdlib.h>
long double x,fact[150],pwr[150],s[1];
int i,term;
void *Power(void *temp)
{
int k;
for(k=0;k<150;k++)
{
pwr[k] = pow(x,k);
//printf("%.2Lf\n",pwr[k]);
}
return pwr;
}
void *Fact(void *temp)
{
long double f;
int j;
fact[0] = 1.0;
for(term=1;term<150;term++)
{
f = 1.0;
for(j=term;j>0;j--)
f = f * j;
fact[term] = f;
//printf("%.2Lf\n",fact[term]);
}
return fact;
}
void *Exp(void *temp)
{
int t;
s[0] = 0;
for(t=0;t<150;t++)
s[0] = s[0] + (pwr[t] / fact[t]);
return s;
}
int main(void)
{
pthread_t thread1,thread2,thread3;
printf("Enter the value of x (between 0 to 100) (for calculating exp(x)) : ");
scanf("%Lf",&x);
printf("\nThreads creating.....\n");
pthread_create(&thread1,NULL,Power,NULL); //calling power function
pthread_create(&thread2,NULL,Fact,NULL); //calling factorial function
printf("Threads created\n");
pthread_join(thread1,NULL);
pthread_join(thread2,NULL);
printf("Master thread and terminated threads are joining\n");
printf("Result collected in Master thread\n");
pthread_create(&thread3,NULL,Exp,NULL);
pthread_join(thread3,NULL);
printf("\nValue of exp(%.2Lf) is : %Lf\n\n",x,s[0]);
exit(1);
}
I was trying to run the above program in linux ubuntu. It is giving following errors
parallelcomp.cpp:(.text+0x1ec): undefined reference to `pthread_create'
parallelcomp.cpp:(.text+0x207): undefined reference to `pthread_create'
parallelcomp.cpp:(.text+0x222): undefined reference to `pthread_join'
parallelcomp.cpp:(.text+0x233): undefined reference to `pthread_join'
parallelcomp.cpp:(.text+0x262): undefined reference to `pthread_create'
parallelcomp.cpp:(.text+0x273): undefined reference to `pthread_join'
The error is mostprobably due to linking binary with pthreads.
Is there any command in ubuntu terminal whcih can solve this problem.?
I have tried with several commands given in this community forum, non of them is helpful.
Is there anyone who would like to help me?
I am also very new to Linux ubuntu.
Any kind of suggestion is appreciable.
How to include libpthread ?
When I am putting the following command, gcc -pthread -o term term.c, in terminalwe i get the following error: Command line option 'p' [from -pthread] is not known.
Please try the following -lpthread. Which version of gcc are you using?
Why do I get "undefined reference" errors even when I include the right header files?
While compiling add link to pthread library -lpthread
this is my 1.c content
#include "2.h"
#include<stdio.h>
#include<string.h>
void push(int ele)
{
stack[tos]=ele;
tos++;
}
char pop()
{
tos--;
return(stack[tos]);
}
void show()
{
int x=tos;
printf("--The Stack elements are.....");
while(x!=0)
printf("%c, ",stack[--x]);
}
//Function to get the precedence of an operator
int prec(char symbol)
{
if(symbol== '(')
return 0;
if(symbol== ')')
return 0;
if(symbol=='+' || symbol=='-')
return 1;
if(symbol=='*' || symbol=='/')
return 2;
if(symbol=='^')
return 3;
return 0;
}
and this is my 2.h content
#define size 10
char stack[size];
int tos=0,ele;
void push();
char pop();
void show();
int isempty();
int isfull();
char infix[30], output[30];
int prec(char);
and my main.c content is
#include "2.h"
#include<stdio.h>
#include<string.h>
int main()
{
int i=0,j=0,k=0,length;
char temp;
printf("\nEnter an infix expression:");
scanf("%s",infix);
printf("\nThe infix expresson is %s",infix);
length=strlen(infix);
for(i=0;i<length;i++)
{
//Numbers are added to the out put QUE
if(infix[i]!='+' && infix[i]!='-' && infix[i]!='*' && infix[i]!='/' &&
infix[i]!='^' && infix[i]!=')' && infix[i]!='(' )
{
output[j++]=infix[i];
printf("\nThe element added to Q is:%c",infix[i]);
}
//If an operator or a bracket is encountered...
else
{
if(tos==0) //If there are no elements in the stack, the operator is added to it
{
push(infix[i]);
printf("\nThe pushed element is:%c",infix[i]);
}
else
{
//Operators or pushed or poped based on the order of precedence
if(infix[i]!=')' && infix[i]!='(')
{
if(prec(infix[i]) <= prec(stack[tos-1]))
{
temp=pop();
printf("\n the poped element is :%c",temp);
output[j++]=temp;
push(infix[i]);
printf("\n The pushed element is :%c",infix[i]);
show();
}
else
{
push(infix[i]);
printf("\nThe pushed element is:%c",infix[i]);
show();
}
}
else
{
if(infix[i]=='(')
{
push(infix[i]);
printf("\nThe pushed-- element is:%c",infix[i]);
}
if(infix[i]==')')
{
temp=pop();
while(temp!='(')
{
output[j++]=temp;
printf("\nThe element added to Q is:%c",temp);
//temp=pop();
printf("\n the poped element is :%c",temp);
temp=pop();
}
}
}
}
}
printf("\nthe infix expression is: %s",output);
}
while(tos!=0)
{
output[j++]=pop();
}
printf("the infix expression is: %s\n",output);
}
i am doing this using MAKE in linux
the code is
myapp: main.o 1.o
gcc -o myapp main.c 1.c
main.o: main.c 2.h
gcc -c main.c
1.o: 1.c 2.h
gcc -c 1.c
but iin coming the error coming
gcc -o myapp main.c 1.c
/tmp/ccy0qyI1.o:(.bss+0x0): multiple definition of `tos'
/tmp/ccQZzbOI.o:(.bss+0x0): first defined here
collect2: ld returned 1 exit status
make: *** [myapp] Error 1
i m trying to fix it up. but not able to resolve
You are defining a global variable tos in a header file, which you include both from 1.c and main.c. So you end up with two global variables with the same name. The linker does not like that. As a traditional-unix extension, the linker may cope with such a situation if the multiply-defined variable is not explicitly initialized, but your code initializes the variable.
I recommend reading the K&R book which you will find in any decent university library.
#Thomas gave you a good explanation of your problem. The global variable tos declaration is in the header file 2.h which is included twice via #include in 1.c and main.c.
If you want to share the variable tos you should declaration it in 1.c or main.c, and modify 2.h to declare it as an extern, e.g.:
1.c:
int tos = 0;
2.h:
extern int tos;
Then you can access tos from main.c, but the variable is only defined once.
Sidebar: Just a suggestion for your own benefit, and for the benefit of sharing future questions in StackOverflow, try to minimize the source code, to the bare necessaries of generating the error. To the point where the program is trivial, because then the bug will be easier to isolate (for you and everyone else), and clearer for the reader, what they should focus on. As well, #Thomas suggestion of The C Programming Language is strongly encouraged as an excellent recommendation for any C programmer.