Ejemplo n.º 1
0
long dependent_swap<dtype>::write(FILE *fileptr) {
  sub_1d_type npages;
  sub_1d_type nwritten=0;
  sub_1d_type sub;

  //if the current swap file stream is null, then set it to fileptr
  //and advance the byte location forward the size of the dataset:
  if (swap == NULL) {
    swap=fileptr;
    swap_start=ftell(swap);
    fseek(swap, this->n_data*sizeof(dtype), SEEK_CUR);
    return this->n_data*sizeof(dtype);
  }

  //write out all the data:
  npages=this->n_data/page_size;
  for (sub_1d_type i=0; i<npages; i++) {
    sub=i*page_size;
    check_page(sub);
    nwritten+=fwrite(this->data, sizeof(dtype), page_size, fileptr);
  }
  sub=npages*page_size;
  if (check_page(sub) != -1) {
    nwritten+=fwrite(this->data, sizeof(dtype), this->n_data-sub, fileptr);
  }

  return nwritten;

}
Ejemplo n.º 2
0
void writer(int num)
{
  uint i;
  uchar *buff;
  PAGECACHE_BLOCK_LINK *link;

  for (i= 0; i < number_of_write_tests; i++)
  {
    uchar c= (uchar) rand() % 256;

    if (i % report_divisor == 0)
      diag("Writer %d - %u", num, i);
    buff= pagecache_read(&pagecache, &file1, 0, 3, NULL,
                         PAGECACHE_PLAIN_PAGE,
                         PAGECACHE_LOCK_WRITE,
                         &link);

    check_page(buff, num);
    bfill(buff, TEST_PAGE_SIZE / 2, c);
    SLEEP;
    bfill(buff + TEST_PAGE_SIZE/2, TEST_PAGE_SIZE / 2, c);
    check_page(buff, num);
    pagecache_unlock_by_link(&pagecache, link,
                             PAGECACHE_LOCK_WRITE_UNLOCK,
                             PAGECACHE_UNPIN, 0, 0, 1, FALSE);
    SLEEP;
  }
}
Ejemplo n.º 3
0
static void check_page(struct btree_page *p,
		       const void *lbound, const void *ubound,
		       int height)
{
	const struct btree_def *def = p->def;
	int i;

	assert (p);
	assert (p->height == height);

	if (p != p->owner->root) {
		assert (p->num_children >= def->branches / 2);
		assert (p->num_children <= def->branches);
	}

	for (i = 0; i < p->num_children; i++) {
		const void *key = PAGE_KEY(p, i);
		const void *next_key = ubound;

		if (i + 1 < p->num_children)
			next_key = PAGE_KEY(p, i + 1);

		assert (def->compare(key, lbound) >= 0);
		if (next_key) {
			assert (def->compare(key, next_key) < 0);
		}
		if (ubound) {
			assert (def->compare(key, ubound) < 0);
		}

		if (p->height)
			check_page(*PAGE_PTR(p, i), key, next_key, height - 1);
	}
}
Ejemplo n.º 4
0
void reader(int num)
{
  unsigned char *buff;
  uint i;
  PAGECACHE_BLOCK_LINK *link;

  for (i= 0; i < number_of_read_tests; i++)
  {
    if (i % report_divisor == 0)
      diag("Reader %d - %u", num, i);
    buff= pagecache_read(&pagecache, &file1, 0, 3, NULL,
                         PAGECACHE_PLAIN_PAGE,
                         PAGECACHE_LOCK_READ,
                         &link);
    check_page(buff, num);
    pagecache_unlock_by_link(&pagecache, link,
                             PAGECACHE_LOCK_READ_UNLOCK,
                             PAGECACHE_UNPIN, 0, 0, 0, FALSE);
    {
      int lim= rand() % read_sleep_limit;
      int j;
      for (j= 0; j < lim; j++)
        SLEEP;
    }
  }
}
Ejemplo n.º 5
0
void writer(int num)
{
  unsigned char *buffr= malloc(TEST_PAGE_SIZE);
  uint i;

  for (i= 0; i < number_of_tests; i++)
  {
    uint end;
    uint page= get_len(number_of_pages);
    pagecache_read(&pagecache, &file1, page, 3, buffr,
                   PAGECACHE_PLAIN_PAGE,
                   PAGECACHE_LOCK_WRITE,
                   0);
    end= check_page(buffr, page * TEST_PAGE_SIZE, 1, page, num);
    put_rec(buffr, end, get_len(record_length_limit), num);
    pagecache_write(&pagecache, &file1, page, 3, buffr,
                    PAGECACHE_PLAIN_PAGE,
                    PAGECACHE_LOCK_WRITE_UNLOCK,
                    PAGECACHE_UNPIN,
                    PAGECACHE_WRITE_DELAY,
                    0, LSN_IMPOSSIBLE);

    if (i % flush_divider == 0)
      flush_pagecache_blocks(&pagecache, &file1, FLUSH_FORCE_WRITE);
  }
  free(buffr);
}
Ejemplo n.º 6
0
static void check_btree(btree_t bt)
{
	assert (bt->def);

	if (bt->root->height) {
		assert (bt->root->num_children >= 2);
	}

	check_page(bt->root, bt->def->zero, NULL, bt->root->height);
}
Ejemplo n.º 7
0
Archivo: free.c Proyecto: Selk/Dev
void	free(void *ptr)
{
	t_block	*b;

	if (ptr == NULL)
		return ;
	b = search_ptr(ptr);
	if (b == NULL)
		return ;
	b = fusion_block(b);
	check_page(b);
}
Ejemplo n.º 8
0
void reader(int num)
{
  unsigned char buff[TEST_PAGE_SIZE];
  uint i;

  for (i= 0; i < number_of_read_tests; i++)
  {
    if (i % report_divisor == 0)
      diag("Reader %d - %u", num, i);
    pagecache_read(&pagecache, &file1, 0, 3, buff,
                   PAGECACHE_PLAIN_PAGE,
                   PAGECACHE_LOCK_LEFT_UNLOCKED,
                   NULL);
    check_page(buff, num);
  }
}
Ejemplo n.º 9
0
void reader(int num)
{
  unsigned char *buffr= malloc(TEST_PAGE_SIZE);
  uint i;

  for (i= 0; i < number_of_tests; i++)
  {
    uint page= get_len(number_of_pages);
    pagecache_read(&pagecache, &file1, page, 3, buffr,
                   PAGECACHE_PLAIN_PAGE,
                   PAGECACHE_LOCK_LEFT_UNLOCKED,
                   0);
    check_page(buffr, page * TEST_PAGE_SIZE, 0, page, -num);

  }
  free(buffr);
}
Ejemplo n.º 10
0
void test_pack(const int *pl, const int **headers){
  unsigned char *data=_ogg_malloc(1024*1024); /* for scripted test cases only */
  long inptr=0;
  long outptr=0;
  long deptr=0;
  long depacket=0;
  long granule_pos=7,pageno=0;
  int i,j,packets,pageout=0;
  int eosflag=0;
  int bosflag=0;

  ogg_stream_reset(&os_en);
  ogg_stream_reset(&os_de);
  ogg_sync_reset(&oy);

  for(packets=0;;packets++)if(pl[packets]==-1)break;

  for(i=0;i<packets;i++){
    /* construct a test packet */
    ogg_packet op;
    int len=pl[i];
    
    op.packet=data+inptr;
    op.bytes=len;
    op.e_o_s=(pl[i+1]<0?1:0);
    op.granulepos=granule_pos;

    granule_pos+=1024;

    for(j=0;j<len;j++)data[inptr++]=i+j;

    /* submit the test packet */
    ogg_stream_packetin(&os_en,&op);

    /* retrieve any finished pages */
    {
      ogg_page og;
      
      while(ogg_stream_pageout(&os_en,&og)){
	/* We have a page.  Check it carefully */

	fprintf(stderr,"%ld, ",pageno);

	if(headers[pageno]==NULL){
	  fprintf(stderr,"coded too many pages!\n");
	  exit(1);
	}

	check_page(data+outptr,headers[pageno],&og);

	outptr+=og.body_len;
	pageno++;

	/* have a complete page; submit it to sync/decode */

	{
	  ogg_page og_de;
	  ogg_packet op_de,op_de2;
	  char *buf=ogg_sync_buffer(&oy,og.header_len+og.body_len);
	  memcpy(buf,og.header,og.header_len);
	  memcpy(buf+og.header_len,og.body,og.body_len);
	  ogg_sync_wrote(&oy,og.header_len+og.body_len);

	  while(ogg_sync_pageout(&oy,&og_de)>0){
	    /* got a page.  Happy happy.  Verify that it's good. */
	    
	    check_page(data+deptr,headers[pageout],&og_de);
	    deptr+=og_de.body_len;
	    pageout++;

	    /* submit it to deconstitution */
	    ogg_stream_pagein(&os_de,&og_de);

	    /* packets out? */
	    while(ogg_stream_packetpeek(&os_de,&op_de2)>0){
	      ogg_stream_packetpeek(&os_de,NULL);
	      ogg_stream_packetout(&os_de,&op_de); /* just catching them all */
	      
	      /* verify peek and out match */
	      if(memcmp(&op_de,&op_de2,sizeof(op_de))){
		fprintf(stderr,"packetout != packetpeek! pos=%ld\n",
			depacket);
		exit(1);
	      }

	      /* verify the packet! */
	      /* check data */
	      if(memcmp(data+depacket,op_de.packet,op_de.bytes)){
		fprintf(stderr,"packet data mismatch in decode! pos=%ld\n",
			depacket);
		exit(1);
	      }
	      /* check bos flag */
	      if(bosflag==0 && op_de.b_o_s==0){
		fprintf(stderr,"b_o_s flag not set on packet!\n");
		exit(1);
	      }
	      if(bosflag && op_de.b_o_s){
		fprintf(stderr,"b_o_s flag incorrectly set on packet!\n");
		exit(1);
	      }
	      bosflag=1;
	      depacket+=op_de.bytes;
	      
	      /* check eos flag */
	      if(eosflag){
		fprintf(stderr,"Multiple decoded packets with eos flag!\n");
		exit(1);
	      }

	      if(op_de.e_o_s)eosflag=1;

	      /* check granulepos flag */
	      if(op_de.granulepos!=-1){
		fprintf(stderr," granule:%ld ",(long)op_de.granulepos);
	      }
	    }
	  }
	}
      }
    }
  }
  _ogg_free(data);
  if(headers[pageno]!=NULL){
    fprintf(stderr,"did not write last page!\n");
    exit(1);
  }
  if(headers[pageout]!=NULL){
    fprintf(stderr,"did not decode last page!\n");
    exit(1);
  }
  if(inptr!=outptr){
    fprintf(stderr,"encoded page data incomplete!\n");
    exit(1);
  }
  if(inptr!=deptr){
    fprintf(stderr,"decoded page data incomplete!\n");
    exit(1);
  }
  if(inptr!=depacket){
    fprintf(stderr,"decoded packet data incomplete!\n");
    exit(1);
  }
  if(!eosflag){
    fprintf(stderr,"Never got a packet with EOS set!\n");
    exit(1);
  }
  fprintf(stderr,"ok.\n");
}
Ejemplo n.º 11
0
// Set up a two-level page table:
//    kern_pgdir is its linear (virtual) address of the root
//
// This function only sets up the kernel part of the address space
// (ie. addresses >= UTOP).  The user part of the address space
// will be setup later.
//
// From UTOP to ULIM, the user is allowed to read but not write.
// Above ULIM the user cannot read or write.
void
mem_init(void)
{
	uint32_t cr0;
	size_t n;

	// Find out how much memory the machine has (npages & npages_basemem).
	i386_detect_memory();

	//////////////////////////////////////////////////////////////////////
	// create initial page directory.
	kern_pgdir = (pde_t *) boot_alloc(PGSIZE);
	memset(kern_pgdir, 0, PGSIZE);

	//////////////////////////////////////////////////////////////////////
	// Recursively insert PD in itself as a page table, to form
	// a virtual page table at virtual address UVPT.
	// (For now, you don't have understand the greater purpose of the
	// following line.)

	// Permissions: kernel R, user R
	kern_pgdir[PDX(UVPT)] = PADDR(kern_pgdir) | PTE_U | PTE_P;

	//////////////////////////////////////////////////////////////////////
	// Allocate an array of npages 'struct Page's and store it in 'pages'.
	// The kernel uses this array to keep track of physical pages: for
	// each physical page, there is a corresponding struct Page in this
	// array.  'npages' is the number of physical pages in memory.
	// Your code goes here:
    pages = boot_alloc(npages*sizeof(* pages));

	//////////////////////////////////////////////////////////////////////
	// Make 'envs' point to an array of size 'NENV' of 'struct Env'.
	// LAB 3: Your code here.

    envs = boot_alloc(NENV * sizeof(* envs));

	//////////////////////////////////////////////////////////////////////
	// Now that we've allocated the initial kernel data structures, we set
	// up the list of free physical pages. Once we've done so, all further
	// memory management will go through the page_* functions. In
	// particular, we can now map memory using boot_map_region
	// or page_insert
	page_init();

	check_page_free_list(1);
	check_page_alloc();
	check_page();

	//////////////////////////////////////////////////////////////////////
	// Now we set up virtual memory

	//////////////////////////////////////////////////////////////////////
	// Map 'pages' read-only by the user at linear address UPAGES
	// Permissions:
	//    - the new image at UPAGES -- kernel R, user R
	//      (ie. perm = PTE_U | PTE_P)
	//    - pages itself -- kernel RW, user NONE
	// Your code goes here:
    boot_map_region( kern_pgdir,  (uintptr_t) UPAGES, npages*(sizeof(* pages)),
                     PADDR(pages), PTE_U | PTE_P);

    boot_map_region( kern_pgdir, (uintptr_t) pages, npages*(sizeof(* pages)),
                     PADDR(pages), PTE_W | PTE_P);

    
	//////////////////////////////////////////////////////////////////////
	// Map the 'envs' array read-only by the user at linear address UENVS
	// (ie. perm = PTE_U | PTE_P).
	// Permissions:
	//    - the new image at UENVS  -- kernel R, user R
	//    - envs itself -- kernel RW, user NONE
	// LAB 3: Your code here.

    boot_map_region( kern_pgdir,  (uintptr_t) UENVS, npages*(sizeof(* envs)),
                     PADDR(envs), PTE_U | PTE_P);

    boot_map_region( kern_pgdir, (uintptr_t) envs, npages*(sizeof(* envs)),
                     PADDR(envs), PTE_W | PTE_P);

	//////////////////////////////////////////////////////////////////////
	// Use the physical memory that 'bootstack' refers to as the kernel
	// stack.  The kernel stack grows down from virtual address KSTACKTOP.
	// We consider the entire range from [KSTACKTOP-PTSIZE, KSTACKTOP)
	// to be the kernel stack, but break this into two pieces:
	//     * [KSTACKTOP-KSTKSIZE, KSTACKTOP) -- backed by physical memory
	//     * [KSTACKTOP-PTSIZE, KSTACKTOP-KSTKSIZE) -- not backed; so if
	//       the kernel overflows its stack, it will fault rather than
	//       overwrite memory.  Known as a "guard page".
	//     Permissions: kernel RW, user NONE
	// Your code goes here:

    boot_map_region( kern_pgdir, KSTACKTOP-KSTKSIZE, KSTKSIZE,
                     PADDR(bootstack), PTE_W | PTE_P );

	//////////////////////////////////////////////////////////////////////
	// Map all of physical memory at KERNBASE.
	// Ie.  the VA range [KERNBASE, 2^32) should map to
	//      the PA range [0, 2^32 - KERNBASE)
	// We might not have 2^32 - KERNBASE bytes of physical memory, but
	// we just set up the mapping anyway.
	// Permissions: kernel RW, user NONE
	// Your code goes here:
    
    boot_map_region( kern_pgdir, (uintptr_t) KERNBASE, 0xFFFFFFFF, 0,
                     PTE_W | PTE_P);

	// Initialize the SMP-related parts of the memory map
	mem_init_mp();

	// Check that the initial page directory has been set up correctly.
	check_kern_pgdir();

	// Switch from the minimal entry page directory to the full kern_pgdir
	// page table we just created.	Our instruction pointer should be
	// somewhere between KERNBASE and KERNBASE+4MB right now, which is
	// mapped the same way by both page tables.
	//
	// If the machine reboots at this point, you've probably set up your
	// kern_pgdir wrong.
	lcr3(PADDR(kern_pgdir));

	check_page_free_list(0);

	// entry.S set the really important flags in cr0 (including enabling
	// paging).  Here we configure the rest of the flags that we care about.
	cr0 = rcr0();
	cr0 |= CR0_PE|CR0_PG|CR0_AM|CR0_WP|CR0_NE|CR0_MP;
	cr0 &= ~(CR0_TS|CR0_EM);
	lcr0(cr0);

	// Some more checks, only possible after kern_pgdir is installed.
	check_page_installed_pgdir();
}
Ejemplo n.º 12
0
int main(int argc, char **argv) {
  int i, m, n, lim, chk, page_format;
  FILE *fi, *fo, *f1, *f2;

  /* print usage */
  if (argc < 3) {
    printf("usage: %s <infile> <outfile> [options]\n", argv[0]);
    printf("options:\n");
    printf("  -b <buffer-number>      set buffer number, default and maximum value is 130\n");
    printf("  -db                     enable double buffering\n");
    printf("  -p                      output 1kb pages (task 2)\n");
    printf("  -c                      check correctness when sort completed (debug)\n");
    printf("  -l <record-number>      sort first <record-number> records (debug)\n");
    return -1;
  }

  /* get arguments */
  k = K;
  lim = 0x7fffffff;
  db = chk = page_format = 0;
  for (i = 3; i < argc; i++) {
    if (!strcmp(argv[i], "-b")) {
      sscanf(argv[++i], "%d", &k);
      if (k > K) {
        fprintf(stderr, "error: too many buffer pages.");
        return -1;
      }
    } else if (!strcmp(argv[i], "-l")) {
      sscanf(argv[++i], "%d", &lim);
    } else if (!strcmp(argv[i], "-c")) {
      chk = 1;
    } else if (!strcmp(argv[i], "-db")) {
      db = 1;
    } else if (!strcmp(argv[i], "-p")) {
      page_format = 1;
    }
  }
  k = k / (db + 1) - 1;
  if (k < 2) {
    fprintf(stderr, "error: too few buffer pages.");
    return -1;
  }

  /* open files */
  fi = fopen(argv[1], "rb+");
  if (!fi) {
    fprintf(stderr, "error: file '%s' is not found.\n", argv[1]);
    return -1;
  }
  if (!page_format) {
    if (!strcmp(argv[1], argv[2])) {
      fprintf(stderr, "error: infile cannot be the same as outfile.\n");
      return -1;
    }
    fo = fopen(argv[2], "wb+");
  }
  f1 = tmpfile();
  f2 = tmpfile();

  /* confirm arguments */
  printf("buffer pages:     %d\n", (k + 1) * (db + 1));
  printf("double buffering: %s\n", db ? "yes" : "no");
  printf("output 1kb pages: %s\n", page_format ? "yes" : "no");

  /* start timer */
  time_t start = time(0);
  puts("sorting...");

  /* init mutex, semaphore */
  if (db) {
    for (i = 0; i <= K; i++) {
      pthread_mutex_init(&mutex[i], 0);
      sem_init(&sem[i], 0, 0);
    }
  }
  /* extract useful data, quick sort pages individualy   */
  struct line line;
  for (n = 0; !feof(fi) && n < lim;) {
    buffer[0][n % M].p = ftell(fi);
    line_read(fi, &line);
    buffer[0][n % M].x = line.x;
    buffer[0][n % M].y = line.y;

    n++;

    if (n % M == 0 || feof(fi) || n == lim) {
      int num = n % M ? n % M : M;
      qsort(buffer[0], num, S, record_cmp);
      fwrite(buffer[0], S, num, f1);
    }
  }

  /* merge sort */
  if (db)
    merge_sort_db(f1, f2, 1, 0, n);
  else
    merge_sort(f1, f2, 1, 0, n);

  /* format from useful data to real data */
  if (page_format)
    format_page(argv[2], f1, fi, n);
  else
    format(fo, f1, fi, n);

  /* stop timer */
  time_t end = time(0);
  int sec = (int)difftime(end, start);
  printf("completed, time elapsed: %d min %d sec\n", sec / 60, sec % 60);

  /* check correctness */
  if (chk) {
    printf("checking correctness: ");
    fflush(stdout);
    if (page_format ? check_page(argv[2]) : check(fo))
      puts("yes");
    else
      puts("no");
  }

  /* close files */
  fclose(f1);
  fclose(f2);
  fclose(fi);
  if (!page_format)
    fclose(fo);

  return 0;
}
Ejemplo n.º 13
0
Archivo: madvise09.c Proyecto: kraj/ltp
static void child(void)
{
	size_t i;
	char *ptr;
	unsigned int usage, old_limit, old_memsw_limit;
	int status, pid, retries = 0;

	SAFE_MKDIR(cgroup_path, 0777);
	SAFE_FILE_PRINTF(tasks_path, "%i", getpid());

	ptr = SAFE_MMAP(NULL, PAGES * page_size, PROT_READ | PROT_WRITE,
	                 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

	for (i = 0; i < PAGES * page_size; i++)
		ptr[i] = 'a';

	if (madvise(ptr, PAGES * page_size, MADV_FREE)) {
		if (errno == EINVAL)
			tst_brk(TCONF | TERRNO, "MADV_FREE is not supported");

		tst_brk(TBROK | TERRNO, "MADV_FREE failed");
	}

	if (ptr[page_size] != 'a')
		tst_res(TFAIL, "MADV_FREE pages were freed immediatelly");
	else
		tst_res(TPASS, "MADV_FREE pages were not freed immediatelly");

	ptr[TOUCHED_PAGE1 * page_size] = 'b';
	ptr[TOUCHED_PAGE2 * page_size] = 'b';

	usage = 8 * 1024 * 1024;
	tst_res(TINFO, "Setting memory limits to %u %u", usage, 2 * usage);

	SAFE_FILE_SCANF(limit_in_bytes_path, "%u", &old_limit);

	if (swap_accounting_enabled)
		SAFE_FILE_SCANF(memsw_limit_in_bytes_path, "%u", &old_memsw_limit);

	SAFE_FILE_PRINTF(limit_in_bytes_path, "%u", usage);

	if (swap_accounting_enabled)
		SAFE_FILE_PRINTF(memsw_limit_in_bytes_path, "%u", 2 * usage);

	do {
		sleep_between_faults++;

		pid = SAFE_FORK();
		if (!pid)
			memory_pressure_child();

		tst_res(TINFO, "Memory hungry child %i started, try %i", pid, retries);

		SAFE_WAIT(&status);
	} while (retries++ < 10 && count_freed(ptr) == 0);

	char map[PAGES+1];
	unsigned int freed = 0;
	unsigned int corrupted = 0;

	for (i = 0; i < PAGES; i++) {
		char exp_val;

		if (ptr[i * page_size]) {
			exp_val = 'a';
			map[i] = 'p';
		} else {
			exp_val = 0;
			map[i] = '_';
			freed++;
		}

		if (i != TOUCHED_PAGE1 && i != TOUCHED_PAGE2) {
			if (check_page(ptr + i * page_size, exp_val)) {
				map[i] = '?';
				corrupted++;
			}
		} else {
			if (check_page_baaa(ptr + i * page_size)) {
				map[i] = '?';
				corrupted++;
			}
		}
	}
	map[PAGES] = '\0';

	tst_res(TINFO, "Memory map: %s", map);

	if (freed)
		tst_res(TPASS, "Pages MADV_FREE were freed on low memory");
	else
		tst_res(TFAIL, "No MADV_FREE page was freed on low memory");

	if (corrupted)
		tst_res(TFAIL, "Found corrupted page");
	else
		tst_res(TPASS, "All pages have expected content");

	if (swap_accounting_enabled)
		SAFE_FILE_PRINTF(memsw_limit_in_bytes_path, "%u", old_memsw_limit);

	SAFE_FILE_PRINTF(limit_in_bytes_path, "%u", old_limit);

	SAFE_MUNMAP(ptr, PAGES);

	exit(0);
}
Ejemplo n.º 14
0
int spimem_write_h(uint8_t spi_chip, uint32_t addr, uint8_t* data_buff, uint32_t size)
{
	uint32_t size1, size2, low, dirty = 0, page, sect_num, check;
		
	if (size > 256)				// Invalid size to write.
		return -2;
	if (addr > 0xFFFFF)			// Invalid address to write to.
		return -2;
	
	low = addr & 0x000000FF;
	if ((size + low) > 256)		// Requested write flows into a second page.
	{
		size1 = 256 - low;
		size2 = size - size1;
	}
	else
	{
		size1 = size;
		size2 = 0;
	}
	if ((addr + (size - 1)) > 0xFFFFF)	// Address too high, can't write all requested bytes.
	{
		size1 = 256 - low;
		size2 = 0;
	}

	if (xSemaphoreTake(Spi0_Mutex, (TickType_t) 1) == pdTRUE)	// Only Block for a single tick.
	{
		enter_atomic();											// Atomic operation begins.
		
		if(ready_for_command_h(spi_chip) != 1)
		{
			exit_atomic();
			xSemaphoreGive(Spi0_Mutex);
			return -4;
		}
					
		page = get_page(addr);
		dirty = check_page(page);
		if(dirty)
		{
			sect_num = get_sector(addr);
			check = load_sector_into_spibuffer(spi_chip, sect_num);			// if check != 4096, FAILURE_RECOVERY.
			check = update_spibuffer_with_new_page(addr, data_buff, size1);	// if check != size1, FAILURE_RECOVERY.
			check = erase_sector_on_chip(spi_chip, sect_num);				// FAILURE_RECOVERY
			check = write_sector_back_to_spimem(spi_chip);					// FAILURE_RECOVERY
		}
		else
		{		
			if(write_page_h(spi_chip, addr, data_buff, size1) != 1)
			{
				exit_atomic();						// Atomic operation ends.
				xSemaphoreGive(Spi0_Mutex);
				return -1;
			}
		}
		if(size2)	// Requested write flows into a second page.
		{
			page = get_page(addr + size1);
			dirty = check_page(page);
			
			if(ready_for_command_h(spi_chip) != 1)
			{
				exit_atomic();
				xSemaphoreGive(Spi0_Mutex);
				return size1;
			}
			if(dirty)
			{
				sect_num = get_sector(addr + size1);
				check = load_sector_into_spibuffer(spi_chip, sect_num);						// if check != 4096, FAILURE_RECOVERY.
				if(check != 4096)
					return -4;
				check = update_spibuffer_with_new_page(addr + size1, (data_buff + size1), size2);	// if check != size1, FAILURE_RECOVERY.
				if(check != size1)
					return -4;
				check = erase_sector_on_chip(spi_chip, sect_num);				// FAILURE_RECOVERY
				if(check != 1)
					return -4;
				check = write_sector_back_to_spimem(spi_chip);					// FAILURE_RECOVERY
				if(check == 0xFFFFFFFF)
					return -4;
			}
			else
			{		
				if(write_page_h(spi_chip, addr + size1, (data_buff + size1), size2) != 1)
				{
					exit_atomic();
					xSemaphoreGive(Spi0_Mutex);
					return size1;
				}
			}
		}
		
		exit_atomic();
		xSemaphoreGive(Spi0_Mutex);
		return (size1 + size2);	
	}

	else
		return -3;												// SPI0 is currently being used or there is an error.
}
Ejemplo n.º 15
0
// Set up a two-level page table:
//    kern_pgdir is its linear (virtual) address of the root
// Then turn on paging.  Then effectively turn off segmentation.
// (i.e., the segment base addrs are set to zero).
//
// This function only sets up the kernel part of the address space
// (ie. addresses >= UTOP).  The user part of the address space
// will be setup later.
//
// From UTOP to ULIM, the user is allowed to read but not write.
// Above ULIM the user cannot read or write.
void
mem_init(void)
{
	uint32_t cr0;
	size_t n;

	// Ensure user & kernel struct Pages agree.
	static_assert(sizeof(struct Page) == sizeof(struct UserPage));

	// Find out how much memory the machine has (npages & npages_basemem).
	i386_detect_memory();

	// Remove this line when you're ready to test this function.
	//panic("mem_init: This function is not finished\n");

	//////////////////////////////////////////////////////////////////////
	// create initial page directory.
	kern_pgdir = (pde_t *) boot_alloc(PGSIZE);
	memset(kern_pgdir, 0, PGSIZE);

	//////////////////////////////////////////////////////////////////////
	// Recursively insert PD in itself as a page table, to form
	// a virtual page table at virtual address UVPT.
	// (For now, you don't have understand the greater purpose of the
	// following line.)
	// Permissions: kernel R, user R
	kern_pgdir[PDX(UVPT)] = PADDR(kern_pgdir) | PTE_U | PTE_P;

	//////////////////////////////////////////////////////////////////////
	// Allocate an array of npages 'struct Page's and store it in 'pages'.
	// The kernel uses this array to keep track of physical pages: for
	// each physical page, there is a corresponding struct Page in this
	// array.  'npages' is the number of physical pages in memory.
	pages = (Page *) boot_alloc(npages * sizeof(struct Page));


	//////////////////////////////////////////////////////////////////////
	// Make 'envs' point to an array of size 'NENV' of 'struct Env'.
	// LAB 3: Your code here.
	envs = (Env *) boot_alloc(NENV * sizeof(struct Env));

	//////////////////////////////////////////////////////////////////////
	// Now that we've allocated the initial kernel data structures, we set
	// up the list of free physical pages. Once we've done so, all further
	// memory management will go through the page_* functions. In
	// particular, we can now map memory using page_map_segment
	// or page_insert
	page_init();

	check_page_free_list(true);
	check_page_alloc();
	check_page();

	//////////////////////////////////////////////////////////////////////
	// Now we set up virtual memory

	//////////////////////////////////////////////////////////////////////
	// Use the physical memory that 'entry_stack' refers to as the kernel
	// stack.  The kernel stack grows down from virtual address KSTACKTOP.
	// We consider the entire range from [KSTACKTOP-PTSIZE, KSTACKTOP)
	// to be the kernel stack, but break this into two pieces:
	//     * [KSTACKTOP-KSTKSIZE, KSTACKTOP) -- backed by physical memory
	//     * [KSTACKTOP-PTSIZE, KSTACKTOP-KSTKSIZE) -- not backed; so if
	//       the kernel overflows its stack, it will fault rather than
	//       overwrite memory.  Known as a "guard page".
	//     Permissions: kernel RW, user NONE
	Page *pp = pa2page((physaddr_t)entry_stack-KERNBASE);
	for (uintptr_t ptr = KSTACKTOP-KSTKSIZE; ptr < KSTACKTOP; ptr += PGSIZE) {
		if (page_insert(kern_pgdir, pp, ptr, PTE_W | PTE_P) < 0)
			panic("Couldn't create page table entries for stack.\n");
		pp++;
	}

	//////////////////////////////////////////////////////////////////////
	// Map all of physical memory at KERNBASE.
	// Ie.  the VA range [KERNBASE, 2^32) should map to
	//      the PA range [0, 2^32 - KERNBASE)
	// We might not have 2^32 - KERNBASE bytes of physical memory, but
	// we just set up the mapping anyway.
	// Permissions: kernel RW, user NONE
	page_map_segment(kern_pgdir, KERNBASE, 0xFFFFFFFF-KERNBASE, 0x0, PTE_W | PTE_P);
     
	//print_page_table(kern_pgdir, false, false);

	//////////////////////////////////////////////////////////////////////
	// Map the 'envs' array read-only by the user at linear address UENVS.
	// Permissions: kernel R, user R
	// (That's the UENVS version; 'envs' itself is kernel RW, user NONE.)
	// LAB 3: Your code here.
	page_map_segment(kern_pgdir, (uintptr_t) UENVS, ROUNDUP(NENV*sizeof(struct Env), PGSIZE), PADDR(envs), PTE_U | PTE_P);

	//////////////////////////////////////////////////////////////////////
	// Map 'pages' read-only by the user at linear address UPAGES.
	// Permissions: kernel R, user R
	// (That's the UPAGES version; 'pages' itself is kernel RW, user NONE.)
	// LAB 3: Your code here.
	page_map_segment(kern_pgdir, UPAGES, ROUNDUP(npages*sizeof(struct Page), PGSIZE), PADDR(pages), PTE_U | PTE_P);

	// Check that the initial page directory has been set up correctly.
	check_kern_pgdir();

	// Switch from the minimal entry page directory to the full kern_pgdir
	// page table we just created.	Our instruction pointer should be
	// somewhere between KERNBASE and KERNBASE+4MB right now, which is
	// mapped the same way by both page tables.
	//
	// If the machine reboots at this point, you've probably set up your
	// kern_pgdir wrong.
	lcr3(PADDR(kern_pgdir));

        // entry.S set the really important flags in cr0 (including enabling
        // paging).  Here we configure the rest of the flags we need.
	cr0 = rcr0();
	cr0 |= CR0_PE|CR0_PG|CR0_AM|CR0_WP|CR0_NE|CR0_MP;
	cr0 &= ~(CR0_TS|CR0_EM);
	lcr0(cr0);

	// Some more checks, only possible after kern_pgdir is installed.
	check_page_installed_pgdir();
}
Ejemplo n.º 16
0
void process_ibpage(page_t *page) {
    ulint page_id;
	rec_t *origin;
	ulint offsets[MAX_TABLE_FIELDS + 2];
	ulint offset, i;
    int is_page_valid = 0;
    int comp;
    unsigned int expected_records = 0;
    unsigned int actual_records = 0;
    int16_t b, infimum, supremum;
	
	// Skip tables if filter used
    if (use_filter_id) {
        dulint index_id = mach_read_from_8(page + PAGE_HEADER + PAGE_INDEX_ID);
        if (index_id.low != filter_id.low || index_id.high != filter_id.high) {
            if (debug) {
            	page_id = mach_read_from_4(page + FIL_PAGE_OFFSET);
                printf("Skipped using index id filter: %lu!\n", page_id);
            }
            return;
        }
    }

	// Read page id
	page_id = mach_read_from_4(page + FIL_PAGE_OFFSET);
	if (debug) printf("Page id: %lu\n", page_id);
	fprintf(f_result, "-- Page id: %lu", page_id);
	// Check requested and actual formats
    if (!check_page_format(page)) return;
	if(table_definitions_cnt == 0){
		fprintf(stderr, "There are no table definitions. Please check  include/table_defs.h\n");
		exit(EXIT_FAILURE);
		}
    is_page_valid = check_page(page, &expected_records);
    
    // comp == 1 if page in COMPACT format and 0 if REDUNDANT
    comp = page_is_comp(page);
    fprintf(f_result, ", Format: %s", (comp ) ? "COMPACT": "REDUNDANT");
    infimum = (comp) ? PAGE_NEW_INFIMUM : PAGE_OLD_INFIMUM;
    supremum = (comp) ? PAGE_NEW_SUPREMUM : PAGE_OLD_SUPREMUM;
	// Find possible data area start point (at least 5 bytes of utility data)
	if(is_page_valid){
        b = mach_read_from_2(page + infimum - 2);
        offset = (comp) ? infimum + b : b;
        }
    else{
        offset = 100 + record_extra_bytes;
        }
    	fprintf(f_result, ", Records list: %s", is_page_valid? "Valid": "Invalid");
    	fprintf(f_result, ", Expected records: (%u %lu)", expected_records, mach_read_from_2(page + PAGE_HEADER + PAGE_N_RECS));
    	fprintf(f_result, "\n");
	if (debug) printf("Starting offset: %lu (%lX). Checking %d table definitions.\n", offset, offset, table_definitions_cnt);
	
	// Walk through all possible positions to the end of page 
	// (start of directory - extra bytes of the last rec)
    //is_page_valid = 0;
	while (offset < UNIV_PAGE_SIZE - record_extra_bytes && ( (offset != supremum ) || !is_page_valid) ) {
		// Get record pointer
		origin = page + offset;
		if (debug) printf("\nChecking offset: 0x%lX: ", offset);
		
		// Check all tables
		for (i = 0; i < table_definitions_cnt; i++) {
			// Get table info
			table_def_t *table = &(table_definitions[i]);
			if (debug) printf(" (%s) ", table->name);

			// Check if origin points to a valid record
			if (check_for_a_record(page, origin, table, offsets) && check_constraints(origin, table, offsets)) {
				actual_records++;
				if (debug) printf("\n---------------------------------------------------\n"
			       			  "PAGE%lu: Found a table %s record: %p (offset = %lu)\n", \
						  page_id, table->name, origin, offset);
                		if(is_page_valid){
					process_ibrec(page, origin, table, offsets);
                    			b = mach_read_from_2(page + offset - 2);
					offset = (comp) ? offset + b : b;
                    			}
				else{
					offset += process_ibrec(page, origin, table, offsets);
                    			}
                		if (debug) printf("Next offset: 0x%lX", offset);
			   		break;
		        	}
            		else{
                		if(is_page_valid){
					b = mach_read_from_2(page + offset - 2);
					offset = (comp) ? offset + b : b;
                    			}
				else{
					offset++;
					}
                		if (debug) printf("\nNext offset: %lX", offset);
               			}
			}
		}
	fprintf(f_result, "-- Page id: %lu", page_id);
	fprintf(f_result, ", Found records: %u", actual_records);
	fprintf(f_result, ", Lost records: %s", (actual_records != expected_records) ? "YES": "NO");
    	fprintf(f_result, ", Leaf page: %s", (mach_read_from_2(page + PAGE_HEADER + PAGE_LEVEL) == 0)? "YES": "NO");
	fprintf(f_result, "\n");
}