This is for a homework assignment in my operating systems class. We're supposed to be testing our knowledge of semaphores and mutexes using this system our professor created.
When I try to make the program, I get this message:
"c++ -o prog2 thread.o thread-main.o /usr/local.csl/ThreadMentor/fedora4/NoVisual/libthreadclass.a -lpthread thread.o: In function 'Elf::ThreadFunc()': /major/username/CS4411OS/prog2/thread.cpp:161: undefined reference to 'AskQuestion(int)' thread.o: In function 'Reindeer::ThreadFunc()': /major/username/CS4411OS/prog2/thread.cpp:131: undefined reference to 'ReindeerBack(int' /major/username/CS4411OS/prog2/thread.cpp:133: undefined reference to 'WaitOthers(int)' /major/username/CS4411OS/prog2/thread.cpp:135: undefined reference to 'WaitSleigh()' /major/username/CS4411OS/prog2/thread.cpp:137: undefined reference to 'FlyOff(); thread.o: In function 'Santa::ThreadFunc()': /major/username/CS4411OS/prog2/thread.cpp:44: undefined reference to 'Sleep()' /usr/bin/ld: Dwarf Error: Offset (952) greater than or equal to .debug_str size (285). thread.o: In function 'main': /major/username/CS4411OS/prog2/thread-main.cpp:40: undefined reference to 'init(int, int); collect2: ld returned 1 exit status make: *** [prog2] Error 1"
First of all, I have no idea what the "/usr/bin/ld: Dwarf Error: Offset (952) greater than or equal to .debug_str size (285)." line means.
I don't understand why I'm getting the "undefined reference errors", since I am including those functions in the files that use them.
thread-main.cpp is my main program
thread.h - class definitions/global variables/function prototypes
thread.cpp - class implementation
thread-support.cpp - implement supporting functions defined in thread.h
"thread-main.cpp", "thread.cpp" and "thread-support.cpp" all include "thread.h"
Just so you know, I am not very knowledgeable about compiling or makefiles. I have no clue what's going on. Can someone please help me and tell me how to fix this? I'm attaching my code here.
thread.cpp
#ifndef THREAD_CPP #define THREAD_CPP #include <iostream> #include "thread.h" //#include "thread-support.cpp" //#include "ThreadClass.h" /** Global variables */ Semaphore * SantaSleep; Semaphore * ElfWait; Semaphore * ElfGroup; Semaphore * ReindeerWait; Semaphore * ReindeerSleigh; Semaphore * deerCheck; Semaphore * elvesCheck; Mutex * delivering; int numDeer; int numElves; int deerBack; int elvesWaiting; int elfNumbers[3]; Santa::Santa(int trips) { numTrips = trips; curTrip = 0; retire = false; } void Santa::ThreadFunc() { Thread::ThreadFunc(); cout << "Santa thread starts." << endl; bool skipElves; while(!retire) { // Santa blocks himself so he can sleep Sleep(); skipElves = false; // aquire locks on the count variables for the waiting reindeer deerCheck->Wait(); // if all reindeer are back if(deerBack == numDeer) { delivering->Lock(); // put reindeer on the sleigh for(int i = 0; i < numDeer; i++) { ReindeerWait->Signal(); } cout << "Santa is preparing the sleigh." << endl; cout << "The team flys off! " << curTrip+1 << endl; // make delivery Delay(); // release all the reindeer for(int i = 0; i < numDeer; i++) { ReindeerSleigh->Signal(); } // update trip counter curTrip++; if(curTrip = numTrips) { retire = true; } // reset reindeer back counter deerBack = 0; skipElves = true; delivering->Unlock(); } deerCheck->Signal(); // aquire locks on the count variables for the waiting elves if(!skipElves) { elvesCheck->Wait(); if(elvesWaiting == 3) { // there could be many elves waiting cout << "Santa is helping Elves." << endl; // answer elves questions Delay(); cout << "Santa answers question posted by elves " << elfNumbers[0] << ", " << elfNumbers[1] << ", " << elfNumbers[2] << "." << endl; // release the elves as a group for(int i = 0; i < 3; i++) { ElfGroup->Signal(); } elvesWaiting = 0; } // release lock on count variable elvesCheck->Signal(); } } cout << "After (" << numTrips << ") deliveries, Santa retires and is on vacation!" << endl; Exit(); } Reindeer::Reindeer(int num) { number = num; } void Reindeer::ThreadFunc() { Thread::ThreadFunc(); cout << "Reindeer " << number << " starts." << endl; while(1) { // vacation Delay(); // return to Santa ReindeerBack(number); // wait for all other reindeer to return WaitOthers(number); // wait to be attached to the sleigh WaitSleigh(); // deliver toys FlyOff(); // will wait for Santa to release all the reindeer // vacation Delay(); } } // constructor Elf::Elf(int num) { number = num; } void Elf::ThreadFunc() { Thread::ThreadFunc(); cout << "Elf " << number << "starts." << endl; while(1) { // make toys Delay(); // ask a question to Santa AskQuestion(number); // take a break Delay(); } } #endif
thread-main.cpp
#include <iostream> #include <cstdlib> #include "thread.h" //#include "thread-support.cpp" using namespace std; int main(int argc, char** argv) { // number of elves that exist int numElves; // number of reindeer that exist int numDeer; // number of trips that Santa will go on int numToys; // Interpret command line values // numElves = argv[1] since argv[0] is the program's name numElves = atoi(argv[1]); numDeer = atoi(argv[2]); numToys = atoi(argv[3]); // set default values if necessary if(numElves == 0) { numElves = 7; } if(numDeer == 0) { numDeer = 9; } if(numToys = 0) { numToys = 5; } // initialize the semaphores init(numDeer, numElves); Santa * s = new Santa(numToys); // arrays are like this // int * Inputs[numElements]; // create the reindeer Reindeer * r[numDeer]; for(int i = 0; i < numDeer; i++) { r[i] = new Reindeer(i+1); } // create the elves Elf * e[numElves]; for(int i = 0; i < numElves; i++) { e[i] = new Elf(i+1); } // start Santa s->Begin(); // start the reindeer for(int i = 0; i < numDeer; i++) { //r[i]->Begin(); } // start the elves for(int i = 0; i < numElves; i++) { //e[i]->Begin(); } // need to wait for Santa to retire s->Join(); exit(0); }
thread-support.cpp
#ifndef THREAD_SUPPORT_CPP #define THREAD_SUPPORT_CPP #include <iostream> #include "thread.h" void init(int numD, int numE) { numDeer = numD; numElves = numE; SantaSleep = new Semaphore("SantaSleep", 0); ElfWait = new Semaphore("ElfWait", 3); ElfGroup = new Semaphore("ElfGroup", 0); ReindeerWait = new Semaphore("ReindeerWait", 0); ReindeerSleigh = new Semaphore("ReindeerSleigh", 0); deerCheck = new Semaphore("DeerCheck", 1); delivering = new Mutex("Delivering", 0); deerBack = 0; elvesWaiting = 0; elfNumbers[0] = 0; elfNumbers[1] = 0; elfNumbers[2] = 0; } void Sleep() { SantaSleep->Wait(); } void WaitSleigh() { ReindeerWait->Wait(); } void ReindeerBack(int number) { //The deerCheck semaphore protects the deerBack integer variable from multiple access deerCheck->Wait(); deerBack++; //The reindeer prints a message stating that they are back if (deerBack != numDeer) { cout << "Reindeer " << number << " returns." << endl; } } void FlyOff() { ReindeerSleigh->Wait(); } void WaitOthers(int number) { // the last one back wakes up Santa if(deerBack == numDeer) { cout << "The last reindeer " << number << " wakes up Santa." << endl; SantaSleep->Signal(); } // release the lock that prevents reindeer from updating // the deerBack counter deerCheck->Signal(); } void AskQuestion(int number) { // is this the last elf in a group of 3? bool lastElf = false; // This semaphore only lets 3 elves get in a group ElfWait->Wait(); // protect the elvesWaiting count variable elvesCheck->Wait(); elvesWaiting++; // add elf's ID to list of waiting elves elfNumbers[elvesWaiting - 1] = number; cout << "Elf " << number << "has a problem." << endl; // am I the last elf in a group of 3? if(elvesWaiting == 3) { lastElf = true; delivering->Lock(); cout << "Elves " << elfNumbers[0] << ", " << elfNumbers[1] << ", " << elfNumbers[2] << " wake up Santa." << endl; // wake up Santa SantaSleep->Signal(); delivering->Unlock(); } // open the lock on the count variable elvesCheck->Signal(); // wait with other elves ElfGroup->Wait(); // the last elf in a group allows 3 more elves to enter if(lastElf) { cout << "Elves " << elfNumbers[0] << ", " << elfNumbers[1] << ", " << elfNumbers[2] << " return to work." << endl; ElfWait->Signal(); ElfWait->Signal(); ElfWait->Signal(); } } #endif
thread.h
#ifndef THREAD_H #define THREAD_H #include "ThreadClass.h" /** Global variables */ extern Semaphore * SantaSleep; extern Semaphore * ElfWait; extern Semaphore * ElfGroup; extern Semaphore * ReindeerWait; extern Semaphore * ReindeerSleigh; extern Semaphore * deerCheck; extern Semaphore * elvesCheck; extern Mutex * delivering; extern int numDeer; extern int numElves; extern int deerBack; extern int elvesWaiting; extern int elfNumbers[3]; void init(int numDeer, int numElves); void Sleep(); void WaitSleigh(); void ReindeerBack(int number); void FlyOff(); void WaitOthers(int number); void AskQuestion(int number); class Santa : public Thread { public: Santa(int trips); private: int numTrips; int curTrip; bool retire; void ThreadFunc(); }; class Reindeer : public Thread { public: Reindeer(int num); private: int number; void ThreadFunc(); }; class Elf : public Thread { public: Elf(int num); private: int number; void ThreadFunc(); }; #endif
Makefile
# ----------------------------------------------------------- # Makefile for fedora4 OS # # Options: # 1. TMLIB = /usr/local.csl/ThreadMentor/fedora4/Visual/libthreadclass.a # 2. TMLIB = /usr/local.csl/ThreadMentor/fedora4/NoVisual/libthreadclass.a # ----------------------------------------------------------- CC = c++ CFLAGS = -g -O2 -Wno-deprecated DFLAGS = -DPACKAGE=\"threadsystem\" -DVERSION=\"1.0\" -DPTHREAD=1 -DUNIX_MSG_Q=1 -DSTDC_HEADERS=1 IFLAGS = -I/usr/local.csl/ThreadMentor/fedora4/include # change to Visual for visualizations TMLIB = /usr/local.csl/ThreadMentor/fedora4/NoVisual/libthreadclass.a OBJ_FILE = thread.o thread-main.o EXE_FILE = prog2 ${EXE_FILE}: ${OBJ_FILE} ${CC} ${FLAGS} -o ${EXE_FILE} ${OBJ_FILE} ${TMLIB} -lpthread thread.o : thread.cpp thread.h ${CC} ${DFLAGS} ${IFLAGS} ${CFLAGS} -c thread.cpp thread-support.o : thread-support.cpp thread.h ${CC} ${DFLAGS} ${IFLAGS} ${CFLAGS} -c thread-support.cpp thread-main.o: thread-main.cpp thread.h ${CC} ${DFLAGS} ${IFLAGS} ${CFLAGS} -c thread-main.cpp clean: rm -f ${OBJ_FILE} ${EXE_FILE} # End of Makefile
This post has been edited by AlexH: 14 October 2009 - 07:20 PM