#include "Cache.h" #include #include #define BUFFERING 100 class mem_counter { int size; int fr; public: mem_counter():size(0),fr(0){} void add(int z){size+=z;} void free(int z){fr+=z;} ~mem_counter() { // cout<<"Allocated "<streams) streams=req_buf[i].id; if(streams<0) { return 0;//req_buf is completely clean } // Init priority table int* bases=new int[streams+1]; mc.add((streams+1)*4); for(i=0; istreams)cerr<<"Oops: id "<=MAXSTREAMS) { printf("Only %d cached streams are supported\n", MAXSTREAMS); return -1; } if(position>=length) return -1; m_tables [id]=table; m_lengths [id]=length; m_positions [id]=position; return 0; } int Cache::Create(int m_fd) { printf("Cache: Creating cache for file descriptor %d\n", m_fd); thread_arg* str; int result; int i; pthread_mutex_init(&mutex_in, 0); pthread_mutex_init(&mutex_out, 0); for(i=0; ifd=m_fd; str->mutex_in=&mutex_in; str->mutex_out=&mutex_out; str->cond_in=&cond_in; str->cond_out=&cond_out; str->req_buf=req_buf; str->buffers_busy=&buffers_busy; str->quit=&m_quit; result=pthread_create(&thread, 0, &readfunc, str); if(result!=0)perror("Creating thread"); m_status=ASYNC; return 0; // Sync(); // usleep(100000); } Cache::~Cache() { m_quit=1; if(m_status==ASYNC) { pthread_cond_broadcast(&cond_in); pthread_join(thread, NULL); pthread_cond_destroy(&cond_in); pthread_cond_destroy(&cond_out); pthread_mutex_destroy(&mutex_in); pthread_mutex_destroy(&mutex_out); for(int i=0; i=MAXSTREAMS)return E_ERROR; if(position>=m_lengths[id])return E_ERROR; cache_right++; __int64 offset=m_tables[id][position].pos; Unsigned max_size=(m_tables[id][position].size & 0x7FFFFFFF) +8; // printf("Actual size %d\n", max_size-8); // printf("Offset %Lx, size %Lx", offset, max_size); m_positions[id]=position; Update(); int freebuf=0; int waiting=0; int ready=0; in1: for(int i=0; imax_size-in_pos-8) size=max_size-in_pos-8; memcpy(buffer, req_buf[i].memory+in_pos+8, size); // printf("Ending read\n"); // printf("Deleting\n"); // pthread_mutex_lock(&mutex_out); // delete req_buf[i].memory; // req_buf[i].memory=0; // req_buf[i].st=req::BUFFER_CLEAN; // t2=lcount(); // pthread_mutex_unlock(&mutex_out); // printf("Success\n"); // printf("Read: read %d bytes at %f ms\n", // req_buf[i].size, (t2-t1)/550000.); return size; } } // printf("Read: no buffer found ( %d free, %d waiting, %d ready )\n", freebuf, waiting, ready); Prefetch(id, position); cache_miss++; goto in1; } int InputStream::Read(char* buffer, Unsigned size) { int ans=read(m_fd, buffer, size); return ans; } int Cache::Prefetch(Unsigned id, Unsigned position) //offset_t offset, Unsigned size) { // printf("Prefetch(%d, %d)\n", id, position); if(id>=MAXSTREAMS)return E_ERROR; if(position>=m_lengths[id])return E_ERROR; __int64 offset=m_tables[id][position].pos; Unsigned size=(m_tables[id][position].size & 0x7FFFFFFF) +8; // Unsigned size=m_tables[id][position].size+8; /* offset_t offset=m_tables[id][position].dwChunkOffset; Unsigned size=m_tables[id][position].dwChunkLength+8;*/ // printf("Prefetch():resolved to %d,%d\n", offset, size); int i; for(i=0; icpr)priority=cpr; break; // printf("waiting\n");break; case req::BUFFER_WRITING: writing++; break; // printf("writing\n");break; case req::BUFFER_READY: ready++; break; // printf("ready\n");break; } } // if(waiting!=0) // printf("Cache status: %d waiting ( lowest priority %d ), %d writing, %d ready, %d clean\n", // waiting, priority, writing, ready, free_reqs); } pthread_mutex_unlock(&mutex_out); int c_id=0, c_pos=1; // printf("%d free reqs\n", free_reqs); free_reqs-=2; while(free_reqs>0) { if(m_tables[c_id]!=0) { if(c_pos+m_positions[c_id]>=m_lengths[c_id]) break; if(c_pos>=m_size) break; if(flags[c_id][c_pos]==0) { if(m_lengths[c_id]<=(m_positions[c_id]+c_pos)) continue; Prefetch(c_id, m_positions[c_id]+c_pos); free_reqs--; } } c_id++; if(c_id==MAXSTREAMS) { c_id=0; c_pos++; } } for(i=0; i