Example #1
0
void freef(char *p)
{
  printf("freef called with p=%p\n", (void *) p);
if(p!=0){
   /* you write the  code for the freef function here */
  struct blockl *temp = (struct blockl *)p;
  temp->tag = FREETAG;
  char *temp2 = p;
  temp2 += temp->size;
  temp2 += (TAGSIZE*2);
  struct blockr *temp3 = (struct blockr *)temp2;
  temp3->tag = FREETAG;
  struct blockr *temp4 = (struct blockr *)(p - TAGSIZE);
  //temp4 -= 1;
  if (temp4->tag == FREETAG) {
	struct blockl *temp5 = (struct blockl *)(temp4 - temp4->size-(TAGSIZE));
	coalesce(temp5, temp);	
  }
  else{
	enchain(temp);
  }
  temp2 += TAGSIZE;
  struct blockl *temp6 = (struct blockl *)temp2;
  if (temp6->tag == FREETAG){
	unchain(temp6);
	coalesce(temp, temp6);
  }
}
}
Example #2
0
void freef(void *f)  
{  
   struct blockl *q;  
   struct blockr *r;  
   struct blockl *s;  
  
   char *p = (char *)f;  
   printf("freef called with p=%p\n", p);  
  
   if (p < allocbuf || p > allocbuf + ALLOCSIZE) {  
      printf("freef: bad pointer to block to be freed, %p\n", (void *) p);  
      return;  
   }  
   p = p - TAGSIZE;             /* undo offset added by alloc()  */  
   q = (struct blockl *) p; /* make pointer to struct blockl */  
   if (q->tag != USEDTAG) {  
      printf("freef: block being freed is not in use, %p\n", (void *) p);  
      return;  
   }  
   r = (struct blockr *) (p + q->size - TAGSIZE); /* point to blockr */  
   if (r->tag != USEDTAG) {  
      printf("freef: block being freed is not in use, %p\n", (void *) p);  
      return;  
   }  
   q->tag = (r->tag = FREETAG);  /* set tags to show it is free         */  
   r->size = q->size;          /* set size in blockr                  */  
                 /* look for opportunity to coalesce    */  
                 /* with next lower block               */  
   r = (struct blockr *) (p - TAGSIZE);  
   if ((char *) r >= allocbuf && r->tag == FREETAG) {  
      s =  (struct blockl *) (p - r->size);  
      p = p - r->size;  
      coalesce(s,q);  
      q = s;  
   } else  
   enchain(q);           /* return to the free list             */  
                 /* look for opportunity to coalesce    */  
                 /* with next higher block              */  
   s = (struct blockl *) (p + q->size);  
   if ((char *) s < allocbuf + ALLOCSIZE && s->tag == FREETAG) {  
      unchain(s);  
      coalesce(q,s);  
   }  
} 
Example #3
0
/* 
 * ccw_req_t *ccw_alloc_request ( int cplength, int datasize )
 * allocates a ccw_req_t, that 
 * - can hold a CP of cplength CCWS
 * - can hold additional data up to datasize 
 */
ccw_req_t *
ccw_alloc_request ( char *magic, int cplength, int datasize )
{
	ccw_req_t * request = NULL;
        int size_needed;
	int data_offset, ccw_offset;
	int cachind;

	/* Sanity checks */
	if ( magic == NULL || datasize > PAGE_SIZE ||
	     cplength == 0 || (cplength*sizeof(ccw1_t)) > PAGE_SIZE)
		BUG();
	debug_text_event ( debug_area, 1, "ALLC");
	debug_text_event ( debug_area, 1, magic);
	debug_int_event ( debug_area, 1, cplength);
	debug_int_event ( debug_area, 1, datasize);

	/* We try to keep things together in memory */
	size_needed = (sizeof (ccw_req_t) + 7) & -8;
	data_offset = ccw_offset = 0;
	if (size_needed + datasize <= PAGE_SIZE) {
		/* Keep data with the request */
		data_offset = size_needed;
		size_needed += (datasize + 7) & -8;
	}
	if (size_needed + cplength*sizeof(ccw1_t) <= PAGE_SIZE) {
		/* Keep CCWs with request */
		ccw_offset = size_needed;
		size_needed += cplength*sizeof(ccw1_t);
	}

	/* determine cache index for the requested size */
	for (cachind = 0; cachind < CCW_NUMBER_CACHES; cachind ++ )
	   if ( size_needed < (SMALLEST_SLAB << cachind) ) 
			break;

	/* Try to fulfill the request from a cache */
	if ( ccw_cache[cachind] == NULL )
		BUG();
	request = kmem_cache_alloc ( ccw_cache[cachind], CCW_CACHE_TYPE );
	if (request == NULL)
		return NULL;
	memset ( request, 0, (SMALLEST_SLAB << cachind));
	request->cache = ccw_cache[cachind];

	/* Allocate memory for the extra data */
	if (data_offset == 0) {
		/* Allocated memory for extra data with kmalloc */
	    request->data = (void *) kmalloc(datasize, CCW_CACHE_TYPE );
		if (request->data == NULL) {
			printk(KERN_WARNING PRINTK_HEADER 
			       "Couldn't allocate data area\n");
			kmem_cache_free(request->cache, request);
			return NULL;
		}
	} else
		/* Extra data already allocated with the request */
		request->data = (void *) ((addr_t) request + data_offset);

	/* Allocate memory for the channel program */
	if (ccw_offset == 0) {
		/* Allocated memory for the channel program with kmalloc */
		request->cpaddr = (ccw1_t *) kmalloc(cplength*sizeof(ccw1_t),
						     CCW_CACHE_TYPE);
		if (request->cpaddr == NULL) {
			printk (KERN_DEBUG PRINTK_HEADER
				"Couldn't allocate ccw area\n");
			if (data_offset == 0)
				kfree(request->data);
			kmem_cache_free(request->cache, request);
			return NULL;
		}
	} else
		/* Channel program already allocated with the request */
		request->cpaddr = (ccw1_t *) ((addr_t) request + ccw_offset);

	memset ( request->data, 0, datasize );
	memset ( request->cpaddr, 0, cplength*sizeof(ccw1_t) );
	strncpy ( (char *)(&request->magic), magic, 4);

	ASCEBC((char *)(&request->magic),4);
	request -> cplength = cplength;
	request -> datasize = datasize;
	/* enqueue request to list of allocated requests */
	enchain(request);
	debug_int_event ( debug_area, 1, (long)request);
	return request;
}