/*===========================================================================* * fs_breadwrite * *===========================================================================*/ PUBLIC int fs_breadwrite(void) { int r, rw_flag, completed; cp_grant_id_t gid; u64_t position; unsigned int off, cum_io, chunk, block_size; size_t nrbytes; dev_t target_dev; /* Pseudo inode for rw_chunk */ struct inode rip; r = OK; target_dev = (dev_t) fs_m_in.REQ_DEV2; /* Get the values from the request message */ rw_flag = (fs_m_in.m_type == REQ_BREAD ? READING : WRITING); gid = (cp_grant_id_t) fs_m_in.REQ_GRANT; position = make64((unsigned long) fs_m_in.REQ_SEEK_POS_LO, (unsigned long) fs_m_in.REQ_SEEK_POS_HI); nrbytes = (size_t) fs_m_in.REQ_NBYTES; block_size = get_block_size(target_dev); /* Don't block-write to a RO-mounted filesystem. */ if(superblock.s_dev == target_dev && superblock.s_rd_only) return EROFS; rip.i_zone[0] = (zone_t) target_dev; rip.i_mode = I_BLOCK_SPECIAL; rip.i_size = 0; rdwt_err = OK; /* set to EIO if disk error occurs */ cum_io = 0; /* Split the transfer into chunks that don't span two blocks. */ while (nrbytes > 0) { off = rem64u(position, block_size); /* offset in blk*/ chunk = min(nrbytes, block_size - off); /* Read or write 'chunk' bytes. */ r = rw_chunk(&rip, position, off, chunk, nrbytes, rw_flag, gid, cum_io, block_size, &completed); if (r != OK) break; /* EOF reached */ if (rdwt_err < 0) break; /* Update counters and pointers. */ nrbytes -= chunk; /* bytes yet to be read */ cum_io += chunk; /* bytes read so far */ position = add64ul(position, chunk); /* position within the file */ } fs_m_out.RES_SEEK_POS_LO = ex64lo(position); fs_m_out.RES_SEEK_POS_HI = ex64hi(position); if (rdwt_err != OK) r = rdwt_err; /* check for disk error */ if (rdwt_err == END_OF_FILE) r = OK; fs_m_out.RES_NBYTES = cum_io; return(r); }
/** * The size of a compressed block. * @return Size of a compressed block (4x4) in bytes. */ inline Uint16 get_block_size() const { return get_block_size(get_pixel_size()); }
/*===========================================================================* * fs_readwrite * *===========================================================================*/ PUBLIC int fs_readwrite(void) { int r, rw_flag, block_spec; int regular; cp_grant_id_t gid; off_t position, f_size, bytes_left; unsigned int off, cum_io, block_size, chunk; mode_t mode_word; int completed; struct inode *rip; size_t nrbytes; r = OK; /* Find the inode referred */ if ((rip = find_inode(fs_dev, (ino_t) fs_m_in.REQ_INODE_NR)) == NULL) return(EINVAL); mode_word = rip->i_mode & I_TYPE; regular = (mode_word == I_REGULAR || mode_word == I_NAMED_PIPE); block_spec = (mode_word == I_BLOCK_SPECIAL ? 1 : 0); /* Determine blocksize */ if (block_spec) { block_size = get_block_size( (dev_t) rip->i_block[0]); f_size = MAX_FILE_POS; } else { block_size = rip->i_sp->s_block_size; f_size = rip->i_size; if (f_size < 0) f_size = MAX_FILE_POS; } /* Get the values from the request message */ rw_flag = (fs_m_in.m_type == REQ_READ ? READING : WRITING); gid = (cp_grant_id_t) fs_m_in.REQ_GRANT; position = (off_t) fs_m_in.REQ_SEEK_POS_LO; nrbytes = (size_t) fs_m_in.REQ_NBYTES; rdwt_err = OK; /* set to EIO if disk error occurs */ if (rw_flag == WRITING && !block_spec) { /* Check in advance to see if file will grow too big. */ if (position > (off_t) (rip->i_sp->s_max_size - nrbytes)) return(EFBIG); } cum_io = 0; /* Split the transfer into chunks that don't span two blocks. */ while (nrbytes != 0) { off = (unsigned int) (position % block_size);/* offset in blk*/ chunk = MIN(nrbytes, block_size - off); if (rw_flag == READING) { bytes_left = f_size - position; if (position >= f_size) break; /* we are beyond EOF */ if (chunk > bytes_left) chunk = (int) bytes_left; } /* Read or write 'chunk' bytes. */ r = rw_chunk(rip, cvul64((unsigned long) position), off, chunk, nrbytes, rw_flag, gid, cum_io, block_size, &completed); if (r != OK) break; /* EOF reached */ if (rdwt_err < 0) break; /* Update counters and pointers. */ nrbytes -= chunk; /* bytes yet to be read */ cum_io += chunk; /* bytes read so far */ position += (off_t) chunk; /* position within the file */ } fs_m_out.RES_SEEK_POS_LO = position; /* It might change later and the VFS has to know this value */ /* On write, update file size and access time. */ if (rw_flag == WRITING) { if (regular || mode_word == I_DIRECTORY) { if (position > f_size) rip->i_size = position; } } /* Check to see if read-ahead is called for, and if so, set it up. */ if(rw_flag == READING && rip->i_seek == NO_SEEK && (unsigned int) position % block_size == 0 && (regular || mode_word == I_DIRECTORY)) { rdahed_inode = rip; rdahedpos = position; } rip->i_seek = NO_SEEK; if (rdwt_err != OK) r = rdwt_err; /* check for disk error */ if (rdwt_err == END_OF_FILE) r = OK; if (r == OK) { if (rw_flag == READING) rip->i_update |= ATIME; if (rw_flag == WRITING) rip->i_update |= CTIME | MTIME; rip->i_dirt = DIRTY; /* inode is thus now dirty */ } fs_m_out.RES_NBYTES = cum_io; return(r); }
void InitBLAC(Bsystem *Bsys){ int i,j; int *BLACS_PARAMS; static int INIT_FLAG_COMM = 0; Bsys->Pmat->info.lenergy.DESC_ivert = ivector(0,8); Bsys->Pmat->info.lenergy.DESC_rhs = ivector(0,8); Bsys->Pmat->info.lenergy.BLACS_PARAMS = ivector(0,14); BLACS_PARAMS = Bsys->Pmat->info.lenergy.BLACS_PARAMS; BLACS_PARAMS[7] = Bsys->pll->nv_gpsolve; BLACS_PARAMS[8] = Bsys->pll->nv_gpsolve; /* determinate dimension of grid of CPUs */ get_proc_grid(pllinfo[get_active_handle()].nprocs, &i, &j); BLACS_PARAMS[3] = i; BLACS_PARAMS[4] = j; /* determinate size of basic block in global boundary operator */ BLACS_PARAMS[9] = get_block_size(BLACS_PARAMS[7], BLACS_PARAMS[3]); BLACS_PARAMS[10] = get_block_size(BLACS_PARAMS[8], BLACS_PARAMS[4]); if (BLACS_PARAMS[9] < BLACS_PARAMS[10]) BLACS_PARAMS[10] = BLACS_PARAMS[9]; else BLACS_PARAMS[9] = BLACS_PARAMS[10]; blacs_gridinit_nektar(BLACS_PARAMS, Bsys->Pmat->info.lenergy.DESC_ivert, Bsys->Pmat->info.lenergy.DESC_rhs); /* allocate memory for local partition of ivert */ /* since we use ScaLAPACK (fortran)- use transpose of inva_LOC */ Bsys->Pmat->info.lenergy.ivert_local = dmatrix(0,BLACS_PARAMS[12]-1, 0,BLACS_PARAMS[11]-1); memset(Bsys->Pmat->info.lenergy.ivert_local[0],'\0',BLACS_PARAMS[11]* BLACS_PARAMS[12]*sizeof(double)); Bsys->Pmat->info.lenergy.ivert_ipvt = ivector(0,BLACS_PARAMS[7]-1); Bsys->Pmat->info.lenergy.map_row = ivector(0,BLACS_PARAMS[11]-1); get_gather_map(BLACS_PARAMS,'r',Bsys->Pmat->info.lenergy.map_row); Bsys->Pmat->info.lenergy.col_displs = ivector(0,BLACS_PARAMS[3]-1); Bsys->Pmat->info.lenergy.col_rcvcnt = ivector(0,BLACS_PARAMS[3]-1); memset(Bsys->Pmat->info.lenergy.col_displs,'\0',BLACS_PARAMS[3]*sizeof(int)); memset(Bsys->Pmat->info.lenergy.col_rcvcnt,'\0',BLACS_PARAMS[3]*sizeof(int)); /* create row and column communicators by splitting */ /* all processors construct 2D grid */ if (INIT_FLAG_COMM == 0){ int info; info = MPI_Comm_split(get_MPI_COMM(), BLACS_PARAMS[6], BLACS_PARAMS[5], &MPI_COMM_COLUMN_NEW); if (info != MPI_SUCCESS){ fprintf (stderr, "scatter_topology_nektar: MPI split error\n"); exit(1); } info = MPI_Comm_split(get_MPI_COMM(), BLACS_PARAMS[5], BLACS_PARAMS[6], &MPI_COMM_ROW_NEW); if (info != MPI_SUCCESS) { fprintf (stderr, "scatter_topology_nektar: MPI split error\n"); exit(1); } INIT_FLAG_COMM = 1; } /* summary */ for (i = 0; i < 13; i++) if (pllinfo[get_active_handle()].procid == 0) printf(" Ubsys->Gmat->BLACS_PARAMS[%d] = %d \n ",i,Bsys->Pmat->info.lenergy.BLACS_PARAMS[i]); }
main(int argc, char **argv) { int disk_fd, c; char *disk_devname, *ssd_devname, *cachedev; sector_t block_size = 0, cache_size = 0; sector_t disk_devsize; int write_around = 0; pname = argv[0]; while ((c = getopt(argc, argv, "fs:b:vr")) != -1) { switch (c) { case 's': cache_size = get_cache_size(optarg); break; case 'b': block_size = get_block_size(optarg); /* Block size should be a power of 2 */ break; case 'v': verbose = 1; break; case 'f': force = 1; break; case 'r': write_around = 1; break; case '?': usage(pname); } } if (optind == argc) usage(pname); if (block_size == 0) block_size = 8; /* 4KB default blocksize */ cachedev = argv[optind++]; if (optind == argc) usage(pname); ssd_devname = argv[optind++]; if (optind == argc) usage(pname); disk_devname = argv[optind]; disk_fd = open(disk_devname, O_RDONLY); if (disk_fd < 0) { fprintf(stderr, "%s: Failed to open %s\n", pname, disk_devname); exit(1); } if (ioctl(disk_fd, BLKGETSIZE, &disk_devsize) < 0) { fprintf(stderr, "%s: Cannot get disk size %s\n", pname, disk_devname); exit(1); } printf("cachedev %s, ssd_devname %s, disk_devname %s\n", cachedev, ssd_devname, disk_devname); printf("cache mode %s, block_size %lu, cache_size %lu\n", ((write_around) ? "WRITE_AROUND" : "WRITE_THRU"), block_size, cache_size); sprintf(dmsetup_cmd, "echo 0 %lu flashcache-wt %s %s %d %lu ", disk_devsize, disk_devname, ssd_devname, write_around, block_size); if (cache_size > 0) { char cache_size_str[4096]; sprintf(cache_size_str, "%lu ", cache_size); strcat(dmsetup_cmd, cache_size_str); } /* Go ahead and create the cache. * XXX - Should use the device mapper library for this. */ strcat(dmsetup_cmd, "| dmsetup create "); strcat(dmsetup_cmd, cachedev); strcat(dmsetup_cmd, "\n"); load_module(); if (verbose) fprintf(stderr, "Creating FlashCache_wt Volume : %s", dmsetup_cmd); system(dmsetup_cmd); }
uint32_t nrf_mem_reserve(uint8_t ** pp_buffer, uint32_t * p_size) { VERIFY_MODULE_INITIALIZED(); NULL_PARAM_CHECK(pp_buffer); NULL_PARAM_CHECK(p_size); const uint32_t requested_size = (*p_size); VERIFY_REQUESTED_SIZE(requested_size); NRF_LOG_DEBUG("[MM]: >> nrf_mem_reserve, size 0x%04lX.\r\n", requested_size); MM_MUTEX_LOCK(); const uint32_t block_cat = get_block_cat(requested_size, TOTAL_BLOCK_COUNT); uint32_t block_index = m_block_start[block_cat]; uint32_t memory_index = m_block_mem_start[block_cat]; uint32_t err_code = (NRF_ERROR_NO_MEM | MEMORY_MANAGER_ERR_BASE); NRF_LOG_DEBUG("[MM]: Start index for the pool = 0x%08lX, total block count 0x%08X\r\n", block_index, TOTAL_BLOCK_COUNT); for (; block_index < TOTAL_BLOCK_COUNT; block_index++) { uint32_t block_size = get_block_size(block_index); if (is_block_free(block_index) == true) { NRF_LOG_DEBUG("[MM]: Reserving block 0x%08lX\r\n", block_index); // Search succeeded, found free block. err_code = NRF_SUCCESS; // Allocate block. block_allocate(block_index); (*pp_buffer) = &m_memory[memory_index]; (*p_size) = block_size; #ifdef MEM_MANAGER_ENABLE_DIAGNOSTICS (*p_min_size) = MIN((*p_min_size), requested_size); (*p_max_size) = MAX((*p_max_size), requested_size); #endif // MEM_MANAGER_ENABLE_DIAGNOSTICS break; } memory_index += block_size; } if (err_code != NRF_SUCCESS) { NRF_LOG_DEBUG ("[MM]: Memory reservation result %d, memory %p, size %d!", err_code, (uint32_t)(*pp_buffer), (*p_size)); #ifdef MEM_MANAGER_ENABLE_DIAGNOSTICS nrf_mem_diagnose(); #endif // MEM_MANAGER_ENABLE_DIAGNOSTICS } MM_MUTEX_UNLOCK(); NRF_LOG_DEBUG("[MM]: << nrf_mem_reserve %p, result 0x%08lX.\r\n", (uint32_t)(*pp_buffer), err_code); return err_code; }
// Return a pointer to a block given its number. // get_block(fs, 0) == fs; void * _ref_get_block(void * fs, __u32 block_num) { __u32 block_size = get_block_size(fs); return fs + (block_num * block_size); }
/* start from bootloader_message.slot_suffix[BOOTCTRL_IDX] */ #define BOOTCTRL_IDX 0 #define BOOTCTRL_OFFSET \ (u32)(&(((struct bootloader_message *)0)->slot_suffix[BOOTCTRL_IDX])) #define CRC_DATA_OFFSET \ (uint32_t)(&(((struct boot_ctl *)0)->a_slot_meta[0])) struct slot_meta { u8 bootsuc:1; u8 tryremain:3; u8 priority:4; }; struct boot_ctl { char magic[4]; /* "\0FSL" */ u32 crc; struct slot_meta a_slot_meta[SLOT_NUM]; u8 recovery_tryremain; }; static unsigned int g_mmc_id; static unsigned int g_slot_selected; static const char *g_slot_suffix[SLOT_NUM] = {"_a", "_b"}; static int do_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); static int strcmp_l1(const char *s1, const char *s2) { if (!s1 || !s2) return -1; return strncmp(s1, s2, strlen(s1)); } void set_mmc_id(unsigned int id) { g_mmc_id = id; } static void dump_slotmeta(struct boot_ctl *ptbootctl) { int i; if (ptbootctl == NULL) return; printf("RecoveryTryRemain %d, crc %u\n", ptbootctl->recovery_tryremain, ptbootctl->crc); for (i = 0; i < SLOT_NUM; i++) { printf("slot %d: pri %d, try %d, suc %d\n", i, ptbootctl->a_slot_meta[i].priority, ptbootctl->a_slot_meta[i].tryremain, ptbootctl->a_slot_meta[i].bootsuc); } return; } const char *get_slot_suffix(void) { return g_slot_suffix[g_slot_selected]; } static unsigned int slot_find(struct boot_ctl *ptbootctl) { unsigned int max_pri = 0; unsigned int slot = -1; int i; for (i = 0; i < SLOT_NUM; i++) { struct slot_meta *pslot_meta = &(ptbootctl->a_slot_meta[i]); if ((pslot_meta->priority > max_pri) && ((pslot_meta->bootsuc > 0) || (pslot_meta->tryremain > 0))) { max_pri = pslot_meta->priority; slot = i; printf("select_slot slot %d\n", slot); } } return slot; } static ulong get_block_size(char *ifname, int dev, int part) { block_dev_desc_t *dev_desc = NULL; disk_partition_t part_info; dev_desc = get_dev(ifname, dev); if (dev_desc == NULL) { printf("Block device %s %d not supported\n", ifname, dev); return 0; } if (get_partition_info(dev_desc, part, &part_info)) { printf("Cannot find partition %d\n", part); return 0; } return part_info.blksz; } #define ALIGN_BYTES 64 /*armv7 cache line need 64 bytes aligned */ static int rw_block(bool bread, char **ppblock, uint *pblksize, char *pblock_write) { int ret; char *argv[6]; char addr_str[20]; char cnt_str[8]; char devpart_str[8]; char block_begin_str[8]; ulong blk_size = 0; uint blk_begin = 0; uint blk_end = 0; uint block_cnt = 0; char *p_block = NULL; if (bread && ((ppblock == NULL) || (pblksize == NULL))) return -1; if (!bread && (pblock_write == NULL)) return -1; blk_size = get_block_size("mmc", g_mmc_id, CONFIG_ANDROID_MISC_PARTITION_MMC); if (blk_size == 0) { printf("rw_block, get_block_size return 0\n"); return -1; } blk_begin = BOOTCTRL_OFFSET/blk_size; blk_end = (BOOTCTRL_OFFSET + sizeof(struct boot_ctl) - 1)/blk_size; block_cnt = 1 + (blk_end - blk_begin); sprintf(devpart_str, "0x%x:0x%x", g_mmc_id, CONFIG_ANDROID_MISC_PARTITION_MMC); sprintf(block_begin_str, "0x%x", blk_begin); sprintf(cnt_str, "0x%x", block_cnt); argv[0] = "rw"; /* not care */ argv[1] = "mmc"; argv[2] = devpart_str; argv[3] = addr_str; argv[4] = block_begin_str; argv[5] = cnt_str; if (bread) { p_block = (char *)memalign(ALIGN_BYTES, blk_size * block_cnt); if (NULL == p_block) { printf("rw_block, memalign %d bytes failed\n", (int)(blk_size * block_cnt)); return -1; } sprintf(addr_str, "0x%x", (unsigned int)p_block); ret = do_read(NULL, 0, 6, argv); if (ret) { free(p_block); printf("do_read failed, ret %d\n", ret); return -1; } *ppblock = p_block; *pblksize = (uint)blk_size; } else { sprintf(addr_str, "0x%x", (unsigned int)pblock_write); ret = do_write(NULL, 0, 6, argv); if (ret) { printf("do_write failed, ret %d\n", ret); return -1; } } return 0; }
// Return a pointer to a block given its number. // get_block(fs, 0) == fs; void * get_block(void * fs, __u32 block_num) { return fs + block_num * get_block_size(fs); }
// Return a pointer to a block given its number. // get_block(fs, 0) == fs; void * get_block(void * fs, __u32 block_num) { return (void *) ((size_t) fs + get_block_size(fs) * block_num); }
int main(int argc, char **argv) { iso_primary_descriptor_type ipd; char *dev = default_dev; char vendor[9],model[17],rev[5]; unsigned char reply[1024]; char tmpstr[255]; int replylen=sizeof(reply); int trackno = 0; int info_only = 0; unsigned char *buffer; int buffersize = READBLOCKS*BLOCKSIZE; int start,stop,imagesize=0,tracksize=0; int counter = 0; long readsize = 0; long imagesize_bytes = 0; int drive_block_size, init_bsize; int force_mode = 0; int scanbus_mode = 0; int dump_start, dump_count; MD5_CTX *MD5; char digest[16],digest_text[33]; int md5_mode = 0; int opt_index = 0; int audio_track = 0; int readblocksize = BLOCKSIZE; int file_format = AF_FILE_AIFFC; #ifdef IRIX CDPARSER *cdp = CDcreateparser(); CDFRAME cdframe; #endif int dev_type; int i,c,o; int len; int start_time,cur_time,kbps; if (rcsid); MD5 = malloc(sizeof(MD5_CTX)); buffer=(unsigned char*)malloc(READBLOCKS*AUDIOBLOCKSIZE); if (!buffer || !MD5) die("No memory"); if (argc<2) die("parameter(s) missing\n" "Try '%s --help' for more information.\n",PRGNAME); /* parse command line parameters */ while(1) { if ((c=getopt_long(argc,argv,"SMmvhid:",long_options,&opt_index)) == -1) break; switch (c) { case 'a': file_format=AF_FILE_AIFF; break; case 'A': file_format=AF_FILE_AIFFC; break; case 'v': verbose_mode=1; break; case 'h': p_usage(); break; case 'd': dev=strdup(optarg); break; case 't': if (sscanf(optarg,"%d",&trackno)!=1) trackno=0; break; case 'i': info_only=1; break; case 'c': if (sscanf(optarg,"%d,%d",&dump_start,&dump_count)!=2) die("invalid parameters"); dump_mode=1; break; #ifdef IRIX case 'C': if (sscanf(optarg,"%d,%d",&dump_start,&dump_count)!=2) die("invalid parameters"); dump_mode=2; break; #endif case 'f': if (sscanf(optarg,"%d",&force_mode)!=1) die("invalid parameters"); if (force_mode<1 || force_mode >2) { die("invalid parameters"); } break; case 'm': md5_mode=1; break; case 'M': md5_mode=2; break; case 's': audio_mode=1; break; case 'S': scanbus_mode=1; break; case 'V': printf(PRGNAME " " VERSION " " HOST_TYPE "\nCopyright (c) Timo Kokkonen, 1997-1998.\n\n"); exit(0); break; case '?': break; default: die("error parsing parameters"); } } if (!info_only) { if (md5_mode==2) outfile=fopen("/dev/null","w"); else outfile=fopen(argv[optind],"w"); if (!outfile) { if (argv[optind]) die("cannot open output file '%s'",argv[optind]); info_only=1; } } printf("readiso(9660) " VERSION "\n"); /* open the scsi device */ if (scsi_open(dev)) die("error opening scsi device '%s'",dev); if (scanbus_mode) { printf("\n"); scan_bus(); exit(0); } memset(reply,0,sizeof(reply)); if ((dev_type=inquiry(vendor,model,rev))<0) die("error accessing scsi device"); if (verbose_mode) { printf("device: %s\n",dev); printf("Vendor: %s\nModel: %s\nRevision: %s\n",vendor,model,rev); } if ( (dev_type&0x1f) != 0x5 ) { die("Device doesn't seem to be a CD-ROM!"); } #ifdef IRIX if (strcmp(vendor,"TOSHIBA")) { warn("NOTE! Audio track reading probably not supported on this device.\n"); } #endif test_ready(); if (test_ready()!=0) { sleep(2); if (test_ready()!=0) die("device not ready"); } fprintf(stderr,"Initializing...\n"); if (audio_mode) { #ifdef IRIX audioport=ALopenport("readiso","w",0); if (!audioport) { warn("Cannot initialize audio."); audio_mode=0; } #else audio_mode=0; #endif } #ifdef IRIX /* Make sure we get sane underflow exception handling */ sigfpe_[_UNDERFL].repls = _ZERO; handle_sigfpes(_ON, _EN_UNDERFL, NULL, _ABORT_ON_ERROR, NULL); #endif /* set_removable(1); */ #if 0 replylen=255; if (mode_sense10(reply,&replylen)==0) { printf("replylen=%d blocks=%d blocklen=%d\n",replylen, V3(&reply[8+1]),V3(&reply[8+5])); PRINT_BUF(reply,replylen); } replylen=255; /* sizeof(reply); */ if (mode_sense(reply,&replylen)==0) { printf("replylen=%d blocks=%d blocklen=%d\n",replylen, V3(&reply[4+1]),V3(&reply[4+5])); PRINT_BUF(reply,replylen); } #endif if (dump_mode==2) init_bsize=AUDIOBLOCKSIZE; else init_bsize=BLOCKSIZE; start_stop(0); if ( (drive_block_size=get_block_size()) < 0 ) { warn("cannot get current block size"); drive_block_size=init_bsize; } if (drive_block_size != init_bsize) { mode_select(init_bsize,(dump_mode==2?0x82:0x00)); drive_block_size=get_block_size(); if (drive_block_size!=init_bsize) warn("cannot set drive block size."); } start_stop(1); if (dump_mode && !info_only) { #ifdef IRIX CDFRAME buf; if (dump_mode==2) { if (cdp) { CDaddcallback(cdp, cd_audio, (CDCALLBACKFUNC)playaudio, 0); } else die("No audioparser"); } #endif fprintf(stderr,"Dumping %d sector(s) starting from LBA=%d\n", dump_count,dump_start); for (i=dump_start;i<dump_start+dump_count;i++) { len=buffersize; read_10(i,1,buffer,&len); if (len<init_bsize) break; #ifdef IRIX if (dump_mode==2) { memcpy(&buf,buffer,CDDA_BLOCKSIZE); CDparseframe(cdp,&buf); } #endif fwrite(buffer,len,1,outfile); fprintf(stderr,"."); } fprintf(stderr,"\ndone.\n"); goto quit; } fprintf(stderr,"Reading disc TOC..."); replylen=sizeof(reply); read_toc(reply,&replylen,verbose_mode); printf("\n"); if (trackno==0) { /* try to find first data track */ for (i=0;i<(reply[3]-reply[2]+1);i++) { o=4+i*8; if (reply[o+1]&DATA_TRACK) { trackno=i+1; break; } } if (trackno==0) die("No data track(s) found."); } fprintf(stderr,"Reading track %d...\n",trackno); if ( (trackno < reply[2]) || (trackno > reply[3]) ) die("Invalid track specified."); if ( ((reply[(trackno-1)*8+4+1]&DATA_TRACK)==0) ) { fprintf(stderr,"Not a data track.\n"); mode_select(AUDIOBLOCKSIZE,0x82); if (mode_sense(reply,&replylen)!=0) die("cannot get sense data"); drive_block_size=V3(&reply[9]); fprintf(stderr,"Selecting CD-DA mode, output file format: %s\n", file_format==AF_FILE_AIFFC?"AIFFC":"AIFF"); audio_track=1; } else { audio_track=0; } start=V4(&reply[(trackno-1)*8+4+4]); stop=V4(&reply[(trackno)*8+4+4]); tracksize=abs(stop-start); /* if (verbose_mode) printf("Start LBA=%d\nStop LBA=%d\n",start,stop); */ len=buffersize; read_10(start-0,1,buffer,&len); /* PRINT_BUF(buffer,32); */ if (!audio_track) { /* read the iso9660 primary descriptor */ fprintf(stderr,"Reading ISO9660 primary descriptor...\n"); len=buffersize; read_10(start+16,1,buffer,&len); if (len<sizeof(ipd)) die("cannot read iso9660 primary descriptor."); memcpy(&ipd,buffer,sizeof(ipd)); imagesize=ISONUM(ipd.volume_space_size); /* we should really check here if we really got a valid primary descriptor or not... */ if ( (imagesize>(stop-start)) || (imagesize<1) ) { fprintf(stderr,"\aInvalid ISO primary descriptor!!!\n"); if (!info_only) fprintf(stderr,"Copying entire track to image file.\n"); force_mode=2; } if (force_mode==1) {} /* use size from ISO primary descriptor */ else if (force_mode==2) imagesize=tracksize; /* use size from TOC */ else { if ( ( (tracksize-imagesize) > MAX_DIFF_ALLOWED ) || ( imagesize > tracksize ) ) { fprintf(stderr,"ISO primary descriptor has suspicious volume size" " (%d blocks)\n",imagesize); imagesize=tracksize; fprintf(stderr, "Using track size from TOC record (%d blocks) instead.\n", imagesize); fprintf(stderr, "(option -f can be used to override this behaviour.)\n"); } } imagesize_bytes=imagesize*BLOCKSIZE; if (verbose_mode||info_only) { printf("ISO9660 image info:\n"); printf("Type: %02xh\n",ipd.type[0]); ISOGETSTR(tmpstr,ipd.id,5); printf("ID: %s\n",tmpstr); printf("Version: %u\n",ipd.version[0]); ISOGETSTR(tmpstr,ipd.system_id,32); printf("System id: %s\n",tmpstr); ISOGETSTR(tmpstr,ipd.volume_id,32); printf("Volume id: %s\n",tmpstr); ISOGETSTR(tmpstr,ipd.volume_set_id,128); if (strlen(tmpstr)>0) printf("Volume set id: %s\n",tmpstr); ISOGETSTR(tmpstr,ipd.publisher_id,128); if (strlen(tmpstr)>0) printf("Publisher id: %s\n",tmpstr); ISOGETSTR(tmpstr,ipd.preparer_id,128); if (strlen(tmpstr)>0) printf("Preparer id: %s\n",tmpstr); ISOGETSTR(tmpstr,ipd.application_id,128); if (strlen(tmpstr)>0) printf("Application id: %s\n",tmpstr); ISOGETDATE(tmpstr,ipd.creation_date); printf("Creation date: %s\n",tmpstr); ISOGETDATE(tmpstr,ipd.modification_date); if (!NULLISODATE(ipd.modification_date)) printf("Modification date: %s\n",tmpstr); ISOGETDATE(tmpstr,ipd.expiration_date); if (!NULLISODATE(ipd.expiration_date)) printf("Expiration date: %s\n",tmpstr); ISOGETDATE(tmpstr,ipd.effective_date); if (!NULLISODATE(ipd.effective_date)) printf("Effective date: %s\n",tmpstr); printf("Image size: %02d:%02d:%02d, %d blocks (%ld bytes)\n", LBA_MIN(ISONUM(ipd.volume_space_size)), LBA_SEC(ISONUM(ipd.volume_space_size)), LBA_FRM(ISONUM(ipd.volume_space_size)), ISONUM(ipd.volume_space_size), (long)ISONUM(ipd.volume_space_size)*BLOCKSIZE ); printf("Track size: %02d:%02d:%02d, %d blocks (%ld bytes)\n", LBA_MIN(tracksize), LBA_SEC(tracksize), LBA_FRM(tracksize), tracksize, (long)tracksize*BLOCKSIZE ); } } else { #ifdef IRIX /* if reading audio track */ imagesize=tracksize; imagesize_bytes=imagesize*CDDA_DATASIZE; buffersize = READBLOCKS*AUDIOBLOCKSIZE; readblocksize = AUDIOBLOCKSIZE; if (cdp) { CDaddcallback(cdp, cd_audio, (CDCALLBACKFUNC)playaudio, 0); } else die("No audioparser"); fclose(outfile); aiffsetup=AFnewfilesetup(); AFinitrate(aiffsetup,AF_DEFAULT_TRACK,44100.0); /* 44.1 kHz */ AFinitfilefmt(aiffsetup,file_format); /* set file format */ AFinitchannels(aiffsetup,AF_DEFAULT_TRACK,2); /* stereo */ AFinitsampfmt(aiffsetup,AF_DEFAULT_TRACK, AF_SAMPFMT_TWOSCOMP,16); /* 16bit */ aiffoutfile=AFopenfile(argv[optind],"w",aiffsetup); if (!aiffoutfile) die("Cannot open target file (%s).",argv[optind]); #endif } /* read the image */ if (md5_mode) MD5Init(MD5); if (!info_only) { start_time=(int)time(NULL); fprintf(stderr,"Reading %s (%ldMb)...\n", audio_track?"audio track":"ISO9660 image", imagesize_bytes/(1024*1024)); do { len=buffersize; if(readsize/readblocksize+READBLOCKS>imagesize) { read_10(start+counter,imagesize-readsize/readblocksize,buffer,&len); } else read_10(start+counter,READBLOCKS,buffer,&len); if ((counter%(1024*1024/readblocksize))<READBLOCKS) { cur_time=(int)time(NULL); if ((cur_time-start_time)>0) { kbps=(readsize/1024)/(cur_time-start_time); } else { kbps=0; } fprintf(stderr,"%3dM of %dM read. (%d kb/s) \r", counter/512,imagesize/512,kbps); } counter+=READBLOCKS; readsize+=len; if (!audio_track) { fwrite(buffer,len,1,outfile); } else { #ifdef IRIX /* audio track */ for(i=0;i<(len/CDDA_BLOCKSIZE);i++) { CDparseframe(cdp,(CDFRAME*)&buffer[i*CDDA_BLOCKSIZE]); } #endif } if (md5_mode) MD5Update(MD5,buffer,(readsize>imagesize_bytes? len-(readsize-imagesize_bytes):len) ); } while (len==readblocksize*READBLOCKS&&readsize<imagesize*readblocksize); fprintf(stderr,"\n"); if (!audio_track) { if (readsize > imagesize_bytes) ftruncate(fileno(outfile),imagesize_bytes); if (readsize < imagesize_bytes) fprintf(stderr,"Image not complete!\n"); else fprintf(stderr,"Image complete.\n"); fclose(outfile); } else { #ifdef IRIX AFclosefile(aiffoutfile); #endif } } if (md5_mode && !info_only) { MD5Final((unsigned char*)digest,MD5); md2str((unsigned char*)digest,digest_text); fprintf(stderr,"MD5 (%s) = %s\n",(md5_mode==2?"'image'":argv[optind]), digest_text); } quit: start_stop(0); /* set_removable(1); */ /* close the scsi device */ scsi_close(); return 0; }
int main(int argc, char **argv) { setlocale(LC_ALL, ""); program_name = argv[0]; opt_block_size = get_block_size(); int c; while ((c = getopt(argc, argv, "b:c:")) != -1) { switch (c) { case 'b': if (!parse_arg_block_size(optarg)) usage(); break; case 'c': if (!parse_arg_compression(optarg)) usage(); break; default: usage(); } } if (argc - optind < 2) usage(); mtbl_output_fname = argv[argc - 1]; /* open user dso */ init_dso(); /* open merger, writer */ init_mtbl(); /* open readers */ const size_t n_readers = argc - 1 - optind; struct mtbl_reader *readers[n_readers]; for (size_t i = 0; i < n_readers; i++) { const char *fname = argv[i + optind]; fprintf(stderr, "%s: opening input file %s\n", program_name, fname); readers[i] = mtbl_reader_init(fname, NULL); if (readers[i] == NULL) { fprintf(stderr, "Error: mtbl_reader_init() failed.\n\n"); usage(); } mtbl_merger_add_source(merger, mtbl_reader_source(readers[i])); } /* do merge */ my_timespec_get(&start_time); merge(); /* cleanup readers */ for (size_t i = 0; i < n_readers; i++) mtbl_reader_destroy(&readers[i]); /* call user cleanup */ if (user_func_free != NULL) user_func_free(user_clos); print_stats(); return (EXIT_SUCCESS); }
/* * cl_update (CUDA version) */ static void update_func_cuda(void *descr[], void *arg) { struct block_description *block = arg; int workerid = starpu_worker_get_id(); DEBUG( "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); if (block->bz == 0) fprintf(stderr,"!!! DO update_func_cuda z %d CUDA%d !!!\n", block->bz, workerid); else DEBUG( "!!! DO update_func_cuda z %d CUDA%d !!!\n", block->bz, workerid); #ifdef STARPU_USE_MPI int rank = 0; MPI_Comm_rank(MPI_COMM_WORLD, &rank); DEBUG( "!!! RANK %d !!!\n", rank); #endif DEBUG( "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); unsigned block_size_z = get_block_size(block->bz); unsigned i; update_per_worker[workerid]++; struct timeval tv, tv2, diff, delta = {.tv_sec = 0, .tv_usec = get_ticks()*1000}; gettimeofday(&tv, NULL); timersub(&tv, &start, &tv2); timersub(&tv2, &last_tick[block->bz], &diff); while (timercmp(&diff, &delta, >=)) { timeradd(&last_tick[block->bz], &delta, &last_tick[block->bz]); timersub(&tv2, &last_tick[block->bz], &diff); if (who_runs_what_index[block->bz] < who_runs_what_len) who_runs_what[block->bz + (who_runs_what_index[block->bz]++) * get_nbz()] = -1; } if (who_runs_what_index[block->bz] < who_runs_what_len) who_runs_what[block->bz + (who_runs_what_index[block->bz]++) * get_nbz()] = global_workerid(workerid); /* * Load neighbours' boundaries : TOP */ /* The offset along the z axis is (block_size_z + K) */ load_subblock_from_buffer_cuda(descr[0], descr[2], block_size_z+K); load_subblock_from_buffer_cuda(descr[1], descr[3], block_size_z+K); /* * Load neighbours' boundaries : BOTTOM */ load_subblock_from_buffer_cuda(descr[0], descr[4], 0); load_subblock_from_buffer_cuda(descr[1], descr[5], 0); /* * Stencils ... do the actual work here :) TODO */ for (i=1; i<=K; i++) { starpu_block_interface_t *oldb = descr[i%2], *newb = descr[(i+1)%2]; TYPE *old = (void*) oldb->ptr, *new = (void*) newb->ptr; /* Shadow data */ cuda_shadow_host(block->bz, old, oldb->nx, oldb->ny, oldb->nz, oldb->ldy, oldb->ldz, i); /* And perform actual computation */ #ifdef LIFE cuda_life_update_host(block->bz, old, new, oldb->nx, oldb->ny, oldb->nz, oldb->ldy, oldb->ldz, i); #else cudaMemcpy(new, old, oldb->nx * oldb->ny * oldb->nz * sizeof(*new), cudaMemcpyDeviceToDevice); #endif /* LIFE */ } cudaError_t cures; if ((cures = cudaThreadSynchronize()) != cudaSuccess) STARPU_CUDA_REPORT_ERROR(cures); } #endif /* STARPU_USE_CUDA */ /* * cl_update (CPU version) */ static void update_func_cpu(void *descr[], void *arg) { struct block_description *block = arg; int workerid = starpu_worker_get_id(); DEBUG( "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); if (block->bz == 0) fprintf(stderr,"!!! DO update_func_cpu z %d CPU%d !!!\n", block->bz, workerid); else DEBUG( "!!! DO update_func_cpu z %d CPU%d !!!\n", block->bz, workerid); #ifdef STARPU_USE_MPI int rank = 0; MPI_Comm_rank(MPI_COMM_WORLD, &rank); DEBUG( "!!! RANK %d !!!\n", rank); #endif DEBUG( "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); unsigned block_size_z = get_block_size(block->bz); unsigned i; update_per_worker[workerid]++; struct timeval tv, tv2, diff, delta = {.tv_sec = 0, .tv_usec = get_ticks() * 1000}; gettimeofday(&tv, NULL); timersub(&tv, &start, &tv2); timersub(&tv2, &last_tick[block->bz], &diff); while (timercmp(&diff, &delta, >=)) { timeradd(&last_tick[block->bz], &delta, &last_tick[block->bz]); timersub(&tv2, &last_tick[block->bz], &diff); if (who_runs_what_index[block->bz] < who_runs_what_len) who_runs_what[block->bz + (who_runs_what_index[block->bz]++) * get_nbz()] = -1; } if (who_runs_what_index[block->bz] < who_runs_what_len) who_runs_what[block->bz + (who_runs_what_index[block->bz]++) * get_nbz()] = global_workerid(workerid); /* * Load neighbours' boundaries : TOP */ /* The offset along the z axis is (block_size_z + K) */ load_subblock_from_buffer_cpu(descr[0], descr[2], block_size_z+K); load_subblock_from_buffer_cpu(descr[1], descr[3], block_size_z+K); /* * Load neighbours' boundaries : BOTTOM */ load_subblock_from_buffer_cpu(descr[0], descr[4], 0); load_subblock_from_buffer_cpu(descr[1], descr[5], 0); /* * Stencils ... do the actual work here :) TODO */ for (i=1; i<=K; i++) { starpu_block_interface_t *oldb = descr[i%2], *newb = descr[(i+1)%2]; TYPE *old = (void*) oldb->ptr, *new = (void*) newb->ptr; /* Shadow data */ unsigned ldy = oldb->ldy, ldz = oldb->ldz; unsigned nx = oldb->nx, ny = oldb->ny, nz = oldb->nz; unsigned x, y, z; unsigned stepx = 1; unsigned stepy = 1; unsigned stepz = 1; unsigned idx = 0; unsigned idy = 0; unsigned idz = 0; TYPE *ptr = old; # include "shadow.h" /* And perform actual computation */ #ifdef LIFE life_update(block->bz, old, new, oldb->nx, oldb->ny, oldb->nz, oldb->ldy, oldb->ldz, i); #else memcpy(new, old, oldb->nx * oldb->ny * oldb->nz * sizeof(*new)); #endif /* LIFE */ } } /* Performance model and codelet structure */ static struct starpu_perfmodel_t cl_update_model = { .type = STARPU_HISTORY_BASED, .symbol = "cl_update" }; starpu_codelet cl_update = { .where = #ifdef STARPU_USE_CUDA STARPU_CUDA| #endif STARPU_CPU, .cpu_func = update_func_cpu, #ifdef STARPU_USE_CUDA .cuda_func = update_func_cuda, #endif .model = &cl_update_model, .nbuffers = 6 }; /* * Save the block internal boundaries to give them to our neighbours. */ /* CPU version */ static void load_subblock_into_buffer_cpu(starpu_block_interface_t *block, starpu_block_interface_t *boundary, unsigned firstz) { /* Sanity checks */ STARPU_ASSERT(block->nx == boundary->nx); STARPU_ASSERT(block->ny == boundary->ny); STARPU_ASSERT(boundary->nz == K); /* NB: this is not fully garanteed ... but it's *very* likely and that * makes our life much simpler */ STARPU_ASSERT(block->ldy == boundary->ldy); STARPU_ASSERT(block->ldz == boundary->ldz); /* We do a contiguous memory transfer */ size_t boundary_size = K*block->ldz*block->elemsize; unsigned offset = firstz*block->ldz; TYPE *block_data = (TYPE *)block->ptr; TYPE *boundary_data = (TYPE *)boundary->ptr; memcpy(boundary_data, &block_data[offset], boundary_size); } /* CUDA version */ #ifdef STARPU_USE_CUDA static void load_subblock_into_buffer_cuda(starpu_block_interface_t *block, starpu_block_interface_t *boundary, unsigned firstz) { /* Sanity checks */ STARPU_ASSERT(block->nx == boundary->nx); STARPU_ASSERT(block->ny == boundary->ny); STARPU_ASSERT(boundary->nz == K); /* NB: this is not fully garanteed ... but it's *very* likely and that * makes our life much simpler */ STARPU_ASSERT(block->ldy == boundary->ldy); STARPU_ASSERT(block->ldz == boundary->ldz); /* We do a contiguous memory transfer */ size_t boundary_size = K*block->ldz*block->elemsize; unsigned offset = firstz*block->ldz; TYPE *block_data = (TYPE *)block->ptr; TYPE *boundary_data = (TYPE *)boundary->ptr; cudaMemcpy(boundary_data, &block_data[offset], boundary_size, cudaMemcpyDeviceToDevice); } #endif /* STARPU_USE_CUDA */ /* Record how many top/bottom saves each worker performed */ unsigned top_per_worker[STARPU_NMAXWORKERS]; unsigned bottom_per_worker[STARPU_NMAXWORKERS]; /* top save, CPU version */ static void dummy_func_top_cpu(void *descr[] __attribute__((unused)), void *arg) { struct block_description *block = arg; int workerid = starpu_worker_get_id(); top_per_worker[workerid]++; DEBUG( "DO SAVE Bottom block %d\n", block->bz); /* The offset along the z axis is (block_size_z + K)- K */ unsigned block_size_z = get_block_size(block->bz); load_subblock_into_buffer_cpu(descr[0], descr[2], block_size_z); load_subblock_into_buffer_cpu(descr[1], descr[3], block_size_z); } /* bottom save, CPU version */ static void dummy_func_bottom_cpu(void *descr[] __attribute__((unused)), void *arg) { struct block_description *block = arg; int workerid = starpu_worker_get_id(); bottom_per_worker[workerid]++; DEBUG( "DO SAVE Top block %d\n", block->bz); load_subblock_into_buffer_cpu(descr[0], descr[2], K); load_subblock_into_buffer_cpu(descr[1], descr[3], K); } /* top save, CUDA version */ #ifdef STARPU_USE_CUDA static void dummy_func_top_cuda(void *descr[] __attribute__((unused)), void *arg) { struct block_description *block = arg; int workerid = starpu_worker_get_id(); top_per_worker[workerid]++; DEBUG( "DO SAVE Top block %d\n", block->bz); /* The offset along the z axis is (block_size_z + K)- K */ unsigned block_size_z = get_block_size(block->bz); load_subblock_into_buffer_cuda(descr[0], descr[2], block_size_z); load_subblock_into_buffer_cuda(descr[1], descr[3], block_size_z); cudaThreadSynchronize(); } /* bottom save, CUDA version */ static void dummy_func_bottom_cuda(void *descr[] __attribute__((unused)), void *arg) { struct block_description *block = arg; int workerid = starpu_worker_get_id(); bottom_per_worker[workerid]++; DEBUG( "DO SAVE Bottom block %d on CUDA\n", block->bz); load_subblock_into_buffer_cuda(descr[0], descr[2], K); load_subblock_into_buffer_cuda(descr[1], descr[3], K); cudaThreadSynchronize(); } #endif /* STARPU_USE_CUDA */ /* Performance models and codelet for save */ static struct starpu_perfmodel_t save_cl_bottom_model = { .type = STARPU_HISTORY_BASED, .symbol = "save_cl_bottom" }; static struct starpu_perfmodel_t save_cl_top_model = { .type = STARPU_HISTORY_BASED, .symbol = "save_cl_top" }; starpu_codelet save_cl_bottom = { .where = #ifdef STARPU_USE_CUDA STARPU_CUDA| #endif STARPU_CPU, .cpu_func = dummy_func_bottom_cpu, #ifdef STARPU_USE_CUDA .cuda_func = dummy_func_bottom_cuda, #endif .model = &save_cl_bottom_model, .nbuffers = 4 }; starpu_codelet save_cl_top = { .where = #ifdef STARPU_USE_CUDA STARPU_CUDA| #endif STARPU_CPU, .cpu_func = dummy_func_top_cpu, #ifdef STARPU_USE_CUDA .cuda_func = dummy_func_top_cuda, #endif .model = &save_cl_top_model, .nbuffers = 4 };
void oskar_dftw( int normalise, int num_in, double wavenumber, const oskar_Mem* weights_in, const oskar_Mem* x_in, const oskar_Mem* y_in, const oskar_Mem* z_in, int offset_coord_out, int num_out, const oskar_Mem* x_out, const oskar_Mem* y_out, const oskar_Mem* z_out, const oskar_Mem* data, int offset_out, oskar_Mem* output, int* status) { if (*status) return; const int location = oskar_mem_location(output); const int type = oskar_mem_precision(output); const int is_dbl = oskar_mem_is_double(output); const int is_3d = (z_in != NULL && z_out != NULL); const int is_data = (data != NULL); const int is_matrix = oskar_mem_is_matrix(output); if (!oskar_mem_is_complex(output) || !oskar_mem_is_complex(weights_in) || oskar_mem_is_matrix(weights_in)) { *status = OSKAR_ERR_BAD_DATA_TYPE; return; } if (oskar_mem_location(weights_in) != location || oskar_mem_location(x_in) != location || oskar_mem_location(y_in) != location || oskar_mem_location(x_out) != location || oskar_mem_location(y_out) != location) { *status = OSKAR_ERR_LOCATION_MISMATCH; return; } if (oskar_mem_precision(weights_in) != type || oskar_mem_type(x_in) != type || oskar_mem_type(y_in) != type || oskar_mem_type(x_out) != type || oskar_mem_type(y_out) != type) { *status = OSKAR_ERR_TYPE_MISMATCH; return; } if (is_data) { if (oskar_mem_location(data) != location) { *status = OSKAR_ERR_LOCATION_MISMATCH; return; } if (!oskar_mem_is_complex(data) || oskar_mem_type(data) != oskar_mem_type(output) || oskar_mem_precision(data) != type) { *status = OSKAR_ERR_TYPE_MISMATCH; return; } } if (is_3d) { if (oskar_mem_location(z_in) != location || oskar_mem_location(z_out) != location) { *status = OSKAR_ERR_LOCATION_MISMATCH; return; } if (oskar_mem_type(z_in) != type || oskar_mem_type(z_out) != type) { *status = OSKAR_ERR_TYPE_MISMATCH; return; } } oskar_mem_ensure(output, (size_t) offset_out + num_out, status); if (*status) return; if (location == OSKAR_CPU) { if (is_data) { if (is_matrix) { if (is_3d) { if (is_dbl) dftw_m2m_3d_double(num_in, wavenumber, oskar_mem_double2_const(weights_in, status), oskar_mem_double_const(x_in, status), oskar_mem_double_const(y_in, status), oskar_mem_double_const(z_in, status), offset_coord_out, num_out, oskar_mem_double_const(x_out, status), oskar_mem_double_const(y_out, status), oskar_mem_double_const(z_out, status), oskar_mem_double4c_const(data, status), offset_out, oskar_mem_double4c(output, status), 0); else dftw_m2m_3d_float(num_in, (float)wavenumber, oskar_mem_float2_const(weights_in, status), oskar_mem_float_const(x_in, status), oskar_mem_float_const(y_in, status), oskar_mem_float_const(z_in, status), offset_coord_out, num_out, oskar_mem_float_const(x_out, status), oskar_mem_float_const(y_out, status), oskar_mem_float_const(z_out, status), oskar_mem_float4c_const(data, status), offset_out, oskar_mem_float4c(output, status), 0); } else { if (is_dbl) dftw_m2m_2d_double(num_in, wavenumber, oskar_mem_double2_const(weights_in, status), oskar_mem_double_const(x_in, status), oskar_mem_double_const(y_in, status), 0, offset_coord_out, num_out, oskar_mem_double_const(x_out, status), oskar_mem_double_const(y_out, status), 0, oskar_mem_double4c_const(data, status), offset_out, oskar_mem_double4c(output, status), 0); else dftw_m2m_2d_float(num_in, (float)wavenumber, oskar_mem_float2_const(weights_in, status), oskar_mem_float_const(x_in, status), oskar_mem_float_const(y_in, status), 0, offset_coord_out, num_out, oskar_mem_float_const(x_out, status), oskar_mem_float_const(y_out, status), 0, oskar_mem_float4c_const(data, status), offset_out, oskar_mem_float4c(output, status), 0); } } else { if (is_3d) { if (is_dbl) dftw_c2c_3d_double(num_in, wavenumber, oskar_mem_double2_const(weights_in, status), oskar_mem_double_const(x_in, status), oskar_mem_double_const(y_in, status), oskar_mem_double_const(z_in, status), offset_coord_out, num_out, oskar_mem_double_const(x_out, status), oskar_mem_double_const(y_out, status), oskar_mem_double_const(z_out, status), oskar_mem_double2_const(data, status), offset_out, oskar_mem_double2(output, status), 0); else dftw_c2c_3d_float(num_in, (float)wavenumber, oskar_mem_float2_const(weights_in, status), oskar_mem_float_const(x_in, status), oskar_mem_float_const(y_in, status), oskar_mem_float_const(z_in, status), offset_coord_out, num_out, oskar_mem_float_const(x_out, status), oskar_mem_float_const(y_out, status), oskar_mem_float_const(z_out, status), oskar_mem_float2_const(data, status), offset_out, oskar_mem_float2(output, status), 0); } else { if (is_dbl) dftw_c2c_2d_double(num_in, wavenumber, oskar_mem_double2_const(weights_in, status), oskar_mem_double_const(x_in, status), oskar_mem_double_const(y_in, status), 0, offset_coord_out, num_out, oskar_mem_double_const(x_out, status), oskar_mem_double_const(y_out, status), 0, oskar_mem_double2_const(data, status), offset_out, oskar_mem_double2(output, status), 0); else dftw_c2c_2d_float(num_in, (float)wavenumber, oskar_mem_float2_const(weights_in, status), oskar_mem_float_const(x_in, status), oskar_mem_float_const(y_in, status), 0, offset_coord_out, num_out, oskar_mem_float_const(x_out, status), oskar_mem_float_const(y_out, status), 0, oskar_mem_float2_const(data, status), offset_out, oskar_mem_float2(output, status), 0); } } } else { if (is_3d) { if (is_dbl) dftw_o2c_3d_double(num_in, wavenumber, oskar_mem_double2_const(weights_in, status), oskar_mem_double_const(x_in, status), oskar_mem_double_const(y_in, status), oskar_mem_double_const(z_in, status), offset_coord_out, num_out, oskar_mem_double_const(x_out, status), oskar_mem_double_const(y_out, status), oskar_mem_double_const(z_out, status), 0, offset_out, oskar_mem_double2(output, status), 0); else dftw_o2c_3d_float(num_in, (float)wavenumber, oskar_mem_float2_const(weights_in, status), oskar_mem_float_const(x_in, status), oskar_mem_float_const(y_in, status), oskar_mem_float_const(z_in, status), offset_coord_out, num_out, oskar_mem_float_const(x_out, status), oskar_mem_float_const(y_out, status), oskar_mem_float_const(z_out, status), 0, offset_out, oskar_mem_float2(output, status), 0); } else { if (is_dbl) dftw_o2c_2d_double(num_in, wavenumber, oskar_mem_double2_const(weights_in, status), oskar_mem_double_const(x_in, status), oskar_mem_double_const(y_in, status), 0, offset_coord_out, num_out, oskar_mem_double_const(x_out, status), oskar_mem_double_const(y_out, status), 0, 0, offset_out, oskar_mem_double2(output, status), 0); else dftw_o2c_2d_float(num_in, (float)wavenumber, oskar_mem_float2_const(weights_in, status), oskar_mem_float_const(x_in, status), oskar_mem_float_const(y_in, status), 0, offset_coord_out, num_out, oskar_mem_float_const(x_out, status), oskar_mem_float_const(y_out, status), 0, 0, offset_out, oskar_mem_float2(output, status), 0); } } } else { size_t local_size[] = {256, 1, 1}, global_size[] = {1, 1, 1}; const void* np = 0; const char* k = 0; int max_in_chunk; float wavenumber_f = (float) wavenumber; /* Select the kernel. */ switch (is_dbl * DBL | is_3d * D3 | is_data * DAT | is_matrix * MAT) { case D2 | FLT: k = "dftw_o2c_2d_float"; break; case D2 | DBL: k = "dftw_o2c_2d_double"; break; case D3 | FLT: k = "dftw_o2c_3d_float"; break; case D3 | DBL: k = "dftw_o2c_3d_double"; break; case D2 | FLT | DAT: k = "dftw_c2c_2d_float"; break; case D2 | DBL | DAT: k = "dftw_c2c_2d_double"; break; case D3 | FLT | DAT: k = "dftw_c2c_3d_float"; break; case D3 | DBL | DAT: k = "dftw_c2c_3d_double"; break; case D2 | FLT | DAT | MAT: k = "dftw_m2m_2d_float"; break; case D2 | DBL | DAT | MAT: k = "dftw_m2m_2d_double"; break; case D3 | FLT | DAT | MAT: k = "dftw_m2m_3d_float"; break; case D3 | DBL | DAT | MAT: k = "dftw_m2m_3d_double"; break; default: *status = OSKAR_ERR_FUNCTION_NOT_AVAILABLE; return; } if (oskar_device_is_nv(location)) local_size[0] = (size_t) get_block_size(num_out); oskar_device_check_local_size(location, 0, local_size); global_size[0] = oskar_device_global_size( (size_t) num_out, local_size[0]); /* max_in_chunk must be multiple of 16. */ max_in_chunk = is_3d ? (is_dbl ? 384 : 800) : (is_dbl ? 448 : 896); if (is_data && is_3d && !is_dbl) max_in_chunk = 768; const size_t element_size = is_dbl ? sizeof(double) : sizeof(float); const size_t local_mem_size = max_in_chunk * element_size; const size_t arg_size_local[] = { 2 * local_mem_size, 2 * local_mem_size, (is_3d ? local_mem_size : 0) }; /* Set kernel arguments. */ const oskar_Arg args[] = { {INT_SZ, &num_in}, {is_dbl ? DBL_SZ : FLT_SZ, is_dbl ? (void*)&wavenumber : (void*)&wavenumber_f}, {PTR_SZ, oskar_mem_buffer_const(weights_in)}, {PTR_SZ, oskar_mem_buffer_const(x_in)}, {PTR_SZ, oskar_mem_buffer_const(y_in)}, {PTR_SZ, is_3d ? oskar_mem_buffer_const(z_in) : &np}, {INT_SZ, &offset_coord_out}, {INT_SZ, &num_out}, {PTR_SZ, oskar_mem_buffer_const(x_out)}, {PTR_SZ, oskar_mem_buffer_const(y_out)}, {PTR_SZ, is_3d ? oskar_mem_buffer_const(z_out) : &np}, {PTR_SZ, is_data ? oskar_mem_buffer_const(data) : &np}, {INT_SZ, &offset_out}, {PTR_SZ, oskar_mem_buffer(output)}, {INT_SZ, &max_in_chunk} }; oskar_device_launch_kernel(k, location, 1, local_size, global_size, sizeof(args) / sizeof(oskar_Arg), args, sizeof(arg_size_local) / sizeof(size_t), arg_size_local, status); } if (normalise) oskar_mem_scale_real(output, 1. / num_in, offset_out, num_out, status); }
/*===========================================================================* * fs_readwrite * *===========================================================================*/ PUBLIC int fs_readwrite(void) { int r, rw_flag, block_spec; int regular; cp_grant_id_t gid; off_t position, f_size, bytes_left; unsigned int off, cum_io, block_size, chunk; mode_t mode_word; int completed; struct inode *rip; size_t nrbytes; r = OK; /* Find the inode referred */ if ((rip = find_inode(fs_dev, (ino_t) fs_m_in.REQ_INODE_NR)) == NULL) return(EINVAL); mode_word = rip->i_mode & I_TYPE; regular = (mode_word == I_REGULAR || mode_word == I_NAMED_PIPE); block_spec = (mode_word == I_BLOCK_SPECIAL ? 1 : 0); /* Determine blocksize */ if (block_spec) { block_size = get_block_size( (dev_t) rip->i_zone[0]); f_size = MAX_FILE_POS; } else { block_size = rip->i_sp->s_block_size; f_size = rip->i_size; } /* Get the values from the request message */ rw_flag = (fs_m_in.m_type == REQ_READ ? READING : WRITING); gid = (cp_grant_id_t) fs_m_in.REQ_GRANT; position = (off_t) fs_m_in.REQ_SEEK_POS_LO; nrbytes = (size_t) fs_m_in.REQ_NBYTES; rdwt_err = OK; /* set to EIO if disk error occurs */ /* If this is file i/o, check we can write */ if (rw_flag == WRITING && !block_spec) { if(rip->i_sp->s_rd_only) return EROFS; /* Check in advance to see if file will grow too big. */ if (position > (off_t) (rip->i_sp->s_max_size - nrbytes)) return(EFBIG); /* Clear the zone containing present EOF if hole about * to be created. This is necessary because all unwritten * blocks prior to the EOF must read as zeros. */ if(position > f_size) clear_zone(rip, f_size, 0); } /* If this is block i/o, check we can write */ if(block_spec && rw_flag == WRITING && (dev_t) rip->i_zone[0] == superblock.s_dev && superblock.s_rd_only) return EROFS; cum_io = 0; /* Split the transfer into chunks that don't span two blocks. */ while (nrbytes > 0) { off = ((unsigned int) position) % block_size; /* offset in blk*/ chunk = min(nrbytes, block_size - off); if (rw_flag == READING) { bytes_left = f_size - position; if (position >= f_size) break; /* we are beyond EOF */ if (chunk > (unsigned int) bytes_left) chunk = bytes_left; } /* Read or write 'chunk' bytes. */ r = rw_chunk(rip, cvul64((unsigned long) position), off, chunk, nrbytes, rw_flag, gid, cum_io, block_size, &completed); if (r != OK) break; /* EOF reached */ if (rdwt_err < 0) break; /* Update counters and pointers. */ nrbytes -= chunk; /* bytes yet to be read */ cum_io += chunk; /* bytes read so far */ position += (off_t) chunk; /* position within the file */ } fs_m_out.RES_SEEK_POS_LO = position; /* It might change later and the VFS has to know this value */ /* On write, update file size and access time. */ if (rw_flag == WRITING) { if (regular || mode_word == I_DIRECTORY) { if (position > f_size) rip->i_size = position; } } rip->i_seek = NO_SEEK; if (rdwt_err != OK) r = rdwt_err; /* check for disk error */ if (rdwt_err == END_OF_FILE) r = OK; /* even on a ROFS, writing to a device node on it is fine, * just don't update the inode stats for it. And dito for reading. */ if (r == OK && !rip->i_sp->s_rd_only) { if (rw_flag == READING) rip->i_update |= ATIME; if (rw_flag == WRITING) rip->i_update |= CTIME | MTIME; IN_MARKDIRTY(rip); /* inode is thus now dirty */ } fs_m_out.RES_NBYTES = cum_io; return(r); }
void nbody_engine_cuda_bh_tex::fcompute(const nbcoord_t& t, const memory* _y, memory* _f) { Q_UNUSED(t); const smemory* y = dynamic_cast<const smemory*>(_y); smemory* f = dynamic_cast<smemory*>(_f); if(y == NULL) { qDebug() << "y is not smemory"; return; } if(f == NULL) { qDebug() << "f is not smemory"; return; } advise_compute_count(); size_t count = m_data->get_count(); std::vector<nbcoord_t> host_y(y->size() / sizeof(nbcoord_t)); std::vector<nbcoord_t> host_mass(count); read_buffer(host_y.data(), y); read_buffer(host_mass.data(), m_mass); const nbcoord_t* rx = host_y.data(); const nbcoord_t* ry = rx + count; const nbcoord_t* rz = rx + 2 * count; const nbcoord_t* mass = host_mass.data(); nbody_space_heap heap; heap.build(count, rx, ry, rz, mass, m_distance_to_node_radius_ratio); size_t tree_size = heap.get_radius_sqr().size(); if(m_dev_indites == NULL) { m_dev_tree_xyzr = dynamic_cast<smemory*>(create_buffer(tree_size * sizeof(nbcoord_t) * 4)); m_dev_tree_mass = dynamic_cast<smemory*>(create_buffer(tree_size * sizeof(nbcoord_t))); m_dev_indites = dynamic_cast<smemory*>(create_buffer(tree_size * sizeof(int))); } const nbcoord_t* dev_y = static_cast<const nbcoord_t*>(y->data()); nbcoord_t* dev_f = static_cast<nbcoord_t*>(f->data()); int* dev_indites = static_cast<int*>(m_dev_indites->data()); static_assert(sizeof(vertex4<nbcoord_t>) == sizeof(nbcoord_t) * 4, "sizeof(vertex4) must be equal to sizeof(nbcoord_t)*4"); std::vector<vertex4<nbcoord_t>> host_tree_xyzr(tree_size); std::vector<int> host_indites(tree_size); #pragma omp parallel for for(size_t n = 0; n < tree_size; ++n) { host_tree_xyzr[n].x = heap.get_mass_center()[n].x; host_tree_xyzr[n].y = heap.get_mass_center()[n].y; host_tree_xyzr[n].z = heap.get_mass_center()[n].z; host_tree_xyzr[n].w = heap.get_radius_sqr()[n]; host_indites[n] = static_cast<int>(heap.get_body_n()[n]); } write_buffer(m_dev_tree_xyzr, host_tree_xyzr.data()); write_buffer(m_dev_tree_mass, heap.get_mass().data()); write_buffer(m_dev_indites, host_indites.data()); if(m_tree_layout == etl_heap) { fcompute_heap_bh_tex(0, static_cast<int>(count), static_cast<int>(tree_size), dev_f, m_dev_tree_xyzr->tex(4), m_dev_tree_mass->tex(), dev_indites, get_block_size()); } else if(m_tree_layout == etl_heap_stackless) { fcompute_heap_bh_stackless(0, static_cast<int>(count), static_cast<int>(tree_size), dev_f, m_dev_tree_xyzr->tex(4), m_dev_tree_mass->tex(), dev_indites, get_block_size()); } fcompute_xyz(dev_y, dev_f, static_cast<int>(count), get_block_size()); }
/*===========================================================================* * fs_readwrite * *===========================================================================*/ PUBLIC int fs_readwrite(void) { int r, rw_flag, block_spec; int regular; cp_grant_id_t gid; off_t position, f_size, bytes_left; unsigned int off, cum_io, block_size, chunk; mode_t mode_word; int completed; struct inode *rip; size_t nrbytes; r = OK; /* Find the inode referred */ if ((rip = find_inode(fs_dev, (ino_t) fs_m_in.REQ_INODE_NR)) == NULL) return(EINVAL); mode_word = rip->i_mode & I_TYPE; /* immediate files are regular files too! */ regular = (mode_word == I_REGULAR || mode_word == I_IMMEDIATE || mode_word == I_NAMED_PIPE); block_spec = (mode_word == I_BLOCK_SPECIAL ? 1 : 0); /* Determine blocksize */ if (block_spec) { block_size = get_block_size( (dev_t) rip->i_zone[0]); f_size = MAX_FILE_POS; } else { block_size = rip->i_sp->s_block_size; f_size = rip->i_size; } /* Get the values from the request message */ rw_flag = (fs_m_in.m_type == REQ_READ ? READING : WRITING); gid = (cp_grant_id_t) fs_m_in.REQ_GRANT; position = (off_t) fs_m_in.REQ_SEEK_POS_LO; nrbytes = (size_t) fs_m_in.REQ_NBYTES; rdwt_err = OK; /* set to EIO if disk error occurs */ if (rw_flag == WRITING && !block_spec && (rip->i_mode & I_TYPE) != I_IMMEDIATE) { /* Check in advance to see if file will grow too big. */ if (position > (off_t) (rip->i_sp->s_max_size - nrbytes)) return(EFBIG); /* Clear the zone containing present EOF if hole about * to be created. This is necessary because all unwritten * blocks prior to the EOF must read as zeros. */ if(position > f_size) clear_zone(rip, f_size, 0); } cum_io = 0; if((rip->i_mode & I_TYPE) == I_IMMEDIATE) { int sanity = 0; if(f_size > 40) printf("Immediate file is %d bytes!\n", f_size); if(rw_flag == WRITING) { /* printf("fs_readwrite() WRITING to immediate file\n"); */ /* is the file going to need to be upconverted from immediate to regular? */ if((f_size + nrbytes) > 40 || position > 40) { char tmp[40]; register int i; register struct buf *bp; for(i = 0; i < f_size; i++) { tmp[i] = *(((char *)rip->i_zone) + i); } /* clear inode since it will now hold pointers rather than data (copied from wipe_inode()) */ rip->i_size = 0; rip->i_update = ATIME | CTIME | MTIME; /* update all times later */ rip->i_dirt = DIRTY; for (i = 0; i < V2_NR_TZONES; i++) rip->i_zone[i] = NO_ZONE; /* Writing to a nonexistent block. Create and enter in inode.*/ if ((bp = new_block(rip, (off_t) 0)) == NULL) panic("bp not valid in fs_readwrite immediate growth; this can't be happening!"); /* copy data to bp->data */ for(i = 0; i < f_size; i++) { bp->b_data[i] = tmp[i]; } bp->b_dirt = DIRTY; put_block(bp, PARTIAL_DATA_BLOCK); position += f_size; f_size = rip->i_size; rip->i_mode = (I_REGULAR | (rip->i_mode & ALL_MODES)); } /* the file will not grow over 40 bytes */ else { sanity = 1; } } else { /* printf("fs_readwrite() READING from immediate file\n"); */ bytes_left = f_size - position; /* if the position is past the end of the file, it is already too late... */ if(bytes_left > 0) { sanity = 1; /* don't read past the EOF, just right up to it */ if(nrbytes > bytes_left) nrbytes = bytes_left; } } if(sanity) { r = rw_immed(rip, position, nrbytes, rw_flag, gid, cum_io); if(r == OK) { cum_io += nrbytes; position += nrbytes; /* no more bytes left to read */ nrbytes = 0; } } } /* Split the transfer into chunks that don't span two blocks. */ while (nrbytes > 0) { off = ((unsigned int) position) % block_size; /* offset in blk*/ chunk = min(nrbytes, block_size - off); if (rw_flag == READING) { bytes_left = f_size - position; if (position >= f_size) break; /* we are beyond EOF */ if (chunk > (unsigned int) bytes_left) chunk = bytes_left; } /* Read or write 'chunk' bytes. */ r = rw_chunk(rip, cvul64((unsigned long) position), off, chunk, nrbytes, rw_flag, gid, cum_io, block_size, &completed); if (r != OK) break; /* EOF reached */ if (rdwt_err < 0) break; /* Update counters and pointers. */ nrbytes -= chunk; /* bytes yet to be read */ cum_io += chunk; /* bytes read so far */ position += (off_t) chunk; /* position within the file */ } fs_m_out.RES_SEEK_POS_LO = position; /* It might change later and the VFS has to know this value */ /* On write, update file size and access time. */ if (rw_flag == WRITING) { if (regular || mode_word == I_DIRECTORY) { if (position > f_size) rip->i_size = position; } } /* Check to see if read-ahead is called for, and if so, set it up. */ if(rw_flag == READING && rip->i_seek == NO_SEEK && (unsigned int) position % block_size == 0 && (regular || mode_word == I_DIRECTORY)) { rdahed_inode = rip; rdahedpos = position; } rip->i_seek = NO_SEEK; if (rdwt_err != OK) r = rdwt_err; /* check for disk error */ if (rdwt_err == END_OF_FILE) r = OK; if (r == OK) { if (rw_flag == READING) rip->i_update |= ATIME; if (rw_flag == WRITING) rip->i_update |= CTIME | MTIME; rip->i_dirt = DIRTY; /* inode is thus now dirty */ } fs_m_out.RES_NBYTES = cum_io; return(r); }
char disk_io_read(test_results_t* result, int iters, cmd_line_args * cmd_args, benchmark_test* bmtest, result_table_t* res_table) { FILE *read_fp = NULL; long long time_diff; int block_size = 0; int done, loop, j; double clock_accuracy; char retry_status = UNACCEPTABLE_DEVIATIONS; int sub_iters = DEFAULT_SUBITERS; int count = 0; char *_read_buf = NULL; char print_flag = FALSE; struct timespec start_time, end_time; block_size = get_block_size(); assert(block_size> 0); clock_accuracy = get_min_exec_time(res_table); RTMB_verbose_printf(stdout, cmd_args, 1, "\nTest Report for disk I/O read configuration:\n"); RTMB_verbose_printf(stdout, cmd_args, 1, "=================================================\n"); RTMB_verbose_printf(stdout, cmd_args, 1, "\ndisk_io_config: Total number of iterations = %d\n\n", iters); done = 0; while (!done) { int n; _read_buf = calloc(1, block_size); if (_read_buf == NULL) { RTMB_printf(stderr, "calloc() failed in disk_io_read_config()\n"); abort(); } /*Make sure there is data in the file before attempting a read*/ setup_file_for_read(block_size * sub_iters, 1); for (loop = 0; loop < iters; loop++) { open_file_for_read(&read_fp); if (get_cur_time(&start_time) == ERROR) { abort(); } for (j = 0; j < sub_iters; j++) { if ((n = fread(_read_buf, sizeof(char), block_size, read_fp)) != block_size) { perror("fwrite:"); abort(); } } if (get_cur_time(&end_time) == ERROR) { abort(); } /* Get the time difference of start and end times */ time_diff = get_time_diff(start_time, end_time); RTMB_verbose_printf(stdout, cmd_args, 2, "disk_io_read_config: Difference between end" " and start times = %.3f us\n", MICROSEC(time_diff)); add_entry(result, time_diff, 0); fclose(read_fp); } if (IS_EXEC_TIME_GRT_THAN_CLK(result, clock_accuracy)) { print_flag = TRUE; if (check_pass_criteria(result, cmd_args, bmtest, 0) == SUCCESS) { /* * test passed, * disk IO rate is determined */ retry_status = ACCEPTABLE_DEVIATIONS; done = 1; break; } else { /*If we have completed, return error*/ if (++count == bmtest->_threshold) { RTMB_printf(stderr, "disk_io_read_config: exceeded" " maximum attempts \n"); break; } } } if (print_flag == TRUE) { RTMB_verbose_printf(stdout, cmd_args, 1, "\ndisk_io_read_config: Retrying test"); RTMB_verbose_printf(stdout, cmd_args, 1, " with bigger work quantum to get" " lesser variance...\n"); } /* * measured times are not accurate enough, * hence retry. */ free_chain(result, 0); sub_iters *= MULTIPLIER_FOR_SUB_ITER; free(_read_buf); } result->opern_amount = block_size * sub_iters; return retry_status; }
// Return a pointer to a block given its number. // get_block(fs, 0) == fs; void * get_block(void * fs, __u32 block_num) { return (void*) (char*)fs + block_num*get_block_size(fs); }
int main(int argc, char **argv) { int nvram_fd, cache_fd, disk_fd, c;//新增 nvram_fd char *disk_devname, *flash_devname, *nvram_devname, *cachedev;//新增 nvram_devname表示nvram缓存路径名字 struct flash_superblock *sb = (struct flash_superblock *)buf;//flash超级块的对象sb指向buf空间 struct flash_superblock *nsb = (struct flash_superblock *)nvram_buf;//新增 nb结构体 sector_t nvram_devsize, cache_devsize, disk_devsize;//新增 nvram_cache_devsize sector_t block_size = 0, md_block_size = 0, cache_size = 0, nvram_size = 0;//新增 nvram_size sector_t ram_needed;//typedef unsigned long sector_t; struct sysinfo i; int cache_sectorsize, nvram_sectorsize;//新增 nvram的扇区大小 int associativity = 512; int disk_associativity = 512; int ret; int cache_mode = -1; char *cache_mode_str; pname = argv[0]; //flashcache_create -p back flashcache /dev/pma /dev/pmb /dev/loop0 //flashcache_create [-v] -p back|around|thru [-s cache size] [-b block size] cachedevname flash_devname disk_devname while ((c = getopt(argc, argv, "fs:b:d:m:va:p:")) != -1) { switch (c) { case 's': //这个位置以后还可以初始化nvram_size属性 cache_size = get_cache_size(optarg);//s选项后面跟着的是缓存大小 默认大小,不然就要分别指定两个缓存的大小 break; case 'a': associativity = atoi(optarg);//缓存分组大小 break; case 'b': block_size = get_block_size(optarg);//缓存块大小 2的n次幂 /* Block size should be a power of 2 */ break; case 'd': disk_associativity = get_block_size(optarg);//磁盘分组大小 break; case 'm': md_block_size = get_block_size(optarg);//元数据块大小 /* MD block size should be a power of 2 */ break; case 'v': verbose = 1; break; case 'f': force = 1; break; case 'p': if (strcmp(optarg, "back") == 0) { //默认设置成WB模式 cache_mode = FLASHCACHE_WRITE_BACK; cache_mode_str = "WRITE_BACK"; } else if ((strcmp(optarg, "thru") == 0) || (strcmp(optarg, "through") == 0)) { cache_mode = FLASHCACHE_WRITE_THROUGH; cache_mode_str = "WRITE_THROUGH"; } else if (strcmp(optarg, "around") == 0) { cache_mode = FLASHCACHE_WRITE_AROUND; cache_mode_str = "WRITE_AROUND"; } else usage(pname); break; case '?': usage(pname); } } if (cache_mode == -1) usage(pname); if (optind == argc) usage(pname); if (block_size == 0) block_size = 8; /* 4KB default blocksize */ //缓存块大小默认为8个扇区,4KB if (md_block_size == 0) md_block_size = 8; /* 4KB default blocksize */ //元数据块大小也是一样 //进一步分别获取虚拟设备、flash设备和磁盘设备的名字 如果说参数个数提前用完了optind==argc,则调用usage返回错误信息 cachedev = argv[optind++]; if (optind == argc) usage(pname); //新增 获取nvram的设备路径名 nvram_devname = argv[optind++]; if (optind == argc) usage(pname); flash_devname = argv[optind++]; if (optind == argc) usage(pname); disk_devname = argv[optind]; //新增 对nvram路径名/磁盘分组大小的输出 //printf("cachedev %s, nvram_devname %s, flash_devname %s, disk_devname %s cache_mode %s disk_associativity %lu\n", // cachedev, nvram_devname, flash_devname, disk_devname, cache_mode_str, disk_associativity); if (cache_mode == FLASHCACHE_WRITE_BACK) printf("FLASHCACHE_WRITE_BACK:block_size %lu, md_block_size %lu, cache_size %lu\n", block_size, md_block_size, cache_size); else printf("block_size %lu, cache_size %lu\n", block_size, cache_size); //新增 读取nvram缓存空间的超级块中的数据,并判断nvram中是否已经有数据 nvram_fd = open(nvram_devname, O_RDONLY); if (nvram_fd < 0) { fprintf(stderr, "Failed to open %s\n", nvram_devname); exit(1); } lseek(nvram_fd, 0, SEEK_SET); if (read(nvram_fd, nvram_buf, 512) < 0) { fprintf(stderr, "Cannot read NVRAM superblock %s\n", nvram_devname); exit(1); } if (nsb->cache_sb_state == CACHE_MD_STATE_DIRTY || nsb->cache_sb_state == CACHE_MD_STATE_CLEAN || nsb->cache_sb_state == CACHE_MD_STATE_FASTCLEAN || nsb->cache_sb_state == CACHE_MD_STATE_UNSTABLE) { fprintf(stderr, "%s: Valid Flashcache already exists on %s\n", pname, nvram_devname); fprintf(stderr, "%s: Use flashcache_destroy first and then create again %s\n", pname, nvram_devname); exit(1); } //读取flash缓存空间的超级块中的数据 //指向文件的头部,并从头部开始读取512个字节的数据到buf中 那就应该是超级块只占用一个扇区大小? cache_fd = open(flash_devname, O_RDONLY); if (cache_fd < 0) { fprintf(stderr, "Failed to open %s\n", flash_devname); exit(1); } lseek(cache_fd, 0, SEEK_SET); if (read(cache_fd, buf, 512) < 0) { fprintf(stderr, "Cannot read Flash superblock %s\n", flash_devname); exit(1); } //通过flash缓存超级块的clean或者shutdown状态来判断是否已经有缓存数据在flash中 if (sb->cache_sb_state == CACHE_MD_STATE_DIRTY || sb->cache_sb_state == CACHE_MD_STATE_CLEAN || sb->cache_sb_state == CACHE_MD_STATE_FASTCLEAN || sb->cache_sb_state == CACHE_MD_STATE_UNSTABLE) { fprintf(stderr, "%s: Valid Flashcache already exists on %s\n", pname, flash_devname); fprintf(stderr, "%s: Use flashcache_destroy first and then create again %s\n", pname, flash_devname); exit(1); } // disk_fd = open(disk_devname, O_RDONLY); if (disk_fd < 0) { fprintf(stderr, "%s: Failed to open %s\n", pname, disk_devname); exit(1); } //新增 获取nvram设备空间大小BLKGETSIZE和物理扇区大小BLKSSZGET //并判断nvram缓存数据块大小是否大于nvram物理扇区大小和nvram缓存空间大小是否小于nvram设备大小 //不过默认cache_size应该为0,所以nvram_size也默认为0 if (ioctl(nvram_fd, BLKGETSIZE, &nvram_devsize) < 0) { fprintf(stderr, "%s: Cannot get nvram size %s\n", pname, nvram_devname); exit(1); } if (ioctl(nvram_fd, BLKSSZGET, &nvram_sectorsize) < 0) { fprintf(stderr, "%s: Cannot get nvram size %s\n", pname, nvram_devname); exit(1); } if (md_block_size > 0 && md_block_size * 512 < nvram_sectorsize) { fprintf(stderr, "%s: NVRAM device (%s) sector size (%d) cannot be larger than metadata block size (%d) !\n", pname, nvram_devname, nvram_sectorsize, md_block_size * 512); exit(1); } if (nvram_size && nvram_size > nvram_devsize) { fprintf(stderr, "%s: Cache size is larger than nvram size %lu/%lu\n", pname, nvram_size, nvram_devsize); exit(1); } //获取flash设备的空间大小并写入到cache_devsize中 if (ioctl(cache_fd, BLKGETSIZE, &cache_devsize) < 0) { fprintf(stderr, "%s: Cannot get cache size %s\n", pname, flash_devname); exit(1); } if (ioctl(disk_fd, BLKGETSIZE, &disk_devsize) < 0) { fprintf(stderr, "%s: Cannot get disk size %s\n", pname, disk_devname); exit(1); } //获取flash设备的物理扇区大小 if (ioctl(cache_fd, BLKSSZGET, &cache_sectorsize) < 0) { fprintf(stderr, "%s: Cannot get cache size %s\n", pname, flash_devname); exit(1); } //flash设备的物理扇区大小不能大于元数据块的大小 不然元数据块就成了管理flash的最小数据单元了 if (md_block_size > 0 && md_block_size * 512 < cache_sectorsize) { fprintf(stderr, "%s: SSD device (%s) sector size (%d) cannot be larger than metadata block size (%d) !\n", pname, flash_devname, cache_sectorsize, md_block_size * 512); exit(1); } //缓存空间大小不能大于flash设备空间大小 if (cache_size && cache_size > cache_devsize) { fprintf(stderr, "%s: Cache size is larger than ssd size %lu/%lu\n", pname, cache_size, cache_devsize); exit(1); } //新增 输出已获取到的设备信息 printf("flash:%s缓存大小为%d,设备大小为%d nvram:%s缓存大小为%d,设备大小为%d disk:%s设备大小为%d\n", flash_devname, cache_size, cache_devsize, nvram_devname, nvram_size, nvram_devsize, disk_devname, disk_devsize); /* Remind users how much core memory it will take - not always insignificant. * If it's > 25% of RAM, warn. */ //如果缓存空间大小没有在参数中赋值,为0,则为设备大小/块大小 *缓存块大小,即整个设备 //新增 nvram_size为0,ram_needed加上nvram设备大小 if (cache_size == 0 || nvram_size == 0) ram_needed = (cache_devsize / block_size) * sizeof(struct cacheblock) + (nvram_devsize / block_size) * sizeof(struct cacheblock); /* Whole device */ else ram_needed = (cache_size / block_size) * sizeof(struct cacheblock) + (nvram_size / block_size) * sizeof(struct cacheblock); sysinfo(&i); printf("Flashcache metadata will use %luMB of your %luMB main memory\n", ram_needed >> 20, i.totalram >> 20); //若是所使用的Flashcache元数据空间占内存空间比例超过1/4则提示 ram_needed不是整个缓存空间的大小吗?为什么说元数据? if (!force && ram_needed > (i.totalram * 25 / 100)) { fprintf(stderr, "Proportion of main memory needed for flashcache metadata is high.\n"); fprintf(stderr, "You can reduce this with a smaller cache or a larger blocksize.\n"); check_sure(); } //printf("输出一次disk_associativity=%lu associativity=%lu\n", disk_associativity, associativity); //磁盘分组大小不能大于缓存分组大小 if (disk_associativity == 0 || disk_associativity > associativity) { fprintf(stderr, "%s: Invalid Disk Associativity %ld\n", pname, disk_associativity); exit(1); } //printf("再输出一次disk_associativity=%lu associativity=%lu\n", disk_associativity, associativity); //缓存大小也不能大于磁盘大小 //新增 加入nvram_size > disk_devsize if (!force && (cache_size > disk_devsize || nvram_size > disk_devsize)) { fprintf(stderr, "Size of cache volume (%s) || (%s) is larger than disk volume (%s)\n", nvram_devname, flash_devname, disk_devname); check_sure(); } //新增 先提前输出一遍命令内容 共享cache_mode、block_size、assoc、md_block_size persistence默认为2,即create printf("echo 0 %lu flashcache disk=%s ssd=%s nvram=%s cachedev=%s cachemode=%d 2 blocksize=%lu cachesize=%lu nvramsize=%lu assoc=%d diskassoc=%d md_block_size=%lu" " | dmsetup create %s.\n", disk_devsize, disk_devname, flash_devname, nvram_devname, cachedev, cache_mode, block_size, cache_size, nvram_size, associativity, disk_associativity, md_block_size, cachedev); /* [root@localhost flashcache-3.1.3]# flashcache_create -p back cache1g8g /dev/pma /dev/pmb /dev/loop0 cachedev cache1g8g, nvram_devname /dev/pma, flash_devname /dev/pmb, disk_devname /dev/loop0 cache mode WRITE_BACK block_size 8, md_block_size 8, cache_size 0 Flashcache metadata will use 58MB of your 64426MB main memory echo 0 20971520 flashcache /dev/loop0 /dev/pmb /dev/pma cache1g8g 1 2 8 0 0 512 266287972864 8 | dmsetup create cache1g8g echo 0 20971520 flashcache /dev/loop0 /dev/pmb cachehaha 1 2 8 0 512 140733193388544 8 | dmsetup create cachehaha */ /* umount /dev/mapper/cachecache dmsetup remove cachecache rmmod flashcache flashcache_destroy /dev/pmb make && make install modprobe pmbd mode="pmbd1,8;hmo50;hms9;pmapY;rdsx1,2;wrsx1,12;" fdisk -l losetup /dev/loop0 /home/disk.img dd if=/dev/zero of=/root/workspace/disk.img bs=1024k count=131072 make KERNEL_TREE=/usr/src/kernels/2.6.32-504.12.2.el6.x86_64/ && make install modprobe flashcache lsmod | grep flashcache flashcache_create -p back cachecache /dev/pma /dev/pmb /dev/loop0 flashcache_create -p back cachecache /dev/pma /dev/loop0 mkfs.ext3 /dev/mapper/cachecache mount /dev/mapper/cachecache /home/mount fio -filename=/home/mount/file.1G -direct=1 -iodepth 1 -thread -rw=randread -ioengine=psync -bs=16k -size=1G -numjobs=10 -runtime=1000 -group_reporting -name=mytest echo 0 20971520 flashcache disk=/dev/loop0 ssd=/dev/pmb nvram=/dev/pma cachedev=cachecache cachemode=1 2 blocksize=8 cachesize=0 nvramsize=0 assoc=512 diskassoc=512 md_block_size=8 | dmsetup create cachecache echo 0 20971520 flashcache /dev/loop0 /dev/pmb /dev/pma cachecache 1 2 8 0 0 512 512 8 | dmsetup create cachecache */ //设计创建设备的命令 先不加入nvram,不然后面需要加上解析参数的部分才能正常运行 sprintf(dmsetup_cmd, "echo 0 %lu flashcache %s %s %s %s %d 2 %lu %lu %lu %d %lu %lu" " | dmsetup create %s", disk_devsize, disk_devname, flash_devname, nvram_devname, cachedev, cache_mode, block_size, cache_size, nvram_size, associativity, disk_associativity, md_block_size, cachedev); printf("dmsetup_cmd:%s\n", dmsetup_cmd); /* Go ahead and create the cache. * XXX - Should use the device mapper library for this. */ load_module();//加载flashcache模块 if (verbose) fprintf(stderr, "Creating FlashCache Volume : \"%s\"\n", dmsetup_cmd); ret = system(dmsetup_cmd);//执行命令 创建设备 if (ret) { fprintf(stderr, "%s failed\n", dmsetup_cmd); exit(1); } return 0; }