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); } } }
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); } }
/* * 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; }