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!"); } }