So I am getting undefined references
timer.H
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
|
#ifndef _timer_H_ // include file only once
#define _timer_H_
/*--------------------------------------------------------------------------*/
/* DEFINES */
/*--------------------------------------------------------------------------*/
/* -- (none) -- */
/*--------------------------------------------------------------------------*/
/* INCLUDES */
/*--------------------------------------------------------------------------*/
#include <stdio.h>
#include <sys/time.h>
#include <list>
#include <stdlib.h>
#include <signal.h>
#include <pthread.h>
#include "semaphore.H"
#include <unistd.h>
#include <iostream>
/*--------------------------------------------------------------------------*/
/* DATA STRUCTURES */
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
/* FORWARDS */
/*--------------------------------------------------------------------------*/
/* -- (none) -- */
/*--------------------------------------------------------------------------*/
/* CLASS T i m e r */
/*--------------------------------------------------------------------------*/
using namespace std;
class Timer {
private:
static long clock_interval; /* in musec */
static bool compare_timers(const Timer * _t1, const Timer * _t2);
/* Compares whether timer _t1 is earlier than timer _t2. This function
may come in handy, for example, whenever timers need to be inserted into
an ordered queue. */
// ACESSORY FUNCTION TO COMPARE TIMEVALS
static bool compare_tv(timeval ta, timeval tb);
static void * TimerHandlerThread(void * args);
/* This function is called by the separate thread that handles the low-level
timer interrupts and checks whether timers events have expired and
need to be executed. */
/* WHEN SHOULD THE TIMER FIRE? */
timeval tv;
static list<Timer*> timeq;
static Semaphore * s;
public:
static int Init(long _clock_interval_musec);
/* Initialize the timer handling. This should be called by the main
thread early on, certainly before it creates the first timers.
An implementation could look as follows: First, the main thread masks the
SIGALARM (or SIGVTALARM) signals; this should be done before any
tasks are created, in order for the tasks to have the signals masked.
Then, method "Init()" would create a new timer thread, which would
process the requests in the timer queue. For this thread, the
signal would be unblocked. */
Timer();
/* Construct timer that calles "Event_Handler" whenever it fires. */
~Timer();
virtual void Set(long _imusec);
/* Set this timer to fire after time '_imusec' from now. */
virtual int Clear();
/* Cancel the timer. */
virtual void Handle_Event() = 0;
/* This function is called when the timer expires. */
};
#endif
|
timer.C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
#include "timer.H"
Timer::Timer() {
s = new Semaphore(1);
}
bool Timer::compare_tv(timeval ta, timeval tb) {
if(ta.tv_sec < tb.tv_sec) {
return true;
}
else if(ta.tv_sec > tb.tv_sec) {
return false;
}
else if(ta.tv_sec == tb.tv_sec) {
if(ta.tv_usec < tb.tv_usec) {
return true;
}
else if(ta.tv_usec > tb.tv_usec) {
return false;
}
else if(ta.tv_usec == tb.tv_usec) {
return false;
}
}
}
bool Timer::compare_timers(const Timer * _t1, const Timer * _t2) {
if(_t1->tv.tv_sec < _t2->tv.tv_sec) {
return true;
}
else if(_t1->tv.tv_sec > _t2->tv.tv_sec) {
return false;
}
else if(_t1->tv.tv_sec == _t2->tv.tv_sec) {
if(_t1->tv.tv_usec < _t2->tv.tv_usec) {
return true;
}
else if(_t1->tv.tv_usec > _t2->tv.tv_usec) {
return false;
}
else if(_t1->tv.tv_usec == _t2->tv.tv_usec) {
return false;
}
}
}
//HANDLER
void * Timer::TimerHandlerThread(void * args) {
long sec = clock_interval / 1000000;
long usec = clock_interval % 1000000;
struct itimerval itv;
itv.it_value.tv_sec = sec;
itv.it_value.tv_usec = usec;
itv.it_interval.tv_sec = sec;
itv.it_interval.tv_usec = usec;
setitimer(ITIMER_REAL, &itv, 0);
sigset_t sg;
int sgcount = 0;
int signo;
if((sigemptyset(&sg) == -1) || (sigaddset(&sg,SIGUSR1)== -1) || (sigprocmask(SIG_BLOCK, &sg, NULL) == -1))
perror("Failed to block signal before sigwait\n");
fprintf(stderr, "This process has ID %ld\n", (long)getpid());
for( ; ; ) {
if(sigwait(&sg, &signo) == -1) {
perror("failed to wait using sigwait");
}
//get current time and compare with timers in queue to see if expired
s->P();
timeq.front()->Handle_Event();
timeq.pop_front();
s->V();
sgcount++;
timeval temp;
gettimeofday(&temp, NULL);
if(compare_tv(temp, timeq.front()->tv)) {
timeq.pop_front();
}
}
//check timer in list and pop???
}
//INIT
int Timer::Init(long _clock_interval_musec) {
pthread_t pt;
int x;
sigset_t sigset;
clock_interval = _clock_interval_musec;
//Set(clock_interval);
sigemptyset(&sigset);
sigaddset(&sigset, SIGALRM);//TIMER_SIGNAL
sigprocmask(SIG_BLOCK, &sigset, NULL);
x=pthread_create(&pt, NULL, TimerHandlerThread, NULL);
if(x) {
printf("ERROR\n");
exit(-1);
}
pthread_detach(pt);
return 0;
}
//SET
void Timer::Set(long _imusec) {
Clear();
gettimeofday(&tv, NULL);
tv.tv_sec += _imusec/1000000;
tv.tv_usec += _imusec%1000000;
s->P();
timeq.push_back(this);
s->V();
//push back the current time + timeval
}
//CLEAR
int Timer::Clear() {
s->P();
timeq.remove(this);
s->V();
//remove current timer from queue
}
Timer::~Timer() {}
|
I'm pretty sure it doesn't have to do with how I am compiling it so it's in my code, but I am not sure what to do. Any help would be greatly appreciated. When I compiled I did not forget timer.C, also had to remove a few error lines because of length, but I think you get the idea
/tmp/cclRk13A.o(.text+0x3b): In function `Timer::Timer[not-in-charge]()':
: undefined reference to `Timer::s'
/tmp/cclRk13A.o(.text+0xc1): In function `Timer::Timer[in-charge]()':
: undefined reference to `Timer::s'
/tmp/cclRk13A.o(.text+0x223): In function `Timer::TimerHandlerThread(void*)':
: undefined reference to `Timer::clock_interval'
/tmp/cclRk13A.o(.text+0x23f): In function `Timer::TimerHandlerThread(void*)':
: undefined reference to `Timer::clock_interval'
/tmp/cclRk13A.o(.text+0x379): In function `Timer::TimerHandlerThread(void*)':
: undefined reference to `Timer::s'
: undefined reference to `Timer::timeq'
/tmp/cclRk13A.o(.text+0x3a8): In function `Timer::TimerHandlerThread(void*)':
: undefined reference to `Timer::timeq'
/tmp/cclRk13A.o(.text+0x3b9): In function `Timer::TimerHandlerThread(void*)':
: undefined reference to `Timer::s'
/tmp/cclRk13A.o(.text+0x3e5): In function `Timer::TimerHandlerThread(void*)':
: undefined reference to `Timer::timeq'
: undefined reference to `Timer::timeq'
: undefined reference to `Timer::clock_interval'
/tmp/cclRk13A.o(.text+0x57d): In function `Timer::Set(long)':
: undefined reference to `Timer::s'
/tmp/cclRk13A.o(.text+0x597): In function `Timer::Set(long)':
: undefined reference to `Timer::timeq'
: undefined reference to `Timer::s'
/tmp/cclRk13A.o(.text+0x5c7): In function `Timer::Clear()':
: undefined reference to `Timer::s'
: undefined reference to `Timer::timeq'
/tmp/cclRk13A.o(.text+0x5f2): In function `Timer::Clear()':
: undefined reference to `Timer::s'
collect2: ld returned 1 exit status