A specific part of the uvm_physseg implementation written by cherry@ deals
with sorting an array of properties and detecting duplicates.
Original implementation.
/*
* Normalises the passed in Array by sorting the entries and
* looking for duplicates - which is an error.
*
* If a valid array passed in, it is replaced with a normalised and
* sorted version of itself, if the function succeeds.
*/staticboolprops_array_normalise(structuvm_physseg_propprops[UVM_PHYSSEG_TYPE_COUNT]){/* props[] sanity: duplicate properties */structuvm_physseg_proppropstmp[UVM_PHYSSEG_TYPE_COUNT];/* Reset the tmp array to a known state */memset(propstmp,UVM_PHYSSEG_TYPE_INVALID,sizeof(propstmp));enumuvm_physseg_typeupstype;/* Iterate through all passed in properties */for(upstype=0;upstype<UVM_PHYSSEG_TYPE_COUNT&&props[upstype].type!=UVM_PHYSSEG_NONE;upstype++){enumuvm_physseg_typethistype=props[upstype].type;if(propstmp[thistype].type==upstype)/* Duplicate! */returnfalse;/* The above memset() should have worked */KASSERT(propstmp[thistype].type==UVM_PHYSSEG_TYPE_INVALID);propstmp[thistype]=props[upstype];}memcpy(props,propstmp,sizeof(propstmp));returntrue;}
I noticed that in the original implemenation there was only one loop to do
sorting which is not right since sorting needs at least two loops (one nested
inside the other) so I had to make some changes to make it do it’s job
correctly. Hopefully the fix works as expected.
Fixed (hopefully) implemenation.
/*
* Normalises the passed in Array by sorting the entries and
* looking for duplicates - which is an error.
*
* If a valid array passed in, it is replaced with a normalised and
* sorted version of itself, if the function succeeds.
*/staticboolprops_array_normalise(structuvm_physseg_propprops[UVM_PHYSSEG_TYPE_COUNT]){/* props[] sanity: duplicate properties */structuvm_physseg_proppropstmp[UVM_PHYSSEG_TYPE_COUNT];/* Store the original array */structuvm_physseg_proppropsorig[UVM_PHYSSEG_TYPE_COUNT];/* Swap variable */structuvm_physseg_proptemp;/* Reset the tmp array to a known state */memset(propstmp,UVM_PHYSSEG_TYPE_INVALID,sizeof(propstmp));/* Copy the original props[] and save it */memcpy(propsorig,props,sizeof(propsorig));enumuvm_physseg_typei,j;/* Iterate through all passed in properties */for(i=0;i<UVM_PHYSSEG_TYPE_COUNT;i++){if(props[0].type!=UVM_PHYSSEG_NONE){for(j=i+1;j<UVM_PHYSSEG_TYPE_COUNT;j++){if(props[j].type==UVM_PHYSSEG_NONE)continue;/* Invalid properties: Duplicate Properties */if(props[i].type==props[j].type){/* Restore the passed props[] */memcpy(props,propsorig,sizeof(propsorig));returnfalse;}if(props[i].type>props[j].type){temp=props[j];props[j]=props[i];props[i]=temp;}}if(props[i].type!=UVM_PHYSSEG_NONE)propstmp[i]=props[i];}else{propstmp[0]=props[0];break;}}memcpy(props,propstmp,sizeof(propstmp));returntrue;}