void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    bool				isError;
    thread_policy_flavor_t		flavorConstant;
    int					flavorPolicySize, flavorPolicySizeBytes, kernError;
    task_t				threadID;
    thread_policy_t			threadPolicy;
    mach_msg_type_number_t		policySizeFilled;
    boolean_t				isDefault, getDefault;
    char				commandString[COMMAND_STRING_LENGTH];
    // for return structure
    //  ...outer
    const char *outerNames[] = 		{"threadID", "flavor", "policy", "policySize", "policyFillSize", "getDefault", "isDefault"};
    int	numOuterDims=2, numOuterFields=7;
    int	outerDims[2]={1,1};
    //	...inner
    const char *standardNames[] = 	{"no_data"};
    int numInnerFieldsStandard=		1;
    /*
    const char *extendedNames[] = 	{"timeshare"};
    int numInnerFieldsExtended=		1;
    */
    const char *timeConstraintNames[]=	{"period", "computation", "constraint", "preemptible"};
    int numInnerFieldsTimeConstraint=	4;
    const char *precedenceNames[]=	{"imporantance"};
    int numInnerFieldsPrecedence=	1;
    int	numInnerDims=2;
    int	innerDims[2]={1,1};
    // ...both
    mxArray  *tempFieldValue, *innerStruct, *outerStruct;
    

    

    //get the policy flavor constant specified by the user and the getDefault argument
    if(nrhs<2 || nrhs > 2)
        mexErrMsgTxt("MachGetPriorityMex requires two input arguments.  See help MachGetPriorityMex.");
    if(!mxIsChar(prhs[0]))
        mexErrMsgTxt("First input argument is not a string.  See help MachGetPriorityMex.");
    mxGetString(prhs[0], commandString, COMMAND_STRING_LENGTH);
    isError=GetFlavorConstantFromFlavorString(commandString, mxGetM(prhs[0]) * mxGetN(prhs[0]), &flavorConstant);  //case sensitive.  
    if(isError)
        mexErrMsgTxt("Unrecognized command.  See help MachGetPriorityMex.");
    if(!(mxIsDouble(prhs[1]) || mxIsLogical(prhs[1])) || mxGetN(prhs[1]) * mxGetM(prhs[1]) != 1)
        mexErrMsgTxt("Second argument must be 1x1 logical or double value.  See help MachGetPriorityMex.");
    if(mxIsLogical(prhs[1]))
        getDefault= (boolean_t)mxGetLogicals(prhs[1])[0];
    if(mxIsDouble(prhs[1]))
        getDefault= (boolean_t)mxGetPr(prhs[1])[0];


    //read the priority settings
    switch(flavorConstant){
        case THREAD_STANDARD_POLICY: 
            flavorPolicySizeBytes=sizeof(thread_standard_policy_data_t); 
            flavorPolicySize=THREAD_STANDARD_POLICY_COUNT; 
            break;
        case THREAD_TIME_CONSTRAINT_POLICY: 
            flavorPolicySizeBytes=sizeof(thread_time_constraint_policy_data_t); 
            flavorPolicySize=THREAD_TIME_CONSTRAINT_POLICY_COUNT; 
            break;
        case THREAD_PRECEDENCE_POLICY: 
            flavorPolicySizeBytes=sizeof(thread_precedence_policy_data_t); 
            flavorPolicySize=THREAD_PRECEDENCE_POLICY_COUNT; 
            break;
    }
    threadPolicy=(thread_policy_t)malloc(flavorPolicySizeBytes);		
    threadID= mach_thread_self();
    policySizeFilled=flavorPolicySize;
    isDefault=getDefault;
    kernError=thread_policy_get(threadID, flavorConstant, threadPolicy, &policySizeFilled, &isDefault);

    //create and populate the return structure
    outerStruct= mxCreateStructArray(numOuterDims, outerDims, numOuterFields, outerNames);
    
    tempFieldValue= mxCreateDoubleMatrix(1,1,mxREAL);
    mxGetPr(tempFieldValue)[0]=(double)threadID;
    mxSetField(outerStruct, 0, "threadID", tempFieldValue);
    
    tempFieldValue= mxCreateString(commandString);
    mxSetField(outerStruct, 0, "flavor", tempFieldValue);
    
    
    switch(flavorConstant){
        case THREAD_STANDARD_POLICY: 				
            innerStruct= mxCreateStructArray(numInnerDims, innerDims, numInnerFieldsStandard, standardNames);
            tempFieldValue= mxCreateDoubleMatrix(1,1,mxREAL);
            mxGetPr(tempFieldValue)[0]= (double)((thread_standard_policy_t)threadPolicy)->no_data;
            mxSetField(innerStruct, 0, "no_data", tempFieldValue);
            break;
       /* THREAD_EXTENDED_POLICY is equal to THREAD_STANDARD_POLICY.  Also,  THREAD_EXTENDED_POLICY is undocumented.  So we ignore it.  
        case THREAD_EXTENDED_POLICY: 		
            innerStruct= mxCreateStructArray(numInnerDims, innerDims, numInnerFieldsExtended, extendedNames);
            tempFieldValue= mxCreateDoubleMatrix(1,1,mxREAL);
            mxGetPr(tempFieldValue)[0]= (double)((thread_extended_policy_t)threadPolicy)->timeshare;
            mxSetField(innerStruct, 1, "timeshare", tempFieldValue);
            break;
        */
        case THREAD_TIME_CONSTRAINT_POLICY: 	
            innerStruct= mxCreateStructArray(numInnerDims, innerDims, numInnerFieldsTimeConstraint, timeConstraintNames);
            tempFieldValue= mxCreateDoubleMatrix(1,1,mxREAL);
            mxGetPr(tempFieldValue)[0]= (double)((thread_time_constraint_policy_t)threadPolicy)->period;
            mxSetField(innerStruct, 0, "period", tempFieldValue);
            tempFieldValue= mxCreateDoubleMatrix(1,1,mxREAL);
            mxGetPr(tempFieldValue)[0]= (double)((thread_time_constraint_policy_t)threadPolicy)->computation;
            mxSetField(innerStruct, 0, "computation", tempFieldValue);
            tempFieldValue= mxCreateDoubleMatrix(1,1,mxREAL);
            mxGetPr(tempFieldValue)[0]= (double)((thread_time_constraint_policy_t)threadPolicy)->constraint;
            mxSetField(innerStruct, 0, "constraint", tempFieldValue);
            tempFieldValue= mxCreateDoubleMatrix(1,1,mxREAL);
            mxGetPr(tempFieldValue)[0]= (double)((thread_time_constraint_policy_t)threadPolicy)->preemptible;
            mxSetField(innerStruct, 0, "preemptible", tempFieldValue);
            break;
        case THREAD_PRECEDENCE_POLICY:
            innerStruct= mxCreateStructArray(numInnerDims, innerDims, numInnerFieldsPrecedence, precedenceNames);
            tempFieldValue= mxCreateDoubleMatrix(1,1,mxREAL);
            mxGetPr(tempFieldValue)[0]= (double)((thread_precedence_policy_t)threadPolicy)->importance;
            mxSetField(innerStruct, 0, "imporantance", tempFieldValue);
            break;
    }
    mxSetField(outerStruct,0, "policy", innerStruct);
    
    tempFieldValue= mxCreateDoubleMatrix(1,1,mxREAL);
    mxGetPr(tempFieldValue)[0]=flavorPolicySize;
    mxSetField(outerStruct, 0, "policySize", tempFieldValue);
    
    tempFieldValue= mxCreateDoubleMatrix(1,1,mxREAL);
    mxGetPr(tempFieldValue)[0]=policySizeFilled;
    mxSetField(outerStruct, 0, "policyFillSize", tempFieldValue);
    
    tempFieldValue= mxCreateLogicalMatrix(1, 1);
    mxGetLogicals(tempFieldValue)[0]=(bool)getDefault;
    mxSetField(outerStruct, 0, "getDefault", tempFieldValue);
    
    tempFieldValue= mxCreateLogicalMatrix(1, 1);
    mxGetLogicals(tempFieldValue)[0]=(bool)isDefault;
    mxSetField(outerStruct, 0, "isDefault", tempFieldValue);
    
    plhs[0]=outerStruct;
    
    free((void*)threadPolicy);        
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    bool						isError;
    thread_policy_flavor_t		flavorConstant;
    int							kernError;
    task_t						threadID;
    thread_policy_t				threadPolicy;
    mach_msg_type_number_t		policyCount, policyCountFilled;
    boolean_t					isDefault;
    char						commandString[COMMAND_STRING_LENGTH];
    
    
    threadID= mach_thread_self();
    kernError=0;
    
    //get the policy flavor constant specified by the user and the getDefault argument
    if(nrhs<1)
        mexErrMsgTxt("MachGetPriorityMex requires at least one argument.  See help MachGetPriorityMex.");
    if(!mxIsChar(prhs[0]))
        mexErrMsgTxt("First input argument is not a string.  See help MachGetPriorityMex.");
    mxGetString(prhs[0], commandString, COMMAND_STRING_LENGTH);
    isError=GetFlavorConstantFromFlavorString(commandString, mxGetM(prhs[0]) * mxGetN(prhs[0]), &flavorConstant);  //case sensitive.  
    if(isError)
        mexErrMsgTxt("Unrecognized command.  See help MachGetPriorityMex.");


    //branch according to the first argument
    switch(flavorConstant){
        case THREAD_STANDARD_POLICY:
            if(nrhs>2)
                mexErrMsgTxt("Extra argument(s) detected.  See help MachGetPriorityMex.");
            if(nrhs==2){
                if(!mxIsChar(prhs[1]))
                    mexErrMsgTxt("Expecting string in second argument.  See help MachGetPriorityMex.");
                mxGetString(prhs[1], commandString, COMMAND_STRING_LENGTH);
                commandString[COMMAND_STRING_LENGTH-1]= '\0';  //guarantee strcmp an end of string character
                if(strcmp(commandString, "default"))
                    mexErrMsgTxt("Unrecognized second argument.  See help MachGetPriorityMex.");
            }
            threadPolicy=(thread_policy_t)malloc(sizeof(thread_standard_policy_data_t));
            policyCount=THREAD_STANDARD_POLICY_COUNT;
            policyCountFilled=policyCount;
            isDefault=TRUE;
            kernError=thread_policy_get(threadID, THREAD_STANDARD_POLICY, threadPolicy, &policyCountFilled, &isDefault);
            if (kernError==0) kernError=thread_policy_set(threadID, THREAD_STANDARD_POLICY, threadPolicy, policyCountFilled);
            break; 
        case THREAD_TIME_CONSTRAINT_POLICY:
            if(nrhs==1)
                mexErrMsgTxt("Missing argument detected.  See help MachGetPriorityMex.");
            else if(nrhs==2){
                if(!mxIsChar(prhs[1]))
                    mexErrMsgTxt("Expecting string in second argument.  See help MachGetPriorityMex.");
                mxGetString(prhs[1], commandString, COMMAND_STRING_LENGTH);
                commandString[COMMAND_STRING_LENGTH-1]= '\0';  //guarantee strcmp an end of string character
                if(strcmp(commandString, "default"))
                    mexErrMsgTxt("Unrecognized second argument.  See help MachGetPriorityMex.");
                threadPolicy=(thread_policy_t)malloc(sizeof(thread_time_constraint_policy_data_t));
                policyCount=THREAD_TIME_CONSTRAINT_POLICY_COUNT;
                policyCountFilled=policyCount;
                isDefault=TRUE;
                kernError=thread_policy_get(threadID, THREAD_TIME_CONSTRAINT_POLICY, threadPolicy, &policyCountFilled, &isDefault);
                if (kernError==0) kernError=thread_policy_set(threadID, THREAD_TIME_CONSTRAINT_POLICY, threadPolicy, policyCountFilled);
                free((void*)threadPolicy);        
                break;
            }else if(nrhs != 5)
                mexErrMsgTxt("Incorrect number of arguments.  See help MachGetPriorityMex.");
            else{
                if(! (mxIsDouble(prhs[1]) && mxGetM(prhs[1]) * mxGetN(prhs[1]) == 1)) 
                    mexErrMsgTxt("Expected double in second argument.  See help MachSetPriorityMex.");
                if(! (mxIsDouble(prhs[2]) && mxGetM(prhs[2]) * mxGetN(prhs[2]) == 1)) 
                    mexErrMsgTxt("Expected double in third argument.  See help MachSetPriorityMex.");
                if(! (mxIsDouble(prhs[3]) && mxGetM(prhs[3]) * mxGetN(prhs[3]) == 1)) 
                    mexErrMsgTxt("Expected double in fourth argument.  See help MachGetPriorityMex.");
                if(!((mxIsDouble(prhs[4]) || mxIsLogical(prhs[4])) && (mxGetM(prhs[4]) * mxGetN(prhs[4]) == 1)))
                    mexErrMsgTxt("Expected double or logical in fifth argument.  See help MachSetPriorityMex.");
                threadPolicy=(thread_policy_t)malloc(sizeof(thread_time_constraint_policy_data_t));
                ((thread_time_constraint_policy_t)threadPolicy)->period=(uint32_t)mxGetPr(prhs[1])[0];
                ((thread_time_constraint_policy_t)threadPolicy)->computation=(uint32_t)mxGetPr(prhs[2])[0];
                ((thread_time_constraint_policy_t)threadPolicy)->constraint=(uint32_t)mxGetPr(prhs[3])[0];
                ((thread_time_constraint_policy_t)threadPolicy)->preemptible= (boolean_t)(mxIsDouble(prhs[4]) ? mxGetPr(prhs[4])[0] : mxGetLogicals(prhs[4])[0]);
                policyCount=THREAD_TIME_CONSTRAINT_POLICY_COUNT;
                policyCountFilled=policyCount;
                kernError=thread_policy_set(threadID, THREAD_TIME_CONSTRAINT_POLICY, threadPolicy, policyCountFilled);
                free((void*)threadPolicy);
                break;
            }
        case THREAD_PRECEDENCE_POLICY:
            if(nrhs>2)
                mexErrMsgTxt("Extra argument(s) detected.  See help MachGetPriorityMex.");
            if(nrhs<2)
                mexErrMsgTxt("Missing argument detected.  See help MachGetPriorityMex.");
            if(mxIsChar(prhs[1])){  //set the default
                mxGetString(prhs[1], commandString, COMMAND_STRING_LENGTH);
                commandString[COMMAND_STRING_LENGTH-1]= '\0';  //guarantee strcmp an end of string character
                if(strcmp(commandString, "default"))
                    mexErrMsgTxt("Unrecognized second argument.  See help MachGetPriorityMex.");
                threadPolicy=(thread_policy_t)malloc(sizeof(thread_precedence_policy_data_t));
                policyCount=THREAD_PRECEDENCE_POLICY_COUNT;
                policyCountFilled=policyCount;
                isDefault=TRUE;
                kernError=thread_policy_get(threadID, THREAD_PRECEDENCE_POLICY, threadPolicy, &policyCountFilled, &isDefault);
                if (kernError==0) kernError=thread_policy_set(threadID, THREAD_PRECEDENCE_POLICY, threadPolicy, policyCountFilled);
                free((void*)threadPolicy);
                break; 
            }else if(mxIsDouble(prhs[1]) && mxGetM(prhs[1]) * mxGetN(prhs[1]) == 1){  //set a specified value
                threadPolicy=(thread_policy_t)malloc(sizeof(thread_precedence_policy_data_t));
                ((thread_precedence_policy_t)threadPolicy)->importance=(integer_t)mxGetPr(prhs[1])[0];
                policyCount=THREAD_PRECEDENCE_POLICY_COUNT;
                policyCountFilled=policyCount;
                kernError=thread_policy_set(threadID, THREAD_PRECEDENCE_POLICY, threadPolicy, policyCountFilled);
            }
    }

    // Check for and report errors in thread_policy_set:
    if (kernError!=0) {
        mexErrMsgTxt("ERROR: Failed to set requested thread scheduling policy! thread_policy_set() failed!");
    }
}