I downloaded pre-build library from http://sourceforge.net/projects/pthreads4w/files/latest/download?source=typ_redirect.
I extracted it to the following directory:
C:\Users\Veena\Documents\pthread\pthreads-w32-2-9-1-release
I set following things:
In projects -> right click -> properties -> configuration properties -> C/C++ -> General -> Additional include directories -> "C:\Users\Veena\Documents\pthread\pthreads-w32-2-9-1-release\Pre-built.2\include"
In projects -> right click -> properties -> configuration properties -> linker -> General -> Additional library directories -> "C:\Users\Veena\Documents\pthread\pthreads-w32-2-9-1-release\Pre-built.2\lib\x86"
In projects -> right click -> properties -> configuration properties -> linker -> Input -> Additional dependencies ->
pthreadVC2.lib
pthreadVCE2.lib
pthreadVSE2.lib
In projects -> right click -> properties -> configuration properties -> linker -> All options -> Additional options ->
-lpthread
This is my code:
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
struct Node {
int data;
struct Node* next;
};
struct Node*head;
pthread_rwlock_t rwlock;
int numThreads;
int i, j;
float mInsert, mDelete, mMember;
int data[1000];
int test[10000];
long numberOfTotalOperations = 10000;
long numberOfInsertOperations;
long numberOfDeleteOperations;
long numberOfMemberOperations;
void *Process(void* rank);
int Member(int val);
int Insert(int val);
int Delete(int val);
long getCurrentTime(void);
int main(int argc, char* argv[]) {
if (argc != 5) {
printf("<member op fraction> <insert op fraction> <delete op fraction>");
exit(0);
}
mMember = strtod(argv[1], NULL);
mInsert = strtod(argv[2], NULL);
mDelete = strtod(argv[3], NULL);
numThreads = strtod(argv[4], NULL);
numberOfInsertOperations = mInsert * numberOfTotalOperations;
numberOfDeleteOperations = mDelete * numberOfTotalOperations;
numberOfMemberOperations = mMember * numberOfTotalOperations;
pthread_rwlock_init(&rwlock, NULL);
//data set : create with non-repeated random number
for (i = 0; i < 1000; i++) {
while (1) {
int temp = rand() % 65536;
int found = 0;
for (j = 0; j < i; j++) {
if (data[j] == temp) { found = 1; break; }
}
if (found == 0) { data[i] = temp; break; }
}
}
//test set
for (i = 0; i < 10000; i++) {
while (1) {
int temp = rand() % 65536;
int found = 0;
for (j = 0; j < i; j++) {
if (test[j] == temp) { found = 1; break; }
}
if (found == 0) { test[i] = temp; break; }
}
}
//----------------------------------------- Insert,Delete,Member
long thread;
pthread_t* thread_handles;
thread_handles = malloc(numThreads * sizeof(pthread_t));
for (thread = 0; thread < numThreads; thread++)
pthread_create(&thread_handles[thread], NULL, Process, (void*)thread);
for (thread = 0; thread < numThreads; thread++)
pthread_join(thread_handles[thread], NULL);
//--------
free(thread_handles);
return 0;
}
void *Process(void* rank) {
long my_rank = (long)rank;
int i, offset = (numberOfTotalOperations * my_rank) / numThreads;
int my_last_i = offset + (numberOfTotalOperations / numThreads);
long insert_op = numberOfInsertOperations / numThreads;
long delete_op = numberOfDeleteOperations / numThreads;
long member_op = numberOfMemberOperations / numThreads;
for (i = offset; i < my_last_i; i++) {
if (i < offset + insert_op) { //insert
pthread_rwlock_wrlock(&rwlock);
Insert(test[i]);
pthread_rwlock_unlock(&rwlock);
}
else if (i < offset + insert_op + delete_op) { //delete
pthread_rwlock_wrlock(&rwlock);
Delete(test[i]);
pthread_rwlock_unlock(&rwlock);
}
else {
pthread_rwlock_rdlock(&rwlock);
Member(test[i]);
pthread_rwlock_unlock(&rwlock);
}
}
return NULL;
}
int Insert(int value)
{
struct Node*curr_p = head;
struct Node*pred_p = NULL;
struct Node*temp_p;
while (curr_p != NULL && curr_p->data < value)
{
pred_p = curr_p;
curr_p = curr_p->next;
}
if (curr_p == NULL || curr_p->data > value)
{
temp_p = malloc(sizeof(struct Node));
temp_p->data = value;
temp_p->next = curr_p;
if (pred_p == NULL) /** New first node */
{
head = temp_p;
}
else
{
pred_p->next = temp_p;
}
return 1;
}
else /* value already in list*/
{
return 0;
}
}
int Member(int value)
{
struct Node*curr_p = head;
while (curr_p != NULL && curr_p->data < value)
{
curr_p = curr_p->next;
}
if (curr_p == NULL || curr_p->data > value)
{
return 0;
}
else
{
return 1;
}
}
int Delete(int value)
{
struct Node*curr_p = head;
struct Node*pred_p = NULL;
while (curr_p != NULL && curr_p->data < value)
{
pred_p = curr_p;
curr_p = curr_p->next;
}
if (curr_p != NULL && curr_p->data == value)
{
if (pred_p == NULL) /** deleting first node in list */
{
head = curr_p->next;
free(curr_p);
}
else
{
pred_p->next = curr_p->next;
free(curr_p);
}
return 1;
}
else /* Value isn't in list */
{
return 0;
}
}
I got following errors which exhibits, pthreads are not included:
1. IntelliSense: a value of type "void *" cannot be assigned to an entity of type "pthread_t *"
2. IntelliSense: a value of type "void *" cannot be assigned to an entity of type "Node *"
3. cannot convert from 'void *' to 'pthread_t *'
4. cannot convert from 'void *' to 'Node *'
What's wrong with my setup?
So, I'm just tried to compile your code and got the same error. It's because you should do explicit conversion void* pointer returned from malloc.
//thread_handles = malloc(numThreads * sizeof(pthread_t));
thread_handles = (pthread_t*)malloc(numThreads * sizeof(pthread_t)); // right one
//temp_p = malloc(sizeof(struct Node));
temp_p = (struct Node*)malloc(sizeof(struct Node)); // right one
In projects -> right click -> properties -> configuration properties -> linker -> All options -> Additional options -> -lpthread
It's wrong. Why did you do this?
In projects -> right click -> properties -> configuration properties -> linker -> Input -> Additional dependencies -> pthreadVC2.lib pthreadVCE2.lib pthreadVSE2.lib
You should link only one this *.lib file. Description from README file:
In general:
pthread[VG]{SE,CE,C}[c].dll
pthread[VG]{SE,CE,C}[c].lib
where:
[VG] indicates the compiler
V - MS VC, or
G - GNU C
{SE,CE,C} indicates the exception handling scheme
SE - Structured EH, or
CE - C++ EH, or
C - no exceptions - uses setjmp/longjmp
c - DLL compatibility number indicating ABI and API
compatibility with applications built against
a snapshot with the same compatibility number.
See 'Version numbering' below.
Related
I am writing a LLVM module pass that will get the third argument in pthread_create. According to the man page the function prototype of pthread_create is
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
For example my target C source is as following.
void *pthread_task(void *args) {
sleep(4);
return NULL;
}
int main(int argc, char *argv[]) {
pthread_t tid;
pthread_create(&tid, NULL, pthread_task, NULL);
pthread_join(tid, NULL);
return 0;
}
I would like to have the output "pthread_task". I was able to access the right function and list all arguments. However, since the third parameter is a function pointer, I don't know how to access the function which it points to.
Also I attach how I implement my module pass as following.
namespace {
~ int32_t indexOfPthreadCreate(CallGraphNode *node) {
~ for (int32_t i = 0; i < node -> size(); i++) {
~ Function *f = (*node)[i] -> getFunction();
~ if (f && f -> getName().compare("pthread_create") == 0) {
+ for (auto &A: f->args()) {
// I would like to access the third parameter of pthread_create here.
+ A.print(errs());
+ }
+ return i;
+ }
}
~ return -1;
}
struct PthreadScopeDetectPass : public ModulePass {
static char ID;
PthreadScopeDetectPass() : ModulePass(ID) { }
bool runOnModule(Module &M) override {
CallGraph &CG = getAnalysis<CallGraphWrapperPass>().getCallGraph();
uint32_t nSCC = 0;
for (scc_iterator<CallGraph *> iterSCC = scc_begin(&CG); !iterSCC.isAtEnd(); ++iterSCC) {
auto nodes = *iterSCC;
for (CallGraphNode *node: nodes) {
Function *currFunc = node -> getFunction();
~ int32_t target_i = indexOfPthreadCreate(node);
~ if (target_i > 0 && currFunc) {
+ insertTimer(currFunc);
}
}
}
return true;
}
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesAll();
AU.addRequired<CallGraphWrapperPass>();
}
};
}
Thanks for #arnt's comment. I already solve the issue. Here's how I solve it.
~ int32_t indexOfPthreadCreate(CallGraphNode *node) {
~ for (int32_t i = 0; i < node -> size(); i++) {
~ Function *f = (*node)[i] -> getFunction();
~ if (f && f -> getName().compare("pthread_create") == 0) {
+ for (auto &inst: instructions(f)) {
~ if (inst.getOpcode() == 56) {
~ CallInst *ci = dyn_cast<CallInst>(&inst);
~ if (ci && ci->getCalledFunction()->getName().compare("pthread_create") == 0) {
~ Function *pthread_task = dyn_cast<Function>(ci->getArgOperand(2));
~_ errs() << "pthread is going to execute " << pthread_task->getName() << "function \n";
}
+ }
+ A.print(errs());
+ }
+ return i;
+ }
}
~ return -1;
}
I have a homework which is done with C++. I coded it using a Main.cpp and a header file (datastruct.h). Homework was done, compiled and run successfully; but submission rules allow me to use just one main.cpp. When I tried to include my code in header to main.cpp I get:
[main] C:\cygnus\cygwin-b20\H-i586-cygwin32\bin\g++.exe 1000 (0) handle_exceptions: Exception: STATUS_ACCESS_VIOLATION
[main] g++ 1000 (0) handle_exceptions: Dumping stack trace to g++.exe.core
Note that: My question is not just about this error, it is about I get this error only I embed my header code to main.cpp. When they are separated, it works fine.
Here is my main.cpp when header codes were not included:
#include <iostream>
#include <fstream>
#include "datastruct.h"
using namespace std;
int main(int argc, char *argv[])
{
Game myGame;
myGame.initializer(argv[1]);
cout << myGame.gamePlay();
myGame.cleaner();
return 0;
}
And here is "datastruct.h":
#ifndef DATASTRUCT_H
#define DATASTRUCT_H
#include <iostream>
#include <fstream>
using namespace std;
int abs(int k) {
if(k < 0) k = -k;
return k;
}
struct Card {
int value;
Card* prev;
};
struct Deck {
Card* top ;
int cardNum;
void addCard(int xd);
int dropCard();
void create();
void clear();
void print();
};
void Deck::clear(/* arguments */) {
Card *p;
while(top)
{
p = top;
top = top -> prev;
delete p;
}
}
int Deck::dropCard(/* arguments */) {
Card* cardPtr;
int returnVal = top -> value;
cardPtr = top;
top = top -> prev;
delete cardPtr;
cardNum--;
return returnVal;
}
void Deck::create() {
cardNum = 0;
top = NULL;
}
void Deck::addCard(int xd) {
Card* newCard;
newCard = new struct Card;
newCard -> value = xd;
newCard -> prev = top;
top = newCard;
cardNum++;
}
struct Game {
Deck* p1;
Deck* p2;
Deck* table;
Deck* bin;
void initializer(char* filename);
void cleaner();
void gamePrint();
void p1gives();
void p2gives();
int gamePlay();
};
int Game::gamePlay()
{
int cardTaken;
while (true)
{
if((p1->cardNum ==0) || (p2->cardNum ==0) || (table->cardNum ==0)) break;
cardTaken = table->dropCard();
if (cardTaken < 0) {
for (int i = 0; i < abs(cardTaken); i++) {
if(p1->top == NULL) break;
p1gives();
}
} else {
for (int i = 0; i < cardTaken; i++) {
if(p2->top == NULL) break;
p2gives();
}
}
if((p1->cardNum ==0) || (p2->cardNum ==0) || (table->cardNum ==0)) break;
cardTaken = table->dropCard();
if (cardTaken < 0) {
for (int i = 0; i < abs(cardTaken); i++) {
if((p1->top == NULL) || (p2->top == NULL)) break;
p2gives();
}
} else {
for (int i = 0; i < cardTaken; i++) {
if((p1->top == NULL) || (p2->top == NULL)) break;
p1gives();
}
}
}
return (bin -> cardNum);
}
void Game::p1gives()
{
if(p2 -> top == NULL)
p2 -> addCard(p1 -> dropCard());
else if (p1 -> top -> value > p2 -> top -> value)
p2 -> addCard(p1 -> dropCard());
else if (p1 -> top -> value <= p2 -> top -> value)
bin -> addCard(p1 -> dropCard());
}
void Game::p2gives()
{
if (p1 -> top == NULL)
p1 -> addCard(p2 -> dropCard());
else if(p2 -> top -> value > p1 -> top -> value)
p1 -> addCard(p2 -> dropCard());
else if(p2 -> top -> value <= p1 -> top -> value)
bin -> addCard(p2 -> dropCard());
}
void Game::cleaner()
{
p1 -> clear();
p2 -> clear();
table -> clear();
bin -> clear();
delete p1;
delete p2;
delete table;
delete bin;
}
void Game::initializer(char* filename)
{
ifstream myFile(filename);
int tableDeckCount, playerDeckCount;
myFile >> tableDeckCount;
myFile >> playerDeckCount;
p1 = new struct Deck;
p1 -> create();
p2 = new struct Deck;
p2 -> create();
table = new struct Deck;
table -> create();
bin = new struct Deck;
bin -> create();
for (int i = 0; i < tableDeckCount; i++) {
int x;
myFile >> x;
table -> addCard(x);
}
for (int i = 0; i < playerDeckCount; i++) {
int x;
myFile >> x;
p1 -> addCard(x);
}
for (int i = 0; i < playerDeckCount; i++) {
int x;
myFile >> x;
p2 -> addCard(x);
}
}
void Deck::print(/* arguments */) {
Card* traverse;
traverse = top;
while (traverse) {
cout << traverse -> value << " , " ;
traverse = traverse -> prev;
}
cout << endl;
}
void Game::gamePrint()
{
cout << "P1:" << endl;
p1 -> print();
cout << "P2:" << endl;
p2 -> print();
cout << "TABLE:" << endl;
table -> print();
cout << "BIN:" << endl;
bin -> print();
}
#endif
I need to include header into main.cpp but when I copy codes I get error. Can someone help me?
Expected work example:
>g++ -std=c++0x -Wall -Wextra -Werror main.cpp -o cardgame
>./cardgame example.game
1
example.game file:
1 3
-2
6
7
8
1
5
4
Run the compilation in elevated privileges on Windows? (right-click run as administrator) /edit. Right-click on sh.exe for cygwin and go to compatibility and check the box "run as administrator")
also, for reference to those who negatively voted: https://developer.qualcomm.com/forum/qdn-forums/mobile-technologies/multimedia-optimization-hexagon-sdk/toolsinstallation/27100
I need some help, I'm learing data structers and I got a task to write a programm based on array of pointers to structres which can add elements and do other task with array.I have next model of levels:
first level --> net of shops
second level --> shop
third level --> goods
I've written types for this
typedef struct
{
QString date;
QString prod_code;
QString name;
}goods;
typedef struct
{
QString address;
QString number;
void **sublevel;
}shop;
typedef struct
{
QString website;
QString name;
QString owner;
QString address;
void **sublevel;
}net;
Then I've created global variable void **Start which points to array of pointers:
// init list
void ** init_list()
{
void** p = new void*[SIZE_AR];
p = p+2;
((int*)p)[COUNT_POS] = 0;
((int*)p)[SIZE_POS] = SIZE_AR;
return p;
}
void ** Start = init_list();
COUNT_POS - index of elements where I store count of currently used elemnets
SIZE_POS - size of array allocated in dynamic memory
SIZE_AR - default size for array
But I get segmentation fault when I try to add to element to the last level
(for previous two ones works fine):
// expand array if it overfilled
void ExpandArrPtr (void **&ar, int &SizeAr, int Cnt)
{
void **arW;
arW = new void*[SizeAr+DELTA+2];
for (int K = SizeAr-1; K >= 0; K--) {
arW[K+2] = ar[K];
}
SizeAr = SizeAr + DELTA;
ar=ar-2;
delete []ar;
ar=arW+2;
((int*)ar)[COUNT_POS] = Cnt;
((int*)ar)[SIZE_POS] = SizeAr;
}
// binary search
void bin_search(void **start, QString key, int &pos, bool &find, Cmpmethod func)
{
int mid;
int high, low;
find = false;
if((int*)start[COUNT_POS] == 0)
{
pos = 0;
qDebug()<<"zero elem\n";
return;
}
low = 0;
high = ((int*)start)[COUNT_POS] - 1;
do
{
mid = (high + low) / 2;
int result = func(start[mid], key);
if(result == 0)
{
pos = mid;
find = true;
return;
}
else if(result == 1)
{
high = mid - 1;
}
else
{
low = mid + 1;
}
}while(low <= high);
pos = low;
}
// function for adding in any level
void addtosort(void **&start, void *pnew, int pos)
{
int count = ((int*)start)[COUNT_POS];
int size = ((int*)start)[SIZE_POS];
if(count == size)
{
ExpandArrPtr(start, size, count);
}
if(pos == count)
{
start[pos] = pnew;
}
else
{
for(int i = count;i >= pos;i--)
{
start[i+1] = start[i];
}
start[pos] = pnew;
}
count++;
((int*)start)[COUNT_POS] = count;
}
void add_goods(void **&Start, goods * Pnew)
{
int pos;
bool find;
bin_search((((shop*)(Start))->sublevel), Pnew->name, pos, find, compare_goods);
addtosort((((shop*)(Start))->sublevel), Pnew, pos);
}
// finding the item in second level to add
void find_place(QString key)
{
int pos;
bool find;
int count = ((int*)Start)[COUNT_POS];
for(int i = 0;i < count;i++)
{
bin_search(((net*)(Start)[i])->sublevel, key, pos, find, compare_shop);
if(find)
{
goods * Pnew = new goods;
Pnew->date = "foo"
Pnew->name = "bar"
add_goods(((net*)(Start)[pos])->sublevel, Pnew);
break;
}
}
}
What can cause such problem?
I have below class
class Cdata12Mnt
{
public:
char IOBname[ID1_IOB_PIOTSUP-ID1_IOB_TOP][BOADNAM_MAX + 4];
char ExIOBname[ID1_MAX_INF-ID1_EXIOB_U1TOP][BOADNAM_MAX + 4];
char cflpath[256];
char basetext[256];
UINT database[ID1_MAX_INF];
int State;
public:
char SelectPath[256];
public:
int GetIOBName(int slt,char *Name);
Cdata12Mnt(char *SelectPath);
virtual ~Cdata12Mnt();
int GetValue(int id);
int GetState() { return State; }
};
And I have function as below
Cdata12Mnt::Cdata12Mnt(char *SelectPath)
{
SCTReg reg;
char buf[256], *cpnt, *npnt, *bpnt1, *bpnt2;
char *startcode[] = {"CNTL_CODE ","SEGMENT "};
char *stopcode = {"END_CNTL_CODE "};
FILE *fp;
int ii, infl;
State = 0;
for (ii = 0; ii < (ID1_IOB_PIOTSUP - ID1_IOB_TOP); ii++) {
strcpy(IOBname[ii], "");
}
for (ii = 0; ii < (ID1_MAX_INF-ID1_EXIOB_U1TOP); ii++) {
**strcpy(ExIOBname[ii], "");**
}
sprintf(cflpath, "%s\\%s", SelectPath, CDATAFL);
if ((fp = fopen(cflpath,"r"))!=NULL) {
for (ii = 0, infl = 0; fgets(buf, 256, fp) != NULL;) {
if (infl == 0 && strncmp(buf, startcode[0], strlen(startcode[0])) == 0) {
if ((cpnt = strchr(&buf[strlen(startcode[0])],*startcode[1])) != NULL) {
if (strncmp(cpnt,startcode[1], strlen(startcode[1])) == 0) {
infl = 1;
continue;
}
}
}
if (infl == 0) {
continue;
}
if (strncmp(buf,stopcode,strlen(stopcode))==0) {
if (ii == ID1_EXIOB_U1TOP) {
for (int nDataNumber = ii; nDataNumber < ID1_MAX_INF; nDataNumber++) {
database[nDataNumber] = 0;
}
}
infl = 0;
continue;
}
if (strncmp(&buf[14], " DD ", 4) == 0) {
if ((cpnt=strchr(buf, ';')) != NULL) {
*cpnt = '\0';
}
if (ii >= ID1_IOB_TOP && ii < ID1_IOB_PIOTSUP) {
if ((bpnt1 = strchr(cpnt + 1,'(')) != NULL && (bpnt2=strchr(cpnt + 1,')'))!=NULL && bpnt1 < bpnt2) {
*bpnt2 = '\0';
*(bpnt1 + BOADNAM_MAX + 1) = '\0';
strcpy(IOBname[ii-ID1_IOB_TOP], bpnt1 + 1);
}
}
if (ii >= ID1_EXIOB_U1TOP && ii < ID1_MAX_INF) {
if ((bpnt1 = strchr(cpnt + 1, '(')) != NULL && (bpnt2=strchr(cpnt+1,')'))!=NULL && bpnt1 < bpnt2) {
*bpnt2='\0';
*(bpnt1+BOADNAM_MAX+1)='\0';
strcpy(ExIOBname[ii-ID1_EXIOB_U1TOP], bpnt1 + 1);
}
}
for (cpnt = &buf[18]; cpnt != NULL;) {
if ((npnt=strchr(cpnt, ',')) != NULL)
*npnt='\0';
}
if (strchr(cpnt,'H')!=NULL) {
sscanf(cpnt,"%XH",&database[ii]);
} else {
database[ii]=atoi(cpnt);
}
ii++;
cpnt = npnt;
if (cpnt != NULL) {
cpnt++;
}
}
}
}
fclose(fp);
} else {
State=-1;
}
When I compile this function in Visual studio 2008, it gives me error at strcpy(IOBname[ii],""); as below
error C2220: warning treated as error - no 'object' file generated
How to fix this error?
The error says that a warning was treated as an error, therefore your problem is a warning message! The object file is then not created because there was an error. So you need to check your warnings and fix them.
In case you don't know how to find them: Open the Error List (View > Error List) and click on Warning.
Go to project properties -> configurations properties -> C/C++ -> treats warning as error -> No (/WX-).
As a side-note, you can enable/disable individual warnings using #pragma. You can have a look at the documentation here
From the documentation:
// pragma_warning.cpp
// compile with: /W1
#pragma warning(disable:4700)
void Test() {
int x;
int y = x; // no C4700 here
#pragma warning(default:4700) // C4700 enabled after Test ends
}
int main() {
int x;
int y = x; // C4700
}
This error message is very confusing. I just fixed the other 'warnings' in my project and I really had only one (simple one):
warning C4101: 'i': unreferenced local variable
After I commented this unused i, and compiled it, the other error went away.
This warning is about unsafe use of strcpy. Try IOBname[ii]='\0'; instead.
As an exercise (largely an exercise in trying to write something using pointers), I'm writing a cache simulation, specifically of the pseudo least recently used system from the old 486. I'm getting an "Access violation reading location" error on the line:
int min = treeArray[set]->root->findPLRU();
Initially the treeArray seems to be initialised properly (if I pause the program at the start and take a look, it's all as should be), but when the programme breaks and I delve in to examine things the root of the tree in question isn't defined.
I feel it's quite probable that I'm making some sort of very elementary pointer mistake, which is causing the pointer to the node to be "lost" somewhere, but I've no clue what it might be. Is there something in particular I need to do to "hold on" to a pointer value?
#include "stdafx.h"
#include "stdlib.h"
#include <conio.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <io.h>
#include "main.h"
//char fn[80]; // trace filename
int tf; // trace file
trace buf[BUFSZ / sizeof(trace)]; // buffer SIZE
int LRUHits = 0;
int pLRUHits = 0;
int randomHits = 0;
int height;
int cachelinenumber;
//log2 helper function
int log2(int n)
{
int i = 0;
while (n)
{
n = n >> 1;
i++;
}
return i - 1;
}
class CacheLine{
public:
int tag;
int access;
CacheLine();
};
class Cache;
class Node{
public:
bool goRight;
Node* left;
Node* right;
int leftCacheLine;
int rightCacheLine;
Node(int depth) // constructor
{
goRight = false;
if (depth < height - 1)
{
left = new Node(depth + 1);
right = new Node(depth + 1);
leftCacheLine = -1;
rightCacheLine = -1;
}
else
{
leftCacheLine = cachelinenumber;
cachelinenumber++;
rightCacheLine = cachelinenumber;
cachelinenumber++;
}
//printf("Depth: %d, Height: %d, Left: %d, Right: %d\n", depth, height, leftCacheLine, rightCacheLine);
}
~Node()
{
delete left;
delete right;
}
int findPLRU()
{
if (leftCacheLine < 0 || rightCacheLine < 0)
{
if (goRight)
{
goRight = false;
return right->findPLRU();
}
else
{
goRight = true;
return left->findPLRU();
}
}
else
{
if (goRight)
{
goRight = false;
return rightCacheLine;
}
else
{
goRight = true;
return leftCacheLine;
}
}
}
};
class Tree{
public:
Node* root;
Tree()
{
root = new Node(0);
}
~Tree()
{
delete root;
}
};
//cache class
class Cache
{
public:
CacheLine *cache;
int l, k, n, replacementPolicy;
int log2l, log2n;
int access;
Tree** treeArray;
//constructor
Cache(int ll, int kk, int nn, int _replacementPolicy)
{
l = ll;
k = kk;
n = nn;
replacementPolicy = _replacementPolicy;
log2l = log2(l);
log2n = log2(n);
cache = (CacheLine*)malloc(sizeof(CacheLine)*k*n);
for (int i = 0; i < k*n; i++)
{
cache[i].tag = 0x80000000;
cache[i].access = 0;
}
if (replacementPolicy == 1)
{
cachelinenumber = 0;
treeArray = new Tree*[n];
for (int i = 0; i < n; i++)
{
treeArray[i] = new Tree();
}
}
access = -1;
}
//destructor
~Cache()
{
free(cache);
}
//test for hit
void hit(int a)
{
access++;
int set = (a >> log2l) & (n - 1);
int tag = a >> (log2n + log2l);
CacheLine* c = &cache[set*k];
for (int i = 0; i < k; i++)
{
if (c[i].tag == tag)
{
c[i].access = access;
if (replacementPolicy == 0)
LRUHits++;
else if (replacementPolicy == 1)
pLRUHits++;
else if (replacementPolicy == 2)
randomHits++;
break;
}
}
if (replacementPolicy == 0) //LRU
{
int min = 0;
int minv = c[0].access;
for (int i = 1; i < k; i++)
{
if (c[i].access < minv)
{
minv = c[i].access;
min = i;
}
}
c[min].tag = tag;
c[min].access = access;
}
else if(replacementPolicy == 1) // pseudoLRU
{
int min = treeArray[set]->root->findPLRU();
c[min].tag = tag;
c[min].access = access;
}
else // random
{
srand(clock());
int randomNumber = rand()%k;
c[randomNumber].tag = tag;
c[randomNumber].access = access;
}
return;
}
};
void analyse (int l, int k, int n)
{
height = log2(k) + 1;
char fn[] = "ico0.trace";
if ((tf = open(fn, _O_RDONLY | _O_BINARY )) == -1) {
printf("unable to open file %s\n", fn);
exit(0);
}
LRUHits = 0;
pLRUHits = 0;
randomHits = 0;
Cache *cache0 = new Cache(l, k, n, 0); // LRU
Cache *cache1 = new Cache(l, k, n, 1); // pseudoLRU
Cache *cache2 = new Cache(l, k, n, 2); // random
int bytes, word0, a, type, burstcount;
int hits = 0;
int tcount = 0;
while (bytes = read(tf, buf, sizeof(buf)))
{
for (int i = 0; i < bytes / (int) sizeof(trace); i++, tcount++)
{
word0 = buf[i].word0;
a = (word0 & ADDRESSMASK) << 2;
type = (word0 >> TYPESHIFT) & TYPEMASK;
burstcount = ((word0 >> BURSTSHIFT) & BURSTMASK) + 1;
cache0->hit(a);
cache1->hit(a);
cache2->hit(a);
}
}
printf("Hits: %d Total: %d\n", LRUHits, tcount);
printf("Hits: %d Total: %d\n", pLRUHits, tcount);
printf("Hits: %d Total: %d\n\n\n", randomHits, tcount);
delete cache0;
delete cache1;
delete cache2;
}
int _tmain(int argc, _TCHAR* argv[])
{
//analyse(16, 1, 8);
analyse(16, 2, 512);
//analyse(16, 4, 256);
//analyse(16, 8, 128);
//analyse(16, 1024, 1);
_getch();
return 0;
}
Your question hasn't yet been pounced upon, probably because your code still doesn't compile since you've not provided main.h.
And even then it would annoy most folks trying to help you because you make no mention of the ico0.trace file that is required to prevent the code from immediately exiting.
You say int min = treeArray[set]->root->findPLRU(); access violates.
1) the value of set can never exceed the size n of your treeArray since you & n-1 the range of input values.
2) since your ~Tree() destructor is never called there will always be a treeArray[set]->root
3) since you *always create new left & right nodes whenever leftCacheLine = -1 or rightCacheLine = -1 it cannot be due to recursive findPLRUs
So, the pointer to the node is not being "lost" somewhere; it is being stomped on.
Try replacing:
int min = treeArray[set]->root->findPLRU();
c[min].tag = tag;
c[min].access = access;
with:
int min = treeArray[set]->root->findPLRU();
if (min >= k*n)
{
printf("ook\n");
}
else
{
c[min].tag = tag;
c[min].access = access;
}
and I think you will discover what's doing the stomping. ;)