static void decrease_reservation(struct memop_args *a) { unsigned long i, j; xen_pfn_t gmfn; if ( !guest_handle_subrange_okay(a->extent_list, a->nr_done, a->nr_extents-1) || a->extent_order > max_order(current->domain) ) return; for ( i = a->nr_done; i < a->nr_extents; i++ ) { if ( i != a->nr_done && hypercall_preempt_check() ) { a->preempted = 1; goto out; } if ( unlikely(__copy_from_guest_offset(&gmfn, a->extent_list, i, 1)) ) goto out; if ( tb_init_done ) { struct { u64 gfn; int d:16,order:16; } t; t.gfn = gmfn; t.d = a->domain->domain_id; t.order = a->extent_order; __trace_var(TRC_MEM_DECREASE_RESERVATION, 0, sizeof(t), &t); } /* See if populate-on-demand wants to handle this */ if ( is_hvm_domain(a->domain) && p2m_pod_decrease_reservation(a->domain, gmfn, a->extent_order) ) continue; for ( j = 0; j < (1 << a->extent_order); j++ ) if ( !guest_remove_page(a->domain, gmfn + j) ) goto out; } out: a->nr_done = i; }
static void increase_reservation(struct memop_args *a) { struct page_info *page; unsigned long i; xen_pfn_t mfn; struct domain *d = a->domain; if ( !guest_handle_is_null(a->extent_list) && !guest_handle_subrange_okay(a->extent_list, a->nr_done, a->nr_extents-1) ) return; if ( a->extent_order > max_order(current->domain) ) return; for ( i = a->nr_done; i < a->nr_extents; i++ ) { if ( i != a->nr_done && hypercall_preempt_check() ) { a->preempted = 1; goto out; } page = alloc_domheap_pages(d, a->extent_order, a->memflags); if ( unlikely(page == NULL) ) { gdprintk(XENLOG_INFO, "Could not allocate order=%d extent: " "id=%d memflags=%x (%ld of %d)\n", a->extent_order, d->domain_id, a->memflags, i, a->nr_extents); goto out; } /* Inform the domain of the new page's machine address. */ if ( !guest_handle_is_null(a->extent_list) ) { mfn = page_to_mfn(page); if ( unlikely(__copy_to_guest_offset(a->extent_list, i, &mfn, 1)) ) goto out; } } out: a->nr_done = i; }
void P_adapt(HashTable* HT_Elem_Ptr, HashTable* HT_Node_Ptr, int h_count, double TARGET) { Element* enriched[297200];/*maybe with linked list or creating new arrays while running*/ int counter=0; int i, j, k; Element* EmTemp; Element* Neighbor; Element* EmTemp2; Node* NdTemp; void* p; unsigned* MyKey; unsigned* NeiKey; unsigned* neighbors; int* order; int* neigh_proc; int myid, numprocs; HashEntryPtr entryp; double error; enriched_neighbor* enriched_start=new enriched_neighbor(); enriched_neighbor* enriched_current=enriched_start; enriched_neighbor* enriched_new; MPI_Comm_size(MPI_COMM_WORLD, &numprocs); MPI_Comm_rank(MPI_COMM_WORLD, &myid); htflush(HT_Elem_Ptr, HT_Node_Ptr, 1);/*-- new -> old*/ int e_buckets=HT_Elem_Ptr->get_no_of_buckets(); for(i=0;i<e_buckets;i++)/*-- increase the order of element seperately*/ { entryp = *(HT_Elem_Ptr->getbucketptr() + i); while(entryp) { EmTemp = (Element*)(entryp->value); if(!EmTemp->get_refined_flag()) { error=sqrt(*(EmTemp->get_el_error())); if(error > TARGET) { enriched[counter]=EmTemp; counter++; order = EmTemp->get_order(); for(j=0;j<5;j++) //-- increase order of four sides and bubble if(*(order+j)<MAX_ORDER) EmTemp->put_order(j, *(order+j)+1); } } entryp = entryp->next; } } /*cout<<myid<<" No. of Elements P-adapted: "<<counter<<endl<<flush;*/ printf("%d No. of Elements P-adapted: %d\n",myid,counter); //-- equivalize the order of the common edge of two elems for(i=0; i < counter; i++) { EmTemp=enriched[i]; /*################################################ added by jp on oct12 purpose: update the error of enriched element ###############################################*/ int ord[5]; int ord_max1; int ii, m; for(ii=0;ii<5;ii++) ord[ii] = *(EmTemp->get_order()+ii); max_order(ord, &ord_max1); order = EmTemp->get_order(); neigh_proc = EmTemp->get_neigh_proc(); neighbors = EmTemp->get_neighbors(); MyKey = EmTemp->pass_key(); for(j=0;j<4;j++) { int my_order = *(order+j); if(*(neigh_proc+j) == -1) { p = HT_Node_Ptr->lookup(EmTemp->getNode()+(j+4)*KEYLENGTH); NdTemp = (Node*)p; NdTemp->put_order(*(order+j)); } if(*(neigh_proc+j) == myid) { p = HT_Elem_Ptr->lookup(neighbors+j*KEYLENGTH); Neighbor = (Element*)p; int which_side = Neighbor->which_neighbor(MyKey); if(which_side > 3) which_side +=-4; int neigh_order = *(Neighbor->get_order()+which_side); int final_order = (my_order>=neigh_order) ? my_order:neigh_order; if(EmTemp->get_gen() <= Neighbor->get_gen()) { if(EmTemp->get_gen() < Neighbor->get_gen())//smaller neighbor { assert(*(neigh_proc+j+4)==myid); p = HT_Elem_Ptr->lookup(neighbors+(j+4)*KEYLENGTH); Neighbor = (Element*)p; //which side should remain the same //which_side = Neighbor->which_neighbor(MyKey); assert(Neighbor->which_neighbor(MyKey)==which_side); neigh_order = *(Neighbor->get_order()+which_side); if(neigh_order >= final_order) final_order=neigh_order; else { Neighbor->put_order(which_side, final_order); NdTemp=(Node*)HT_Node_Ptr->lookup(Neighbor->getNode()+(which_side+4)*KEYLENGTH); NdTemp->put_order(final_order); } } Neighbor=(Element*)HT_Elem_Ptr->lookup(neighbors+j*KEYLENGTH); Neighbor->put_order(which_side, final_order); NdTemp=(Node*)HT_Node_Ptr->lookup(Neighbor->getNode()+(which_side+4)*KEYLENGTH); NdTemp->put_order(final_order); EmTemp->put_order(j, final_order); NdTemp=(Node*)HT_Node_Ptr->lookup(EmTemp->getNode()+(j+4)*KEYLENGTH); NdTemp->put_order(final_order); } else if(EmTemp->get_gen() > Neighbor->get_gen()) //lookup the other small elements which has the same neighbor //get the max of the three { int third_order=0; int start; int end; int twin; if(j<3) { start = j; end = j+1;} else { start = 3; end = 0;} p = HT_Node_Ptr->lookup(EmTemp->getNode()+start*KEYLENGTH); NdTemp = (Node*)p; if(NdTemp->getinfo() == S_C_CON) twin = start - 1; else twin = end; if(twin<0) twin = 3; p = HT_Elem_Ptr->lookup(neighbors+twin*KEYLENGTH); EmTemp2 = (Element*)p; assert(EmTemp2); assert(*(EmTemp2->get_neighbors()+j*KEYLENGTH)==*(Neighbor->pass_key()) && *(EmTemp2->get_neighbors()+j*KEYLENGTH+1)==*(Neighbor->pass_key()+1)); third_order=*(EmTemp2->get_order()+j); if(my_order>=neigh_order)final_order=my_order; else final_order=neigh_order; if(third_order>final_order) final_order=third_order; Neighbor->put_order(which_side%4, final_order);//which_side can be > 3 EmTemp->put_order(j, final_order); EmTemp2->put_order(j, final_order); NdTemp=(Node*)HT_Node_Ptr->lookup(Neighbor->getNode()+(which_side%4+4)*KEYLENGTH); NdTemp->put_order(final_order); NdTemp=(Node*)HT_Node_Ptr->lookup(EmTemp->getNode()+(j+4)*KEYLENGTH); NdTemp->put_order(final_order); NdTemp=(Node*)HT_Node_Ptr->lookup(EmTemp2->getNode()+(j+4)*KEYLENGTH); NdTemp->put_order(final_order); } } else if((*(neigh_proc+j)>=0)&&(*(neigh_proc+j)!=myid)) { if(*(EmTemp->get_neigh_gen()+j) < EmTemp->get_gen()) { int start; int end; int twin; if(j<3) { start = j; end = j+1;} else { start = 3; end = 0;} p = HT_Node_Ptr->lookup(EmTemp->getNode()+start*KEYLENGTH); NdTemp = (Node*)p; if(NdTemp->getinfo() == S_C_CON) twin = start - 1; else twin = end; if(twin<0) twin = 3; p = HT_Elem_Ptr->lookup(neighbors+twin*KEYLENGTH); Neighbor = (Element*)p; //assert(Neighbor); //if(!Neighbor) cout<<myid<<" "<<*(neighbors+twin*KEYLENGTH)<<" Neighbor"<<"\n"<<flush; NeiKey = EmTemp->get_neighbors()+j*KEYLENGTH; int flag; for(m=0;m<4;m++) { flag = 1; for(k=0;k<KEYLENGTH;k++) { if( *(Neighbor->get_neighbors()+m*KEYLENGTH+k) != *(NeiKey+k)) { flag = 0; break; } } if(flag) break; } assert(m==j); //assert(flag); //if(!flag) cout<<myid<<" "<<*(NeiKey+k)<<" flag"<<"\n"<<flush; int neigh_order = *(Neighbor->get_order()+m); int my_order = *(order+j); int final_order = (my_order>=neigh_order) ? my_order:neigh_order; EmTemp->put_order(j, final_order); Neighbor->put_order(m, final_order); NdTemp->put_order(final_order);//still the S_C_CON NdTemp=(Node*)HT_Node_Ptr->lookup(EmTemp->getNode()+(j+4)*KEYLENGTH); NdTemp->put_order(final_order); NdTemp=(Node*)HT_Node_Ptr->lookup(Neighbor->getNode()+(m+4)*KEYLENGTH); NdTemp->put_order(final_order); /*inserting the element in the linked list finally*/ /*there might be elements which are not necessary, if two small elements at the interface of a big 1 were enriched but don't care*/ enriched_new=new enriched_neighbor(); enriched_current->next=enriched_new; enriched_new->set_parameters(*(neigh_proc+j), NeiKey, MyKey, final_order); enriched_current=enriched_new; }//if diff.proc and EmTemp is younger else//if EmTemp and its neighbor a.) has same gen. b.)EmTemp is older { NeiKey = EmTemp->get_neighbors()+j*KEYLENGTH; NdTemp=(Node*)HT_Node_Ptr->lookup(EmTemp->getNode()+(j+4)*KEYLENGTH); NdTemp->put_order(*(order+j)); enriched_new=new enriched_neighbor(); enriched_current->next=enriched_new; enriched_new->set_parameters(*(neigh_proc+j), NeiKey, MyKey, *(order+j)); enriched_current=enriched_new; } }//if different proc }//for j=0 j<4 /*################################################ added by jp on oct12 purpose: update the error of enriched element ###############################################*/ for(ii=0;ii<5;ii++) ord[ii] = *(EmTemp->get_order()+ii); int ord_max2; max_order(ord, &ord_max2); int gn; double sl, er; gn = EmTemp->get_gen(); sl = *EmTemp->get_el_solution(); er = *EmTemp->get_el_error(); double hh = 1.0/pow(2,(gn+1)); EmTemp->putel_sq(hh*pow(((double)ord_max1/(double)ord_max2)*sl,2), hh*pow(((double)ord_max1/(double)ord_max2)*er,2)); /*----------------------------------------------------------*/ }//going through all the enriched elements MPI_Barrier(MPI_COMM_WORLD); update_order_interp(HT_Elem_Ptr, HT_Node_Ptr, enriched_start, myid, numprocs); htflush(HT_Elem_Ptr, HT_Node_Ptr, 2); //data_com(HT_Elem_Ptr, HT_Node_Ptr, myid, numprocs, h_count); /*this recalculation should be included in put_order of Element class*/ int hash_size=HT_Elem_Ptr->get_no_of_buckets(); for(i=0;i<hash_size;i++) { entryp = *(HT_Elem_Ptr->getbucketptr() + i); while(entryp) { EmTemp = (Element*)(entryp->value); if(!EmTemp->get_refined_flag()) EmTemp->update_ndof(); entryp = entryp->next; } } }
static void populate_physmap(struct memop_args *a) { struct page_info *page; unsigned int i, j; xen_pfn_t gpfn, mfn; struct domain *d = a->domain; if ( !guest_handle_subrange_okay(a->extent_list, a->nr_done, a->nr_extents-1) ) return; if ( a->extent_order > (a->memflags & MEMF_populate_on_demand ? MAX_ORDER : max_order(current->domain)) ) return; for ( i = a->nr_done; i < a->nr_extents; i++ ) { if ( i != a->nr_done && hypercall_preempt_check() ) { a->preempted = 1; goto out; } if ( unlikely(__copy_from_guest_offset(&gpfn, a->extent_list, i, 1)) ) goto out; if ( a->memflags & MEMF_populate_on_demand ) { if ( guest_physmap_mark_populate_on_demand(d, gpfn, a->extent_order) < 0 ) goto out; } else { if ( is_domain_direct_mapped(d) ) { mfn = gpfn; for ( j = 0; j < (1U << a->extent_order); j++, mfn++ ) { if ( !mfn_valid(mfn) ) { gdprintk(XENLOG_INFO, "Invalid mfn %#"PRI_xen_pfn"\n", mfn); goto out; } page = mfn_to_page(mfn); if ( !get_page(page, d) ) { gdprintk(XENLOG_INFO, "mfn %#"PRI_xen_pfn" doesn't belong to d%d\n", mfn, d->domain_id); goto out; } put_page(page); } mfn = gpfn; page = mfn_to_page(mfn); } else { page = alloc_domheap_pages(d, a->extent_order, a->memflags); if ( unlikely(!page) ) { if ( !opt_tmem || a->extent_order ) gdprintk(XENLOG_INFO, "Could not allocate order=%u extent: id=%d memflags=%#x (%u of %u)\n", a->extent_order, d->domain_id, a->memflags, i, a->nr_extents); goto out; } mfn = page_to_mfn(page); } guest_physmap_add_page(d, gpfn, mfn, a->extent_order); if ( !paging_mode_translate(d) ) { for ( j = 0; j < (1U << a->extent_order); j++ ) set_gpfn_from_mfn(mfn + j, gpfn + j); /* Inform the domain of the new page's machine address. */ if ( unlikely(__copy_to_guest_offset(a->extent_list, i, &mfn, 1)) ) goto out; } } } out: a->nr_done = i; }
/* ap (typ_ap(ap(f,x)), x) = typ (ap(f,x)) */ DEM typ_ap (DEM r) { DEM a, b, c, u, v, w, bz, cz, PIbzcz, bz1, tf, tf1, r1; ORDER o, o1; if (node(r) == _ap) { /* if (subdem(1,r) == z && !in (z, subdem(0,r))) return subdem(0,r); a = typ (z); u = typ (a); */ bz = typ (subdem(1,r)); /* b = fnc (bz); */ /* b = lambda (z, bz); */ /*PIbzcz = typ (subdem(0,r)); cz = arg (PIbzcz);*/ tf = typ (subdem(0,r)); new_tf: if (node(tf) == _ap && node(subdem(0,tf)) == _ap) { if (node(subdem(0,subdem(0,tf))) == _F) { o = order(subdem(0,subdem(0,tf))); bz1 = subdem(1,subdem(0,tf)); /* cz = Kottx (suc_order(o),*U(o)*/ cz = Kttx (typ(subdem(1,tf)), bz1, subdem(1,tf)); goto re; } else if (node(subdem(0,subdem(0,tf))) == _PI) { cz = arg (tf); goto re; } } /* r1 = ap (simplif (subdem(0,r)), subdem(1,r)); if (r1 != r) */ tf1 = simplif (tf); if (tf1 != tf) /*return lambda (z, r1);*/ { tf = tf1; goto new_tf; } /* error ("Bad type of function in lambda", __LINE__, tf); */ return NULL; /* c = fnc (cz); */ /*c = lambda (z, cz);*/ re: return cz; #if 0 c = lambda (z, cz); o1 = max_order (order_u(u), max_order (order_u(typ(bz)), order_u(typ(tf)) )); return Sotttxx (pred_order (o1/*order_u (u)*/), a, b, c, lambda (z, subdem(0,r)), lambda (z, subdem(1,r))); #endif } else { /* error ("typ_ap : bad ap :", __LINE__, r); */ return NULL; /* a = typ (z); b = typ (r); u = typ (a); return Kottx (pred_order (order_u(u)), b, a, r); */ } }