⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rf_diskthreads.c

📁 RAIDFrame是个非常好的磁盘阵列RAID仿真工具
💻 C
📖 第 1 页 / 共 3 页
字号:
    int tid;    rf_get_threadid(tid);    printf("[%d] done waiting for diskthreads to complete\n", tid);  }    return(0);}int rf_ConfigureDiskThreads(  RF_ShutdownList_t  **listp,  RF_Raid_t           *raidPtr,  RF_Config_t         *cfgPtr){  RF_RowCol_t r, c;  int rc;  RF_DiskQueue_t **diskQueues     = raidPtr->Queues;  RF_DiskQueue_t *spareDiskQueues = &raidPtr->Queues[0][raidPtr->numCol];  RF_RaidDisk_t **disks           = raidPtr->Disks;  RF_RaidDisk_t *spareDisks       = &raidPtr->Disks[0][raidPtr->numCol];#ifndef SIMULATE  int t, threadsPerDisk         = raidPtr->maxQueueDepth;#endif /* !SIMULATE */#ifndef SIMULATE  rc = rf_create_managed_mutex(listp, &raidPtr->diskthread_count_mutex);  if (rc) {    RF_ERRORMSG3("Unable to init mutex file %s line %d rc=%d\n",      __FILE__, __LINE__, rc);    return(rc);  }  rc = rf_create_managed_cond(listp, &raidPtr->diskthread_count_cond);  if (rc) {    RF_ERRORMSG3("Unable to init cond file %s line %d rc=%d\n",      __FILE__, __LINE__, rc);    return(rc);  }#endif /* !SIMULATE */  /* create threads for the disks */  RF_CallocAndAdd(raidPtr->diskids, raidPtr->numRow, sizeof(RF_DiskId_t *), (RF_DiskId_t **), raidPtr->cleanupList);  if (raidPtr->diskids == NULL)    return(ENOMEM);#ifndef SIMULATE  RF_CallocAndAdd(raidPtr->diskthreads, raidPtr->numRow, sizeof(RF_Thread_t *), (RF_Thread_t **), raidPtr->cleanupList);  if (raidPtr->diskthreads == NULL)    return(ENOMEM);#endif /* !SIMULATE */  for (r=0; r<raidPtr->numRow; r++) {    RF_CallocAndAdd(raidPtr->diskids[r], raidPtr->numCol, sizeof(struct RF_DiskId_s), (struct RF_DiskId_s *), raidPtr->cleanupList);    if (raidPtr->diskids[r] == NULL)      return(ENOMEM);#ifndef SIMULATE    RF_CallocAndAdd(raidPtr->diskthreads[r], raidPtr->numCol, sizeof(RF_Thread_t), (RF_Thread_t *), raidPtr->cleanupList);    if (raidPtr->diskthreads[r] == NULL)      return(ENOMEM);#endif /* !SIMULATE */    for (c=0; c<raidPtr->numCol; c++) {      raidPtr->diskids[r][c].queue = &(diskQueues[r][c]);      raidPtr->diskids[r][c].disk  = &(disks[r][c]);      raidPtr->diskids[r][c].row   = r;      raidPtr->diskids[r][c].col   = c;      raidPtr->diskids[r][c].raidPtr = raidPtr;#ifdef SIMULATE      raidPtr->diskids[r][c].state   = RF_IDLE;#else /* SIMULATE */      for (t=0; t<threadsPerDisk; t++) {        if (RF_CREATE_THREAD(raidPtr->diskthreads[r][c], disk_rw_func, &raidPtr->diskids[r][c]))          RF_PANIC();        RF_LOCK_MUTEX(raidPtr->diskthread_count_mutex);        raidPtr->diskthreads_created++;        RF_UNLOCK_MUTEX(raidPtr->diskthread_count_mutex);      }#endif /* SIMULATE */    }  }/* create spare drives */  /* create threads for the spare disks */  if (raidPtr->numSpare) {    RF_CallocAndAdd(raidPtr->sparediskids, raidPtr->numSpare, sizeof(RF_DiskId_t), (RF_DiskId_t *), raidPtr->cleanupList);    if (raidPtr->sparediskids == NULL)      return(ENOMEM);#ifndef SIMULATE    RF_CallocAndAdd(raidPtr->sparediskthreads, raidPtr->numSpare, sizeof(RF_Thread_t), (RF_Thread_t *), raidPtr->cleanupList);    if (raidPtr->sparediskthreads == NULL)      return(ENOMEM);#endif /* !SIMULATE */    for (r=0; r<raidPtr->numSpare; r++) {      raidPtr->sparediskids[r].queue = &(spareDiskQueues[r]);      raidPtr->sparediskids[r].disk  = &(spareDisks[r]);      raidPtr->sparediskids[r].row   = 0;      raidPtr->sparediskids[r].col   = r+raidPtr->numCol;      raidPtr->sparediskids[r].raidPtr = raidPtr;#ifdef SIMULATE      raidPtr->sparediskids[r].state   = RF_IDLE;#else /* SIMULATE */      for (t=0; t<threadsPerDisk; t++) {        if (RF_CREATE_THREAD(raidPtr->sparediskthreads[r], disk_rw_func, &raidPtr->sparediskids[r]))          RF_PANIC();        RF_LOCK_MUTEX(raidPtr->diskthread_count_mutex);        raidPtr->diskthreads_created++;        RF_UNLOCK_MUTEX(raidPtr->diskthread_count_mutex);      }#endif /* SIMULATE */    }  }#ifndef SIMULATE  if (rf_dtDebug) {    int tid;    rf_get_threadid(tid);    printf("[%d] waiting for diskthreads to start\n", tid);  }  RF_LOCK_MUTEX(raidPtr->diskthread_count_mutex);  while(raidPtr->diskthreads_running < raidPtr->diskthreads_created) {    RF_WAIT_COND(raidPtr->diskthread_count_cond, raidPtr->diskthread_count_mutex);  }  RF_UNLOCK_MUTEX(raidPtr->diskthread_count_mutex);  if (rf_dtDebug) {    int tid;    rf_get_threadid(tid);    printf("[%d] done waiting for diskthreads to start\n", tid);  }#endif /* !SIMULATE */  return(0);}#ifndef SIMULATEstatic int open_raw_disk_file(fname)  char  *fname;{  int fd;  if ((fd = open(fname, O_RDWR, 0)) < 0) {    RF_ERRORMSG1("Unable to open device file \"%s\"\n",fname);    perror("open_raw_disk_file");    exit(1);  }  return(fd);}#endif /* !SIMULATE */#ifdef SIMULATEint rf_SetDiskIdle(raidPtr, r, c)  RF_Raid_t    *raidPtr;  RF_RowCol_t   r;  RF_RowCol_t   c;{  if((r==0) && (c>=raidPtr->numCol)){raidPtr->sparediskids[c-raidPtr->numCol].state = RF_IDLE;}  else{raidPtr->diskids[r][c].state = RF_IDLE;}  return(0);}int rf_ScanDiskQueues(raidPtr)  RF_Raid_t  *raidPtr;{  RF_RowCol_t r, c;  int t;     t=0;         for (r=0; r<raidPtr->numRow; r++)     for (c=0; c<raidPtr->numCol; c++)       if (raidPtr->diskids[r][c].state == RF_IDLE) t+=disk_rw_func(&raidPtr->diskids[r][c]);		     		         for (r=0; r<raidPtr->numSpare; r++) {    if (raidPtr->sparediskids[r].state == RF_IDLE) t+=disk_rw_func(&raidPtr->sparediskids[r]);  }  return (t);}void rf_simulator_complete_io(id)  RF_DiskId_t  *id;{	id->queue->numOutstanding--;	RF_ASSERT(id->queue->numOutstanding >= 0);}static int disk_rw_func(id)  RF_DiskId_t  *id;{  RF_DiskQueueData_t *req;  RF_Raid_t *raidPtr;  int numbytes, status = 0;  RF_uint64 byteoffs;#ifndef SIMULATE  int i, numactual;#endif /* !SIMULATE */   double access_time;  double total_access_time;  double media_done_time;  double wake_up_time;  raidPtr = id->raidPtr;  req = rf_DiskIODequeue(id->queue);       /* blocks thread until something available.  Can also terminate thread. */  if (!req) {	  /* there is nothing to do for now */	  return(0);  }  /* reject the request if the disk is in any of the dead states */  if (RF_DEAD_DISK(id->disk->status)) {      status = -1; wake_up_time=rf_cur_time; goto out;  }  byteoffs = req->sectorOffset * id->disk->blockSize;  numbytes = req->numSector * id->disk->blockSize;  /* the mapping code must guarantee this property */  RF_ASSERT(req->sectorOffset + req->numSector <= id->disk->numBlocks + rf_protectedSectors);  if (req->type != RF_IO_TYPE_NOP && numbytes == 0) {    if (id->row >= 0) printf("WARNING: zero-byte transfer to disk row %d col %d\n",id->row,id->col);    else printf("WARNING: zero-byte transfer to spare disk %d\n",id->col);  }#ifndef SIMULATE  id->queue->numOutstanding--;  RF_ASSERT(id->queue->numOutstanding >= 0);#endif /* !SIMULATE */  switch (req->type)    {    case RF_IO_TYPE_NOP:         /* used primarily to unlock a locked queue */      break;    case RF_IO_TYPE_READ:    case RF_IO_TYPE_WRITE:      rf_Access_time(&access_time,rf_cur_time, req->sectorOffset, req->numSector, &id->disk->diskState, &media_done_time, 1 );#if RF_KEEP_DISKSTATS > 0      if (req->type == RF_IO_TYPE_READ)        id->disk->nreads++;      else        id->disk->nwrites++;#endif /* RF_KEEP_DISKSTATS > 0 */      wake_up_time=rf_cur_time+access_time; /* should add previos computation time too */      total_access_time= access_time;      /* create an event and ret to main */      break;    default:      RF_ERRORMSG1("Error: unknown access type '%c' in disk_rw_func\n",req->type);      status = -1;      wake_up_time=rf_cur_time;      goto out;            break;    } /* end case */  id->state = RF_BUSY; out:#ifdef SIMULATE  rf_DDEventRequest(wake_up_time, req->CompleteFunc,req->argument, req->owner, id->row, id->col, (RF_Raid_t *) req->raidPtr, (void *)id);#else /* SIMULATE */  rf_DDEventRequest(wake_up_time, req->CompleteFunc,req->argument, req->owner, id->row, id->col, (RF_Raid_t *) req->raidPtr, (void *)NULL);#endif /* SIMULATE */#if RF_DEMO > 0  if (rf_demoMode)    rf_update_disk_iops(1);#endif /* RF_DEMO > 0 */  /* unlock the disk queue if:     (1) this is an unlocking req, independent of failure status of I/O     (2) this is a locking req that failed  */  RF_LOCK_MUTEX(req->queue->mutex);  if (RF_UNLOCKING_REQ(req)) {    if (rf_queueDebug) printf("unlocking queue after pri %d req to r %d c %d\n",req->priority,id->queue->row, id->queue->col);    RF_ASSERT(RF_QUEUE_LOCKED(id->queue));    RF_UNLOCK_QUEUE(id->queue);    id->queue->nextLockingOp = id->queue->unlockingOp = NULL;  } else if (RF_LOCKING_REQ(req) && (status)) {    RF_UNLOCK_QUEUE(id->queue);  } else if (RF_LOCKING_REQ(req)) {    if (rf_queueDebug) printf("completed pri %d locking req on r %d c %d\n",req->priority, id->queue->row, id->queue->col);  } else if (rf_queueDebug) printf("completed pri %d regular req on r %d c %d\n",req->priority,id->queue->row, id->queue->col);  RF_UNLOCK_MUTEX(req->queue->mutex);  if (rf_dtDebug > 1) {    printf("Disk op (r%d c%d) %c %ld %d buf 0x%lx stat %d ",	   id->row,id->col,req->type,req->sectorOffset, req->numSector, req->buf, status);  }    if (status == 0) return (1);  else return (0);}#else  /* SIMULATE *//* this routine is executed by each of the disk threads.  It just grabs the next request off of * the disk queue and sends it down. */static void disk_rw_func(id)  RF_DiskId_t  *id;{  RF_DiskQueueData_t *req;  RF_Raid_t *raidPtr;  int numactual, numbytes, status, i;  RF_uint64 byteoffs, sectOffset;  int fd, tid;  long nReads = 0, nWrites = 0, rdRtSum = 0, wrRtSum = 0, util;  RF_Etimer_t timer;  struct timeval st_time, end_time, elpsd;  int media_time_ms;  int initialized = 0, bus, target, lun;  void *r_handle, *w_handle;        /* these are structures via which we do I/Os through the cam layer */  raidPtr = id->raidPtr;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -