Exemplo n.º 1
0
kma_page_t* kma_get_page()
{
  void* ptr = master->ptr;
  unsigned int num = GET(ptr); //read the page count currently in master page
  kma_page_t* newpage = get_page(); //request a new page
  void* temp = ptr + WSIZE_11 + num*sizeof(kma_page_t*);
  *(kma_page_t**)temp = newpage; //place the new kma_page_t* in master page
  
  PUT(ptr, ++num); //update page count
  PUT(newpage->ptr, PACK(PAGESIZE,0)); // place block header in the newly allocated page
  
  /* record in the freelist */
  fl_add(newpage->ptr);
  return newpage;
}
Exemplo n.º 2
0
void* kma_split(void* ptr, kma_size_t size) 
{
  	unsigned int blk_size= GETSIZE(ptr);
	unsigned int half = blk_size >> 1;
	
	if (((half - BLKHDR) < size) || (blk_size == MINSIZE)) {
	    // cannot split any more and need to allocate the block; 
            PUT(ptr, PACK(blk_size,1));
	    return ptr;
	}

	// split!
	PUT(ptr, PACK(half,0));  //update header
	void* next_half = ptr+half;
	PUT(next_half, PACK(half,0));  //insert the second header
   	//insert next_half to free list 
	fl_add(next_half); 
 	return kma_split(ptr, size); //recurse
}
Exemplo n.º 3
0
void* kma_coalesce(void* ptr) 
{
  unsigned int size = GETSIZE(ptr);
  
  /* for debugging use
  void* base_addr = BASEADDR(ptr);
  unsigned int offset = (ptr - base_addr)/size;
  printf("%d", offset);
  */

  int bud = WHERE_BUD(ptr, size); //0 if bud on the right, 1 if bud on the left
   

  /* corner condition: size == PAGESIZE */
  if (size == PAGESIZE) return ptr;

  /* find bud location */
  void* bud_addr;
  if (bud) bud_addr = ptr - size; //bud on the left 
  else     bud_addr = ptr + size; //bud on the right  
  
  bool can_coalesce;
  can_coalesce = (!IF_ALLOC(bud_addr)) && (GETSIZE(ptr) == GETSIZE(bud_addr));
  
  if (!can_coalesce) {
	//bud allocated - do nothing,simply return, this is great!
	fl_add(ptr);
  	return ptr;
  }
  //we need to coalesce!  	
  if (bud) {
        fl_remove(bud_addr);
  		PUT(bud_addr, PACK(size<<1,0)); //bud on the left, update bud header
	return kma_coalesce(bud_addr);
  }

  fl_remove(bud_addr); 
  PUT(ptr, PACK(size<<1,0)); //bud on the right, update our header
  return kma_coalesce(ptr); 	
}
Exemplo n.º 4
0
static sCmdArg eval_binOpExp(const sASTNode *node,octa offset,bool *finished) {
	sCmdArg res = {ARGVAL_INT,ORG_EXPR,0,{0}};
	sCmdArg left = eval_get(node->d.binOpExp.left,offset,finished);
	sCmdArg right = eval_get(node->d.binOpExp.right,offset,finished);
	if(left.type == ARGVAL_STR || right.type == ARGVAL_STR)
		cmds_throwEx("Unsupported operation!\n");

	if(left.type == ARGVAL_FLOAT || right.type == ARGVAL_FLOAT) {
		unsigned ex;
		if(left.type != ARGVAL_FLOAT) {
			left.d.integer = fl_floatit(left.d.integer,0,true,false,&ex);
			left.type = ARGVAL_FLOAT;
		}
		if(right.type != ARGVAL_FLOAT) {
			right.d.integer = fl_floatit(right.d.integer,0,true,false,&ex);
			right.type = ARGVAL_FLOAT;
		}

		res.type = ARGVAL_FLOAT;
		switch(node->d.binOpExp.op) {
			case BINOP_ADD:
				res.d.integer = fl_add(left.d.integer,right.d.integer,&ex);
				break;
			case BINOP_SUB:
				res.d.integer = fl_sub(left.d.integer,right.d.integer,&ex);
				break;
			case BINOP_MULU:
			case BINOP_MUL:
				res.d.integer = fl_mult(left.d.integer,right.d.integer,&ex);
				break;
			case BINOP_DIVU:
			case BINOP_DIV:
				res.d.integer = fl_divide(left.d.integer,right.d.integer,&ex);
				break;
			case BINOP_MODU:
			case BINOP_MOD:
				// 2500 makes sure that the remainder can be calculated in one step
				res.d.integer = fl_remstep(left.d.integer,right.d.integer,2500,&ex);
				break;

			case BINOP_AND:
			case BINOP_OR:
			case BINOP_XOR:
			case BINOP_SL:
			case BINOP_SAR:
			case BINOP_SR:
				cmds_throwEx("Unsupported operation!\n");
				break;

			default:
				assert(false);
				break;
		}
	}
	else {
		// note: some of the operations are the same on x86 and mmix. but some of them aren't.
		// therefore, we use the mmix-integer-arithmetic-functions if they are different.
		octa aux;
		switch(node->d.binOpExp.op) {
			case BINOP_ADD:
				res.d.integer = left.d.integer + right.d.integer;
				break;
			case BINOP_SUB:
				res.d.integer = left.d.integer - right.d.integer;
				break;
			case BINOP_MUL:
				res.d.integer = int_smult(left.d.integer,right.d.integer,&aux);
				break;
			case BINOP_MULU:
				res.d.integer = int_umult(left.d.integer,right.d.integer,&aux);
				break;
			case BINOP_DIV:
				res.d.integer = int_sdiv(left.d.integer,right.d.integer,&aux);
				break;
			case BINOP_DIVU:
				res.d.integer = int_udiv(0,left.d.integer,right.d.integer,&aux);
				break;
			case BINOP_MOD:
				int_sdiv(left.d.integer,right.d.integer,&aux);
				res.d.integer = aux;
				break;
			case BINOP_MODU:
				int_udiv(0,left.d.integer,right.d.integer,&aux);
				res.d.integer = aux;
				break;
			case BINOP_AND:
				res.d.integer = left.d.integer & right.d.integer;
				break;
			case BINOP_OR:
				res.d.integer = left.d.integer | right.d.integer;
				break;
			case BINOP_XOR:
				res.d.integer = left.d.integer ^ right.d.integer;
				break;
			case BINOP_SL:
				res.d.integer = int_shiftLeft(left.d.integer,right.d.integer);
				break;
			case BINOP_SAR:
				res.d.integer = int_shiftRightArith(left.d.integer,right.d.integer);
				break;
			case BINOP_SR:
				res.d.integer = int_shiftRightLog(left.d.integer,right.d.integer);
				break;
			default:
				assert(false);
				break;
		}
	}
	if(offset == 0)
		*finished = false;
	return res;
}
Exemplo n.º 5
0
/* Allocates the rel_t object, and adds it to the list in the polygroup if it factored or was a partial.
 * It determines the factors by trial division, and it also adds the factors to the linked list in the
 * rel_t. If it didn't factor and wasn't a partial, the relation is freed.
*/
void construct_relation (mpz_t qx, int32_t x, poly_t *p, nsieve_t *ns){
	ns->tdiv_ct ++;
	rel_t *rel = (rel_t *)(malloc(sizeof(rel_t)));
	if (rel == NULL){
		printf ("Malloc failed\n");
		exit(1);
	}
	rel->poly = p;
	rel->x = x;
	rel->cofactor = 1;
	rel->factors = NULL;
	if (mpz_cmp_ui (qx, 0) < 0){
		fl_add (rel, 0);
	}
	mpz_abs(qx, qx);
	uint64_t q = 0;
	int i;
	while (mpz_divisible_ui_p(qx, 2)){	// handle 2 separately
		mpz_divexact_ui(qx, qx, 2);
		fl_add (rel, 1);
	}
	for (i=1; i < ns->fb_len; i++){
		// instead of doing a multi-precision divisiblilty test, we can use the get_offset method to
		// detect if 'x' is in the arithmetic progression of sieve values divisible by ns->fb[i].
		if (get_offset (ns->fb[i], i, x, 0, p, p->group, ns) == 0 || get_offset (ns->fb[i], i, x, 1, p, p->group, ns) == 0){
			mpz_divexact_ui(qx, qx, ns->fb[i]);
			fl_add (rel, i+1);	// add to the factor list
			// If the result of the division fits in 64 bits, ditch the arbitrary precision.
			if (mpz_fits_64 (qx)) goto fixedprec_tdiv;
			while (mpz_divisible_ui_p (qx, ns->fb[i])){	// the sieve doesn't tell us
				mpz_divexact_ui(qx, qx, ns->fb[i]);	// how many times the factor divided
				fl_add (rel, i+1);
				if (mpz_fits_64 (qx)){
					goto fixedprec_tdiv;
				}
			}
		}
	}
fixedprec_tdiv:
	q = mpz_get_64 (qx);
	if (q < ns->fb[i] * ns->fb[i]){	// q must be prime
		if (q < ns->fb_bound){	// if it's less than the factor base bound, it had better be in the FB.
			fl_add (rel, fb_lookup (q, ns));	// look it up and add it to the list.
			goto add_rel;
		}
		if (q < ns->lp_bound) {	// in this case we have a partial relation.
			rel->cofactor = q;
			goto add_rel;
		}
	}
	while (i < ns->fb_len){		// continue the trial division
		while (q % ns->fb[i] == 0){	// it is no longer efficient to compute offsets here (that 
			q /= ns->fb[i];		// calculation involved mods!)
			fl_add (rel, i+1);
			if (q < ns->fb[i] * ns->fb[i]){
				if (q < ns->fb_bound){
					fl_add (rel, fb_lookup (q, ns));
					goto add_rel;
				}
				if (q < ns->lp_bound) {
					rel->cofactor = q;
					goto add_rel;
				}
			}
		}
		i++;
	}
	// if we're here, we weren't able to do anything with this relation.
//	rel_free (rel);
	return;

add_rel:	// add the relation to the list in the poly_group_t we're working with.
	if (p->group->nrels < PG_REL_STORAGE){
		p->group->relns[ p->group->nrels ] = rel;
		p->group->nrels ++;
		return;
	} else {	// if we ran out of space, just let it go. 
//		rel_free(rel);
		return;
	}
}