/*! * CAAM page allocation: * Allocates a partition from secure memory, with the id * equal to partion_num. This will de-allocate the page * if it is already allocated. The partition will have * full access permissions. The permissions are set before, * running a job descriptor. A memory page of secure RAM * is allocated for the partition. * * @param page Number of the page to allocate. * @param partition Number of the partition to allocate. * @return 0 on success, ERROR_IN_PAGE_ALLOC otherwise */ int caam_page_alloc(uint8_t page_num, uint8_t partition_num) { uint32_t temp_reg; ccsr_sec_t *sec = (void *)CONFIG_SYS_FSL_SEC_ADDR; uint32_t sm_vid = SM_VERSION(sec_in32(&sec->smvid)); uint32_t jr_id = 0; /* * De-Allocate partition_num if already allocated to ARM core */ if (sec_in32(CAAM_SMPO_0) & PARTITION_OWNER(partition_num)) { temp_reg = secmem_set_cmd(PARTITION(partition_num) | CMD_PART_DEALLOC); if (temp_reg & SMCSJR_AERR) { printf("Error: De-allocation status 0x%X\n", temp_reg); return ERROR_IN_PAGE_ALLOC; } } /* set the access rights to allow full access */ sec_out32(CAAM_SMAG1JR(sm_vid, jr_id, partition_num), 0xF); sec_out32(CAAM_SMAG2JR(sm_vid, jr_id, partition_num), 0xF); sec_out32(CAAM_SMAPJR(sm_vid, jr_id, partition_num), 0xFF); /* Now need to allocate partition_num of secure RAM. */ /* De-Allocate page_num by starting with a page inquiry command */ temp_reg = secmem_set_cmd(PAGE(page_num) | CMD_INQUIRY); /* if the page is owned, de-allocate it */ if ((temp_reg & SMCSJR_PO) == PAGE_OWNED) { temp_reg = secmem_set_cmd(PAGE(page_num) | CMD_PAGE_DEALLOC); if (temp_reg & SMCSJR_AERR) { printf("Error: Allocation status 0x%X\n", temp_reg); return ERROR_IN_PAGE_ALLOC; } } /* Allocate page_num to partition_num */ temp_reg = secmem_set_cmd(PAGE(page_num) | PARTITION(partition_num) | CMD_PAGE_ALLOC); if (temp_reg & SMCSJR_AERR) { printf("Error: Allocation status 0x%X\n", temp_reg); return ERROR_IN_PAGE_ALLOC; } /* page inquiry command to ensure that the page was allocated */ temp_reg = secmem_set_cmd(PAGE(page_num) | CMD_INQUIRY); /* if the page is not owned => problem */ if ((temp_reg & SMCSJR_PO) != PAGE_OWNED) { printf("Allocation of page %d in partition %d failed 0x%X\n", temp_reg, page_num, partition_num); return ERROR_IN_PAGE_ALLOC; } return 0; }
static void InheritPartition (ELEMENT *e) { int i; ELEMENT *SonList[MAX_SONS]; if (GetAllSons(e,SonList)==0) { for(i=0; SonList[i]!=NULL; i++) { PARTITION(SonList[i]) = PARTITION(e); InheritPartition(SonList[i]); } } }
int SEL(int *A,int m,int p,int k,int r) { int temp = 0; int n = 0,i = 0,j = 0; if(p - m + 1 <= r) { INSERTIONSORT(A,m,p); return m + k - 1; } while(1) { n = p - m + 1; for(i = 1;i <= n/r;i++) { INSERTIONSORT(A,m + (i - 1) * r,m + i * r - 1); //将中间值收集到A的前部 temp = A[m+i-1]; if(r%2) r++; A[m+i-1] = A[m+(i-1)*r+r/2-1]; A[m+(i-1)*r+r/2-1] = temp; } if((n / r) % 2) j = (n / r) / 2; else j = (n / r) / 2 + 1; j = SEL(A,m,m + n/r - 1,j,r); temp = A[m]; A[m] = A[j]; A[j] = A[m]; j = p + 1; j = PARTITION(A,m,j); if(j - m + 1 == k) return j; else if(j - m + 1 > k) p = j -1; else { k = k - (j - m + 1); m = j + 1; } } }
int RANDOMIZED_PARTITION(int *At, int p, int r) { int i = (int)randBtw(p,r); int tmp = At[r]; At[r] = At[i]; At[i] = tmp; return PARTITION(At,p,r); }
/************************************************************** * Copyright (c) Wuzhiyi * Introduction to Algorithms * * 题目: Chapter 7.3 * 名称: RANDOMIZED-QUICKSORT * 作者: alan-forever * 语言: * 内容摘要: 快速排序随机化版本 * * 修改记录: * 修改日期 版本号 修改人 修改内容 * ------------------------------------------------------------ * 20150708 V1.0 wuzhiyi 创建 **************************************************************/ int RANDOMIZED_PARTITION(int A[], int p, int r) { int i=p+rand()%(r-p+1); int temp=A[r]; A[r]=A[i]; A[i]=temp; return PARTITION(A,p,r); }
void QUICK_SORT(int a[], int p, int r) { if (p<r) { int q = PARTITION(a, p, r); QUICK_SORT(a, p, q - 1); QUICK_SORT(a, q + 1, r); } }
static int Gather_RestrictedPartition (DDD_OBJ obj, void *data, DDD_PROC proc, DDD_PRIO prio) { ELEMENT *theElement = (ELEMENT *)obj; if (EMASTER(theElement)) { PRINTDEBUG(gm,4,(PFMT "Gather_RestrictedPartition(): e=" EID_FMTX "\n", me,EID_PRTX(theElement))) ((int *)data)[0] = PARTITION(theElement); } return(GM_OK); }
static int Scatter_RestrictedPartition (DDD_OBJ obj, void *data, DDD_PROC proc, DDD_PRIO prio) { ELEMENT *theElement = (ELEMENT *)obj; ELEMENT *SonList[MAX_SONS]; int i,partition; if (USED(theElement) && EMASTERPRIO(prio)) { PRINTDEBUG(gm,4,(PFMT "Scatter_ElementRestriction(): restricting sons of e=" EID_FMTX "\n", me,EID_PRTX(theElement))) partition = ((int *)data)[0]; /* send master sons to master element partition */ if (GetSons(theElement,SonList)) RETURN(GM_ERROR); for (i=0; SonList[i]!=NULL; i++) PARTITION(SonList[i]) = partition; } return(GM_OK); }
int NS_DIM_PREFIX BalanceGridRCB (MULTIGRID *theMG, int level) { HEAP *theHeap = theMG->theHeap; GRID *theGrid = GRID_ON_LEVEL(theMG,level); /* balance grid of level */ LB_INFO *lbinfo; ELEMENT *e; int i, son; INT MarkKey; /* distributed grids cannot be redistributed by this function */ if (me!=master && FIRSTELEMENT(theGrid) != NULL) { printf("Error: Redistributing distributed grids using recursive coordinate bisection is not implemented!\n"); return (1); } if (me==master) { if (NT(theGrid) == 0) { UserWriteF("WARNING in BalanceGridRCB: no elements in grid\n"); return (1); } Mark(theHeap,FROM_TOP,&MarkKey); lbinfo = (LB_INFO *) GetMemUsingKey(theHeap, NT(theGrid)*sizeof(LB_INFO), FROM_TOP, MarkKey); if (lbinfo==NULL) { Release(theHeap,FROM_TOP,MarkKey); UserWrite("ERROR in BalanceGridRCB: could not allocate memory from the MGHeap\n"); return (1); } /* construct LB_INFO list */ for (i=0, e=FIRSTELEMENT(theGrid); e!=NULL; i++, e=SUCCE(e)) { lbinfo[i].elem = e; CenterOfMass(e, lbinfo[i].center); } /* apply coordinate bisection strategy */ theRCB(lbinfo, NT(theGrid), 0, 0, DimX, DimY, 0); IFDEBUG(dddif,1) for (e=FIRSTELEMENT(theGrid); e!=NULL; e=SUCCE(e)) { UserWriteF("elem %08x has dest=%d\n", DDD_InfoGlobalId(PARHDRE(e)), PARTITION(e)); } ENDDEBUG for (i=0, e=FIRSTELEMENT(theGrid); e!=NULL; i++, e=SUCCE(e)) { InheritPartition (e); } Release(theHeap,FROM_TOP,MarkKey); } return 0; }
static void theRCB (LB_INFO *theItems, int nItems, int px, int py, int dx, int dy, int dim) { int i, part0, part1, ni0, ni1; static int (*sort_function)(const void *e1, const void *e2); /* determine sort function */ switch (dim) { case 0 : sort_function = sort_rcb_x; break; case 1 : sort_function = sort_rcb_y; break; #ifdef __THREEDIM__ case 2 : sort_function = sort_rcb_z; break; #endif default : printf("%d: theRCB(): ERROR no valid sort dimension specified\n",me); break; } if (nItems==0) return; if ((dx<=1)&&(dy<=1)) { for(i=0; i<nItems; i++) { int dest = py*DimX+px; PARTITION(theItems[i].elem) = dest; } return; } if (dx>=dy) { if (nItems>1) qsort(theItems, nItems, sizeof(LB_INFO), sort_function); part0 = dx/2; part1 = dx-part0; ni0 = (int)(((double)part0)/((double)(dx))*((double)nItems)); ni1 = nItems-ni0; theRCB(theItems, ni0, px, py, part0, dy,(dim+1)%DIM); theRCB(theItems+ni0, ni1, px+part0, py, part1, dy,(dim+1)%DIM); } else { if (nItems>1) qsort(theItems, nItems, sizeof(LB_INFO), sort_function); part0 = dy/2; part1 = dy-part0; ni0 = (int)(((double)part0)/((double)(dy))*((double)nItems)); ni1 = nItems-ni0; theRCB(theItems, ni0, px, py , dx, part0,(dim+1)%DIM); theRCB(theItems+ni0, ni1, px, py+part0, dx, part1,(dim+1)%DIM); } }
INT NS_DIM_PREFIX RestrictPartitioning (MULTIGRID *theMG) { INT i,j; ELEMENT *theElement; ELEMENT *theFather; ELEMENT *SonList[MAX_SONS]; GRID *theGrid; /* reset used flags */ for (i=TOPLEVEL(theMG); i>=0; i--) { theGrid = GRID_ON_LEVEL(theMG,i); for (theElement=PFIRSTELEMENT(theGrid); theElement!=NULL; theElement=SUCCE(theElement)) { SETUSED(theElement,0); } } /* set flags on elements which violate restriction */ for (i=TOPLEVEL(theMG); i>=0; i--) { theGrid = GRID_ON_LEVEL(theMG,i); for (theElement=FIRSTELEMENT(theGrid); theElement!=NULL; theElement=SUCCE(theElement)) { if (GLEVEL(theGrid) == 0) break; if (LEAFELEM(theElement) || USED(theElement)) { theFather = theElement; while (EMASTER(theFather) && ECLASS(theFather)!=RED_CLASS && LEVEL(theFather)>0) { theFather = EFATHER(theFather); } /* if father with red refine class is not master */ /* partitioning must be restricted */ if (!EMASTER(theFather)) { /* the sons of father will be sent to partition of father */ SETUSED(theFather,1); } /* if element is marked for coarsening and father */ /* of element is not master -> restriction is needed */ if (COARSEN(theFather)) { /* level 0 elements are not coarsened */ if (LEVEL(theFather)<=1) continue; if (!EMASTER(EFATHER(theFather))) SETUSED(EFATHER(theFather),1); } } } /* transfer restriction flags to master copies of father */ DDD_IFAOneway(ElementVHIF,GRID_ATTR(theGrid),IF_BACKWARD,sizeof(INT), Gather_ElementRestriction, Scatter_ElementRestriction); } /* send restricted sons to partition of father */ for (i=0; i<=TOPLEVEL(theMG); i++) { theGrid = GRID_ON_LEVEL(theMG,i); /* transfer (new) partitions of elements to non master copies */ DDD_IFAOnewayX(ElementVHIF,GRID_ATTR(theGrid),IF_FORWARD,sizeof(INT), Gather_RestrictedPartition, Scatter_RestrictedPartition); for (theElement=PFIRSTELEMENT(theGrid); theElement!=NULL; theElement=SUCCE(theElement)) { if (!USED(theElement)) continue; /* push partition to the sons */ GetAllSons(theElement,SonList); for (j=0; SonList[j]!=NULL; j++) { SETUSED(SonList[j],1); if (EMASTER(SonList[j])) PARTITION(SonList[j]) = PARTITION(theElement); } } } if (TransferGrid(theMG) != 0) RETURN(GM_FATAL); return(GM_OK); }
void NS_DIM_PREFIX SetGhostObjectPriorities (GRID *theGrid) { ELEMENT *theElement,*theNeighbor,*SonList[MAX_SONS]; NODE *theNode; EDGE *theEdge; VECTOR *theVector; INT i,prio,*proclist,hghost,vghost; /* reset USED flag for objects of ghostelements */ for (theElement=PFIRSTELEMENT(theGrid); theElement!=NULL; theElement=SUCCE(theElement)) { SETUSED(theElement,0); SETTHEFLAG(theElement,0); for (i=0; i<EDGES_OF_ELEM(theElement); i++) { theEdge = GetEdge(CORNER(theElement,CORNER_OF_EDGE(theElement,i,0)), CORNER(theElement,CORNER_OF_EDGE(theElement,i,1))); ASSERT(theEdge != NULL); SETUSED(theEdge,0); SETTHEFLAG(theEdge,0); } if (VEC_DEF_IN_OBJ_OF_GRID(theGrid,SIDEVEC)) for (i=0; i<SIDES_OF_ELEM(theElement); i++) { theVector = SVECTOR(theElement,i); if (theVector != NULL) { SETUSED(theVector,0); SETTHEFLAG(theVector,0); } } } /* to reset also nodes which are at corners of the boundary */ /* reset of nodes need to be done through the node list */ for (theNode=PFIRSTNODE(theGrid); theNode!=NULL; theNode=SUCCN(theNode)) { SETUSED(theNode,0); SETTHEFLAG(theNode,0); SETMODIFIED(theNode,0); } /* set FLAG for objects of horizontal and vertical overlap */ for (theElement=PFIRSTELEMENT(theGrid); theElement!=NULL; theElement=SUCCE(theElement)) { if (PARTITION(theElement) == me) continue; /* check for horizontal ghost */ hghost = 0; for (i=0; i<SIDES_OF_ELEM(theElement); i++) { theNeighbor = NBELEM(theElement,i); if (theNeighbor == NULL) continue; if (PARTITION(theNeighbor) == me) { hghost = 1; break; } } /* check for vertical ghost */ vghost = 0; GetAllSons(theElement,SonList); for (i=0; SonList[i]!=NULL; i++) { if (PARTITION(SonList[i]) == me) { vghost = 1; break; } } /* one or both of vghost and hghost should be true here */ /* except for elements which will be disposed during Xfer */ if (vghost) SETTHEFLAG(theElement,1); if (hghost) SETUSED(theElement,1); for (i=0; i<CORNERS_OF_ELEM(theElement); i++) { theNode = CORNER(theElement,i); if (vghost) SETTHEFLAG(theNode,1); if (hghost) SETUSED(theNode,1); } for (i=0; i<EDGES_OF_ELEM(theElement); i++) { theEdge = GetEdge(CORNER_OF_EDGE_PTR(theElement,i,0), CORNER_OF_EDGE_PTR(theElement,i,1)); ASSERT(theEdge != NULL); if (vghost) SETTHEFLAG(theEdge,1); if (hghost) SETUSED(theEdge,1); } if (VEC_DEF_IN_OBJ_OF_GRID(theGrid,SIDEVEC)) for (i=0; i<SIDES_OF_ELEM(theElement); i++) { theVector = SVECTOR(theElement,i); if (theVector != NULL) { if (vghost) SETTHEFLAG(theVector,1); if (hghost) SETUSED(theVector,1); } } } DEBUG_TIME(0); /* set USED flag for objects of master elements */ /* reset FLAG for objects of master elements */ for (theElement=PFIRSTELEMENT(theGrid); theElement!=NULL; theElement=SUCCE(theElement)) { if (PARTITION(theElement) != me) continue; SETUSED(theElement,0); SETTHEFLAG(theElement,0); for (i=0; i<CORNERS_OF_ELEM(theElement); i++) { theNode = CORNER(theElement,i); SETUSED(theNode,0); SETTHEFLAG(theNode,0); SETMODIFIED(theNode,1); } for (i=0; i<EDGES_OF_ELEM(theElement); i++) { theEdge = GetEdge(CORNER_OF_EDGE_PTR(theElement,i,0), CORNER_OF_EDGE_PTR(theElement,i,1)); ASSERT(theEdge != NULL); SETUSED(theEdge,0); SETTHEFLAG(theEdge,0); } if (VEC_DEF_IN_OBJ_OF_GRID(theGrid,SIDEVEC)) for (i=0; i<SIDES_OF_ELEM(theElement); i++) { theVector = SVECTOR(theElement,i); if (theVector != NULL) { SETUSED(theVector,0); SETTHEFLAG(theVector,0); } } } DEBUG_TIME(0); /* set object priorities for ghostelements */ for (theElement=PFIRSTELEMENT(theGrid); theElement!=NULL; theElement=SUCCE(theElement)) { if (PARTITION(theElement) == me) continue; if (USED(theElement) || THEFLAG(theElement)) { prio = PRIO_CALC(theElement); PRINTDEBUG(gm,1,("SetGhostObjectPriorities(): e=" EID_FMTX " new prio=%d\n", EID_PRTX(theElement),prio)) SETEPRIOX(theElement,prio); if (VEC_DEF_IN_OBJ_OF_GRID(theGrid,ELEMVEC)) { theVector = EVECTOR(theElement); if (theVector != NULL) SETPRIOX(theVector,prio); } } /* set edge priorities */ for (i=0; i<EDGES_OF_ELEM(theElement); i++) { theEdge = GetEdge(CORNER(theElement,CORNER_OF_EDGE(theElement,i,0)), CORNER(theElement,CORNER_OF_EDGE(theElement,i,1))); ASSERT(theEdge != NULL); if (USED(theEdge) || THEFLAG(theEdge)) { PRINTDEBUG(dddif,3,(PFMT " dddif_SetGhostObjectPriorities():" " downgrade edge=" EDID_FMTX " from=%d to PrioHGhost\n", me,EDID_PRTX(theEdge),prio)); EDGE_PRIORITY_SET(theGrid,theEdge,PRIO_CALC(theEdge)); } else EDGE_PRIORITY_SET(theGrid,theEdge,PrioMaster); } #ifdef __THREEDIM__ /* if one(all) of the side nodes is (are) a hghost (vghost) node */ /* then its a hghost (vghost) side vector */ if (VEC_DEF_IN_OBJ_OF_GRID(theGrid,SIDEVEC)) for (i=0; i<SIDES_OF_ELEM(theElement); i++) { if (USED(theVector) || THEFLAG(theVector)) SETPRIOX(theVector,PRIO_CALC(theVector)); } #endif } /* to set also nodes which are at corners of the boundary */ /* set them through the node list */ for (theNode=PFIRSTNODE(theGrid); theNode!=NULL; theNode=SUCCN(theNode)) { /* check if its a master node */ if (USED(theNode) || THEFLAG(theNode)) { PRINTDEBUG(dddif,3,(PFMT " dddif_SetGhostObjectPriorities():" " downgrade node=" ID_FMTX " from=%d to PrioHGhost\n", me,ID_PRTX(theNode),prio)); /* set node priorities of node to ghost */ NODE_PRIORITY_SET(theGrid,theNode,PRIO_CALC(theNode)) } else if (MODIFIED(theNode) == 0)