Exemplo n.º 1
0
//Add a <key,value> pair to the cache
//If key already exists, overwrite the old value
//If maxmem capacity is exceeded, values will be removed
void cache_set(cache_t cache, _key_t key, val_t val, uint32_t val_size)
{
  cache_real_obj *c = cache->cache;

  //Delete the value if it's already in the cache.
  meta_t old = get_key_loc(cache,key);
  if (old != NULL) cache_delete(cache, key);

  uint64_t available_memory = cache->cache->size - cache_space_used(cache);
  printf("Trying to add a value of size %"PRIu32", with available memory %"PRIu64"\n",val_size,available_memory);
  if (available_memory < val_size)
    {
      printf("   Increasing size.\n");
      defrag(cache, 1); //This doubles the cache size (defragmenting at the same time).
    }
  bucket_timer_up(cache);
  //Create a new meta object and pair it to a slab address, and copy the value over
  meta_t next_meta = create_meta(cache,key,val_size);
  next_meta->address = get_address(c->slab_manager,val_size);
  //enact eviction policy if we need space
  if (next_meta->address == NULL){
    uint32_t val_slab_class = get_slab_class(c->slab_manager, val_size);
    cache_evict(cache, val_slab_class);
    next_meta->address = get_address(c->slab_manager,val_size);
    if (next_meta->address == NULL){
      uint32_t slab_class = get_slab_class(c->slab_manager, val_size);
      printf("Couldn't add a %u-%u byte value because there are no slabs of that range, and no free slabs to be allocated\n",slab_class>>1, slab_class);
      free(next_meta);
      return;
    }
Exemplo n.º 2
0
bool SlottedPage::tryUpdateSlotWithIndirection(uint16_t slotID, char const *dataptr, uint16_t lenInBytes) {
    Slot* s = &slots[slotID];
    if(getFreeSpaceInBytes() >= lenInBytes){
        header.dataStart -= lenInBytes;
        memcpy( &data[header.dataStart], dataptr, lenInBytes);

        s->offset = header.dataStart;
        s->length = lenInBytes;

        setControlbitsToDefault(slotID);
        //here we have completely removed the TID, which was previously stored in this slot
        return true;
    }
    //4. (length is greater than before && space after defrag) -> defrag and insert anywhere on page -> update length & offset
    else if(getFreeSpaceInBytesAfterDefrag() >= lenInBytes){
        defrag();

        header.dataStart -= lenInBytes;
        memcpy( &data[header.dataStart], dataptr, lenInBytes);

        s->offset = header.dataStart;
        s->length = lenInBytes;

        setControlbitsToDefault(slotID);
        //here we have completely removed the TID, which was previously stored in this slot
        return true;
    }
    return false;
}
Exemplo n.º 3
0
void deleteFile(const char *path){
	filereference *ref = getReferenceByPath((char *)path);	
	if(ref == NULL){
		printf("Warning: Trying to delete unexistent file: $%s\n", path);
		return;
	}

	drive->filecount--;
	drive->freespace += ref->size;
	// if the file to be deleted is already the last file in the list
	if(strcmp(drive->files[drive->filecount].name,path) == 0){
		// there is nothing else to be done, decrementing the filecount is enough
		return;
	} 

	// the file is somewhere in the middle or begining of the filelist
	int cnt;
	bool copyahead = false;
	for(cnt = 0; cnt < drive->filecount; cnt++){
		ref = drive->files + cnt;
		if(strcmp(path,ref->name) == 0){// found match
			copyahead = true;
		}
		if(copyahead){
			*ref = drive->files[cnt+1];
		}
	}

	defrag();
}
Exemplo n.º 4
0
void			free(void *ptr)
{
	t_block		*block;
	t_zone		*zone;

	if (!ptr)
		return ;
	pthread_mutex_lock(&g_mutex);
	block = (t_block *)(ptr - HEADER_SIZE);
	if (!block->parent)
	{
		pthread_mutex_unlock(&g_mutex);
		return ;
	}
	block->flag = FREE;
	zone = block->parent;
	zone->blocks_used--;
	zone->size_free += block->size + HEADER_SIZE;
	if (zone->blocks_used <= 0 || zone->type == LARGE_INDEX)
		free_zone(zone);
	else
		defrag(block);
	ptr = NULL;
	pthread_mutex_unlock(&g_mutex);
}
Exemplo n.º 5
0
int spm_alloc(int bytes) {
	assert(spm_used_size + bytes <= spm_size);

	int blocks = bytes/spm_block_size + (bytes%spm_block_size?1:0);
	/* first try */
	int loc = first_fit(blocks);
	if (loc == -1) {
		defrag();
		spm_need_defragment = 1;
	}
	else {
		spm_need_defragment = 0;
	}
	
	/* set the bits of the used blocks */
	loc = first_fit(blocks);
	assert(loc != -1);
	for (int k = 0; k < blocks; k++) {
		set(loc + k);
	}

	spm_used_size += blocks * spm_block_size;
	spm_internal_fragment += spm_block_size - bytes%spm_block_size;
	return loc;
}
Exemplo n.º 6
0
void *malloc(size_t size) {
   Header *curr = freelist, *prev = NULL, *first = NULL;
   int desiredSize = size;

   // 16-divisiblity
   while (size % 16)
      size++;

   // defrag contiguous free blocks then iterate over the freelist
   defrag(); 
   while (curr) {
      if (curr->free && curr->size >= size) {
         // carve out block if free block is big enough
         if (curr->size > size) {
            curr->next = carveHeader(size, curr);
            curr->size = size;
         }

         // if curr->size is equal to desired alloc size only do this
         curr->free = 0;

#if DEBUG_MALLOC
         snprintf(buffer, BUFSIZE, "MALLOC: malloc(%d) => (ptr=%p, size=%d)\n", 
          desiredSize, curr + 1, curr->size); 
         fputs(buffer, stderr);
#endif
         return curr + 1;
      }

      curr = curr->next;
   }

   // extend section break if no blocks are available
   Header *header = sbrk(sizeof(Header) + size);     
   if (header < 0)
      return NULL;

   header->free = 0;
   header->size = size;
   push_back(header);

#if DEBUG_MALLOC
   snprintf(buffer, BUFSIZE, "MALLOC: malloc(%d) => (ptr=%p, size=%d)\n", 
    desiredSize, header + 1, header->size); 
   fputs(buffer, stderr);
#endif

   return header + 1;
}
Exemplo n.º 7
0
int deallocate(void* mem_ptr) {
	size_t i, j;
	size_t heap_pos;
	bool find_flag = false;

	printf("\n --- deallocate ---");

	if (mem_ptr == NULL) {
		printf("\nNULL pointer free().\n");
		return DEALLOC_FAILURE;
	}

	for (i = 0; i < memory->heaps_count; i++) {
		if (mem_ptr == memory->heaps[i].mem_ptr) {
			heap_pos = i;
			find_flag = true;
			for (j = memory->heaps[i].mem_begin; 
				j < memory->heaps[i].mem_end; j++) {
					memory->mem_block[j] = 0;
			}

		}

		if (find_flag == true) {
			break;
		}
	}

	if (find_flag == false) {
		printf("\nNot initialized pointer or double free().\n");
		return DEALLOC_FAILURE;
	}

	memory->allocated_bytes -= memory->heaps[heap_pos].mem_size;
	memory->free_bytes += memory->heaps[heap_pos].mem_size;
	memory->mem_usage.total_free_calls++;
	mem_ptr = NULL;
	zero_heap_data(&(memory->heaps[heap_pos]));
	move_heaps();
	find_free_mem();
	defrag();
	return 0; 
}
Exemplo n.º 8
0
/*
 * Only call on a regular slot (no indirection, not removed!)
 */
bool SlottedPage::tryUpdate(uint16_t slotID, char const *dataptr, uint16_t lenInBytes) {
    Slot* s = &slots[slotID];
    //1. (length is the same) -> insert at the same position
    //& 2. (length is smaller than before) -> insert at the same position  -> update length & fragmented
    if(s->length >= lenInBytes){
        memcpy(&data[s->offset], dataptr, lenInBytes);
        header.fragmentedSpace += s->length - lenInBytes;
        s->length = lenInBytes;
        return true;
    }
    else if( s->length < lenInBytes){
        //3. (length is greater than before && space on page) -> insert anywhere on page -> update length, offset, fragmented
        if(getFreeSpaceInBytes() >= lenInBytes){
            header.fragmentedSpace += s->length;

            header.dataStart -= lenInBytes;
            memcpy( &data[header.dataStart], dataptr, lenInBytes);

            s->offset = header.dataStart;
            s->length = lenInBytes;
            setControlbitsToDefault(slotID);

            return true;
        }
        //4. (length is greater than before && space after defrag) -> defrag and insert anywhere on page -> update length & offset
        else if(getFreeSpaceInBytesAfterDefrag() + s->length >= lenInBytes){
            setControlbitsToRemoved(slotID);
            defrag();

            header.dataStart -= lenInBytes;
            memcpy( &data[header.dataStart], dataptr, lenInBytes);

            s->offset = header.dataStart;
            s->length = lenInBytes;

            setControlbitsToDefault(slotID);
            return true;
        }
    }
    return false;
}
Exemplo n.º 9
0
Arquivo: malloc.c Projeto: 8l/subc
void *malloc(int size) {
	int	*p, *end;
	int	k, n, tries;

	size = (size + sizeof(int) - 1) / sizeof(int);
	if (NULL == _arena) {
		if (size >= THRESHOLD)
			_asize = size + 1;
		else
			_asize = size * OVERALLOC;
		_arena = _sbrk(_asize * sizeof(int));
		if ((int *) -1 == _arena) {
			errno = ENOMEM;
			return NULL;
		}
		_arena[0] = _asize;
		freep = _arena;
	}
	for (tries = 0; tries < 3; tries++) {
		end = _arena + _asize;
		p = freep;
		do {
			if (*p > size) {
				if (size + 1 == *p) {
					*p = -*p;
				}
				else {
					k = *p;
					*p = -(size+1);
					p[size+1] = k - size - 1;
				}
				freep = p;
				return p+1;
			}
			p += abs(*p);
			if (p == end) p = _arena;
			if (p < _arena || p >= end || 0 == *p) {
				_write(2, "malloc(): corrupt arena\n", 24);
				abort();
			}
		} while (p != freep);
		if (0 == tries) {
			defrag();
		}
		else {
			if (size >= THRESHOLD)
				n = size + 1;
			else
				n = size * OVERALLOC;
			if (_sbrk(n * sizeof(int)) == (void *)-1) {
				errno = ENOMEM;
				return NULL;
			}
			k = _asize;
			_asize += n;
			*end = _asize - k;
		}
	}
	errno = ENOMEM;
	return NULL;
}
Exemplo n.º 10
0
int FileSystem::changeSize(fs_pageno newPageCount) {
	bool mustReleaseLock = getLock();
	int result = FILESYSTEM_ERROR;

	// if "newPageCount" is too small, an error is returned
	if ((newPageCount < MIN_PAGE_COUNT) || (newPageCount < getUsedPageCount()) ||
			(newPageCount > MAX_PAGE_COUNT))
		goto endOfChangeSize;

	if (newPageCount < pageCount) {
		// First, defragment the filesystem in order to be able to reduce the size.
		if (defrag() == FILESYSTEM_ERROR)
			goto endOfChangeSize;

		// Then, decrease the size of the filesystem.
		int newPageLayoutSize = (newPageCount + (intsPerPage - 1)) / intsPerPage;

		byte *pageBuffer = (byte*)malloc(pageSize);
		
		// copy page layout data to new position
		for (int i = 0; i < newPageLayoutSize; i++) {
			readPage(pageCount + i, pageBuffer);
			writePage(newPageCount + i, pageBuffer);
		}
		
		// copy file->page mappings to new position
		for (int i = 0; i < fileMappingSize; i++) {
			readPage(pageCount + pageLayoutSize + i, pageBuffer);
			writePage(newPageCount + newPageLayoutSize + i, pageBuffer);
		}

		free(pageBuffer);

		pageCount = newPageCount;
		pageLayoutSize = newPageLayoutSize;

		// write changed preamble to disk
		int32_t pageCountOnDisk = (int32_t)pageCount;
		int32_t pageLayoutSizeOnDisk = (int32_t)pageLayoutSize;
		lseek(dataFile, 2 * INT_SIZE, SEEK_SET);
		forced_write(dataFile, &pageCountOnDisk, INT_SIZE);
		forced_write(dataFile, &pageLayoutSizeOnDisk, INT_SIZE);

		// change the size of the data file
		off_t fileSize = pageSize;
		fileSize *= (newPageCount + newPageLayoutSize + fileMappingSize);
		forced_ftruncate(dataFile, fileSize);
	} // end if (newPageCount < pageCount)

	if (newPageCount > pageCount) {
		// change the size of the data file
		int newPageLayoutSize = (newPageCount + (intsPerPage - 1)) / intsPerPage;
		off_t fileSize = pageSize;
		fileSize *= (newPageCount + newPageLayoutSize + fileMappingSize);
		if (ftruncate(dataFile, fileSize) < 0) {
			fprintf(stderr, "Filesystem size could not be changed.\n");
			perror(NULL);
			goto endOfChangeSize;
		}
		if (getSize() != fileSize) {
			fprintf(stderr, "Filesystem size could not be changed.\n");
			perror(NULL);
			goto endOfChangeSize;
		}

		int oldPageCount = pageCount;
		pageCount = newPageCount;
		int oldPageLayoutSize = pageLayoutSize;
		pageLayoutSize = newPageLayoutSize;

		// write changed preamble to disk
		int32_t pageCountOnDisk = (int32_t)pageCount;
		int32_t pageLayoutSizeOnDisk = (int32_t)pageLayoutSize;
		lseek(dataFile, 2 * INT_SIZE, SEEK_SET);
		forced_write(dataFile, &pageCountOnDisk, INT_SIZE);
		forced_write(dataFile, &pageLayoutSizeOnDisk, INT_SIZE);

		byte *pageBuffer = (byte*)malloc(pageSize);

		// copy file->page mappings to new position
		for (int i = fileMappingSize - 1; i >= 0; i--) {
			readPage(oldPageCount + oldPageLayoutSize + i, pageBuffer);
			writePage(newPageCount + newPageLayoutSize + i, pageBuffer);
		}

		// copy page layout data to new position
		for (int i = oldPageLayoutSize - 1; i >= 0; i--) {
			readPage(oldPageCount + i, pageBuffer);
			writePage(newPageCount + i, pageBuffer);
		}
		// initialize layout data for the new pages
		int32_t unusedValue = UNUSED_PAGE;
		for (int i = 0; i < intsPerPage; i++)
			memcpy(&pageBuffer[i * INT_SIZE], &unusedValue, INT_SIZE);
		for (int i = oldPageLayoutSize; i < newPageLayoutSize; i++)
			 writePage(newPageCount + i, pageBuffer);

		free(pageBuffer);
		
		// update the freePages and freeFileNumbers arrays
		free(freePages); freePages = NULL;
		free(freeFileNumbers); freeFileNumbers = NULL;
		initializeFreeSpaceArrays();
	} // end if (newPageCount > pageCount)

	enableCaching();
	result = FILESYSTEM_SUCCESS;

endOfChangeSize:
	if (mustReleaseLock)
		releaseLock();
	return result;
} // end of changeSize(fs_pageno)
Exemplo n.º 11
0
void *realloc(void *ptr, size_t size) {
   int desiredSize = size;

   // if first argument is NULL, do malloc
   if (!ptr) {
      void *block = malloc(size);

#if DEBUG_MALLOC
      snprintf(buffer, BUFSIZE, "MALLOC: realloc(%p, %d) => (ptr=%p, " 
       "size=%d)\n",
       ptr, desiredSize, block, ((Header *)block)[-1].size);
      fputs(buffer, stderr);
#endif

      return block;
   }
   defrag();

   Header *curr = (Header *)ptr - 1;
   int sum = curr->size;

   // track how much free continguous space we have to do an in-place
   // expansion
   curr = curr->next;
   while (curr && curr->free) {
      sum += curr->size;
      curr = curr->next;
   }

   // 16 divisibility
   while (size % 16)
      size++;

   curr = (Header *)ptr - 1;
   if (sum > size && curr->next) {   // in-place expansion w/o moving sbrk
      Header *oldHeader = curr->next;
      Header *newHeader = (char *)curr + sizeof(Header) + size;
      newHeader->next = oldHeader->next;
      newHeader->size = sum - size;
      newHeader->free = 1;

      curr->next = newHeader;
      curr->size = size;
   }
   else if (sum < size) {
      if (!curr->next) { // in-place expansion w/ moving sbrk
         sbrk(size - curr->size); 
         curr->size = size;
      }
      else {   // malloc new location, copy data
         curr->free = 1;
         char *oldLocation = ++curr;
         char *newLocation = malloc(size);
         
         if (!newLocation) {
            curr->free = 0;
            return NULL;
         }

         memmove(newLocation, oldLocation, curr->size);
         curr = (Header *)newLocation - 1;
      }
   }

#if DEBUG_MALLOC
   snprintf(buffer, BUFSIZE, "MALLOC: realloc(%p, %d) => (ptr=%p, size=%d)\n",
    ptr, desiredSize, curr + 1, curr->size);
   fputs(buffer, stderr);
#endif

   return curr + 1;
}