/* allocate a DirEntry in the directory `dirEntry' * its address in filesystem is returned in addr */ int allocateDirEntry(DirEntry *dirEntry,ULONG * value_addr) { int result = _traverse(dirEntry,traverse_availableDirEntry,value_addr); /* result == 1 means all clusters of dirEntry were searched * which means we can not found a available entry * allocate a new cluster to get one */ if( result == 1 ) { #ifdef DEBUG printf("No available Dir Entry in current cluster !\n"); #endif /* search the last cluster in the FAT chain * allocate a new cluster and append it to the last cluster */ ULONG startCluster = getDirClusterNum(dirEntry); ULONG last = getLastCluster(startCluster); ULONG newCluster = allocateCluster(); if( newCluster == 0 ) report_exit("Not enough space!\n"); FAT[last] = newCluster; FAT[newCluster] = EOD; updateAllFat(); /* allocate the first dir entry in the cluster */ *value_addr = (cluster2sector( newCluster ) * bps); } #ifdef DEBUG printf("Allocated dirEntry address: 0x%08x\n",(int)*value_addr); #endif return 1; }
void* runRThreads(void *pvpDCluster) { t_Cluster **pptDCluster = (t_Cluster **) pvpDCluster; t_Cluster *ptDCluster = (t_Cluster *) *pptDCluster; double dBestVBL = -DBL_MAX; t_Cluster** aptCluster = NULL; pthread_t atRestarts[N_RTHREADS]; /*run each restart on a separate thread*/ int iret[N_RTHREADS]; int r = 0, nBestR = -1; char *szCOutFile = NULL; aptCluster = (t_Cluster **) malloc(N_RTHREADS*sizeof(t_Cluster*)); if(!aptCluster) goto memoryError; for(r = 0; r < N_RTHREADS; r++){ if(ptDCluster->szCOutFile != NULL){ szCOutFile = (char *) malloc(sizeof(char)*MAX_FILE_NAME_LENGTH); sprintf(szCOutFile,"%sr%d.csv",ptDCluster->szCOutFile,r); } aptCluster[r] = (t_Cluster *) malloc(sizeof(t_Cluster)); allocateCluster(aptCluster[r],ptDCluster->nN,ptDCluster->nK,ptDCluster->nD,ptDCluster->ptData,ptDCluster->lSeed + r*R_PRIME,ptDCluster->nMaxIter,ptDCluster->dEpsilon,szCOutFile); aptCluster[r]->ptVBParams = ptDCluster->ptVBParams; aptCluster[r]->nThread = r; iret[r] = pthread_create(&atRestarts[r], NULL, fitEM, (void*) aptCluster[r]); } for(r = 0; r < N_RTHREADS; r++){ pthread_join(atRestarts[r], NULL); } /*free up memory associated with input cluster*/ free(ptDCluster); for(r = 0; r < N_RTHREADS; r++){ if(aptCluster[r]->dVBL > dBestVBL){ nBestR = r; dBestVBL = aptCluster[r]->dVBL; } } *pptDCluster = aptCluster[nBestR]; for(r = 0; r < N_RTHREADS; r++){ if(r != nBestR){ destroyCluster(aptCluster[r]); free(aptCluster[r]); } } free(aptCluster); return NULL; memoryError: fprintf(stderr, "Failed allocating memory in runRThreads\n"); fflush(stderr); exit(EXIT_FAILURE); }
/* Write content to a new file */ int writeFile(char* filename,const char * inputname,char mode) { #ifdef DEBUG printf("** write file **\n"); #endif /* get the parent directory name and basename */ char dirname[80]="/",basename[80]; if( getDirBaseName(dirname,basename,filename) == 0 ) report_exit("Invalid filename\n"); int inputfd = open(inputname,O_RDONLY); #ifdef DEBUG printf("dirname: [%s]\n",dirname); printf("basename:[%s]\n",basename); #endif /* Check if its containing directory exist */ DirEntry dirEntry,baseEntry; if( locateFileInFS(dirname,&dirEntry) == 0) return 0; /* the address of the baseEntry */ ULONG addr; /* write pointer */ ULONG writeAddr=0; /* bytes per cluster */ ULONG bCluster = bps*spc; /* check if the file exists */ if( locateFileInDir(basename,&dirEntry,&baseEntry,&addr) == 0 ) { #ifdef DEBUG printf("allocate new DirEntry\n"); #endif /* allocate a new entry in its containg directory * or find a new one in another cluster */ allocateDirEntry(&dirEntry,&addr); /* initialize the DirEntry */ memset(&baseEntry,0,sizeof(DirEntry)); baseEntry.DIR_FileSize = 0; setDirClusHiLo(&baseEntry,0); setDirEntryFileName(&baseEntry,basename); baseEntry.DIR_Attr = ATTR_ARC; updateDirEntry(addr,&baseEntry); } else { /* otherwise use the existing entry in 'baseEntry'*/ if( mode == 't' ) { /* write mode:unallocate the FAT chain */ ULONG c_num = getDirClusterNum(&baseEntry); #ifdef DEBUG printf("Unalocate FAT chain,start cluster :%lu\n",c_num); #endif baseEntry.DIR_FileSize = 0; setDirClusHiLo(&baseEntry,0); updateDirEntry(addr,&baseEntry); unallocateFatChain(c_num); } else { /* append mode: continue with the FAT chain */ ULONG fileSize=baseEntry.DIR_FileSize; ULONG startCluster=getDirClusterNum(&baseEntry); ULONG last = getLastCluster(startCluster); ULONG totalCluster = getClusterChainSize(startCluster); ULONG left=totalCluster*spc*bps-fileSize; ULONG bytesInLast = bCluster - left; writeAddr = getClusterOffset(last) + bytesInLast; } } /* update the 1st FAT in fs */ updateFat(0); /* read sth. from stdin,every time a cluster */ int len,result = 1; ULONG startCluster = getDirClusterNum(&baseEntry); ULONG fileSize = baseEntry.DIR_FileSize; ULONG totalCluster = getClusterChainSize(startCluster); ULONG left=totalCluster*spc*bps-fileSize; ULONG p=getLastCluster(getDirClusterNum(&baseEntry)),q=0; #ifdef DEBUG printf("fileSize=%lu,totalCluster=%lu,startCluster=%lu,left=%lu\n", fileSize,totalCluster,startCluster,left); #endif lseek(fd, writeAddr, SEEK_SET); /* every time read a cluster */ while( (len=read(inputfd,(void*)buffer,bCluster))!=0) { fileSize+=len; buffer[len]=0; #ifdef DEBUG printf("len=%d buffer:%s\n",len,buffer); #endif if( left >= len ) { #ifdef DEBUG printf("Before=%lu, After=%lu\n",left,left-len); #endif write(fd,buffer,len); left-=len; } else { /* not enought space, allocate new cluster */ #ifdef DEBUG printf("Before=%lu,full!\n",left); #endif /* write the enought part to current cluster */ write(fd,buffer,left); q=p; p=allocateCluster(); /* write the remaining part to new cluster */ writeAddr = getClusterOffset(p); lseek(fd, writeAddr, SEEK_SET); write(fd,buffer+left,len-left); #ifdef DEBUG printf("Write %lu to new cluster,left=%lu\n",len-left,bCluster-(len-left)); #endif left = bCluster-(len-left); /* update the starting cluster if it is first allocated */ if(q==0) setDirClusHiLo(&baseEntry,p); else FAT[q]=p; FAT[p]=EOD; /* update the first FAT in fs,update all later */ updateFat(0); } /* update size field in DirEntry */ baseEntry.DIR_FileSize = fileSize; updateDirEntry(addr,&baseEntry); } updateAllFat(); #ifdef DEBUG printf("** write file end **\n"); #endif return result; }