예제 #1
0
파일: cache.c 프로젝트: naftaliharris/cs140
/* Reads from or writes to the given sector at bytes i such that from <= i < to,
 * reading them to or writing them from buffer. buffer must have size at least
 * from - to. 
 *
 * For internal use.
 */
static void
cached_read_write(block_sector_t sector, bool write,
                  uint32_t from, uint32_t to, void *buffer)
{
    ASSERT (from < to);
    ASSERT (to <= BLOCK_SECTOR_SIZE);

    struct cached_block *cb;
    while (true) {
        reader_acquire(&sector_lock);
        cb = find_cached_sector(sector);
        if (cb != NULL) {
            reader_release(&sector_lock);
            rw_acquire(&cb->rw_lock, write);
            if (cb->sector == sector && (cb->state == CLEAN || cb->state == DIRTY)) {
                /* Typical case: Found the sector in cache, and it didn't
                 * change before we got a chance to see it. */

                if (write) {
                    memcpy(cb->data + from, buffer, (to - from));
                    cb->state = DIRTY;
                }
                else {
                    memcpy(buffer, cb->data + from, (to - from));
                }

                cb->accessed = true;  /* XXX synchronized? */
                rw_release(&cb->rw_lock, write);
                return;
            }
            /* Atypical case: We found the sector in cache, but it changed
             * before we got a chance to see it: Try again. */
            rw_release(&cb->rw_lock, write);
        } else {
            cb = get_free_block();
            reader_release(&sector_lock);
            writer_acquire(&sector_lock);
            if (find_cached_sector(sector) == NULL) {
                /* Typical case: We didn't find the sector in cache, and it
                 * didn't pop up before we could add it */
                cb->sector = sector;
                cb->state = IN_IO;
                writer_release(&sector_lock);

                block_read(fs_device, cb->sector, cb->data);
                cb->state = CLEAN;

                if (write) {
                    memcpy(cb->data + from, buffer, (to - from));
                    cb->state = DIRTY;
                }
                else {
                    memcpy(buffer, cb->data + from, (to - from));
                }

                cb->accessed = true;
                writer_release(&cb->rw_lock);
                return;
            }
            /* Atypical case: We didn't find the sector in cache, but it
             * popped up before we could add it: Try again. */
            writer_release(&sector_lock);
            writer_release(&cb->rw_lock);
        }
    }
}
예제 #2
0
void *rw_bnchmrk(void *arg) {

  /* struct unpack */
  struct opts o = *(struct opts*)arg;
  int wprob = o.prob;
  int *shared_array  = o.array;
  struct rw *l = o.lock;
  int wcslen = o.wcslen;
  int rcslen = o.rcslen;
  int ncslen = o.ncslen;
  unsigned msecs = o.msecs;

  int node, private_array[64];
  long i = 0; /* result */

  struct timeval tsmain, tfmain, tsncs, tfncs, tswcs, tfwcs, tsrcs, tfrcs; 

  int seed = time(NULL);

  gettimeofday(&tsmain, NULL);
  gettimeofday(&tfmain, NULL);
  while (mtimediff(tfmain, tsmain) <= msecs) {
    i++;

    gettimeofday(&tsncs, NULL);
    gettimeofday(&tfncs, NULL);
    while (mtimediff(tfncs, tsncs) <= ncslen) {
      int r = rand_r(&seed) % 500;
      private_array[rand_r(&seed) % 64] += r;
      private_array[rand_r(&seed) % 64] -= r;
      gettimeofday(&tfncs, NULL);      
    }

    int p = rand_r(&seed) % 100;

    if( p < wprob) {

      gettimeofday(&tswcs, NULL);
      rw_acquire(l, W, &node); /*entering the critical section*/


      gettimeofday(&tfwcs, NULL);
      while (mtimediff(tfwcs, tswcs) <= wcslen) {
	int r = rand_r(&seed) % 500;
	shared_array[rand_r(&seed) % 64] += r;
	shared_array[rand_r(&seed) % 64] -= r;
	gettimeofday(&tfwcs, NULL);
      }

      rw_release(l, W, node);
    } else {
      gettimeofday(&tsrcs, NULL);
      rw_acquire(l, R, &node); /*entering the critical section*/
      gettimeofday(&tfrcs, NULL);
      while (mtimediff(tfrcs,tsrcs) <= rcslen) {
	volatile int i1 = shared_array[rand_r(&seed) % 64];
	volatile int i2 = shared_array[rand_r(&seed) % 64];
	gettimeofday(&tfrcs, NULL);
      }

      rw_release(l, R, node);
    }
    gettimeofday(&tfmain, NULL);
  }

  return (void *)i;
}