home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * exprofle.c
- *
- * version 1.00, 04-06-1990
- *
- * execution profiler
- *
- * copyright Ferdinand Oeinck 1990
- *
- */
-
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include "h.swis"
- #include "kernel.h"
- #include "h.exproasm"
-
-
- int * funcadr_ptr;
- int * count_ptr;
- int funccount;
- static char * filen;
-
- void myexithandler(void);
-
-
- void exprofle_init(char * filename)
- {
- unsigned int * codestart;
- unsigned int * codeend;
- unsigned int * i;
- int fpestart, fpeend;
- int len, instr, count = 0;
- _kernel_swi_regs regs;
- char * modulename;
-
- if (_kernel_hostos() != _kernel_ARTHUR) {
- printf("Error: Not running on ARTHUR host OS\n");
- exit(1);
- }
- if (!_kernel_fpavailable()) {
- printf("Warning: Execution time profiling not possible.\n");
- printf(" No floating point support.\n");
- return;
- }
- regs.r[0] = 12;
- regs.r[1] = 0;
- regs.r[2] = 0;
- while (_kernel_swi(OS_Module, ®s, ®s) == NULL) {
- modulename = (char*)(regs.r[3] + *((int *)(regs.r[3] + 0x10)));
- if (strcmp(modulename,"FPEmulator") == 0) break;
- }
- fpestart = regs.r[3];
- _kernel_swi(OS_Module, ®s, ®s);
- fpeend = regs.r[3];
-
- if ( (filen = malloc(strlen(filename) + 1)) == NULL) {
- printf("Warning: Execution time profiling not possible.\n");
- printf(" Malloc failed.\n");
- return;
- }
-
- strcpy(filen, filename);
-
- codestart = exproasm_getstart();
- codeend = exproasm_getend();
-
- for (i = codestart; i != codeend; i++) {
- instr = *i & 0xffff0000;
- if (instr == (unsigned int) 0xff000000) {
- len = *i & 0xffff;
- if (len >= strlen((char *)i - len)) count++;
- }
- }
- count += 4;
-
- if ((funcadr_ptr = (int *) calloc(count, sizeof(int))) == NULL) {
- printf("Warning: Execution time profiling not possible.\n");
- printf(" Malloc failed.\n");
- free(filen);
- return;
- }
- if ((count_ptr = (int *) calloc(count, sizeof(int))) == NULL) {
- printf("Warning: Execution time profiling not possible.\n");
- printf(" Malloc failed.\n");
- free(funcadr_ptr);
- free(filen);
- return;
- }
- funccount = count;
-
- count = 1;
- for (i = codestart; i != codeend; i++) {
- instr = *i & 0xffff0000;
- if (instr == (unsigned int) 0xff000000) {
- len = *i & 0xffff;
- if (len >= strlen((char *)i - len)) {
- funcadr_ptr[count++] = (int) i - len;
- }
- }
- }
- funcadr_ptr[count] = (int) codeend;
- funcadr_ptr[count + 1] = (int) fpestart;
- funcadr_ptr[count + 2] = (int) fpeend;
-
- if (!exproasm_ClaimIntDeviceVector()) {
- free(count_ptr);
- free(funcadr_ptr);
- free(filen);
- printf("Warning: Execution time profiling not possible.\n");
- printf(" I think this is not RISC_OS 2.00\n");
- return;
- }
- atexit(myexithandler);
- }
-
- void myexithandler(void)
- {
- int i, sumc = 0;
- float sum = 0, sump = 0;
- FILE *fp;
- exproasm_ReleaseIntDeviceVector();
-
- for (i = 0; i < funccount; i++) sum += count_ptr[i];
- sum = sum - count_ptr[funccount - 2]; /* substract double counted fp values */
- if (sum == 0) sum = 1;
-
- fp = fopen(filen, "w");
-
- fprintf(fp, " nr address function name percentage count\n");
- fprintf(fp, "==========================================================================\n");
-
- fprintf(fp, "%4i %8x: %-40s: %6.2f, %7i\n", 0,
- funcadr_ptr[1], "lessthan", 100.0 * (float) count_ptr[0] / sum, count_ptr[0]);
- sump += (float) 100.0 * (float) count_ptr[0] / sum;
- sumc += count_ptr[0];
-
- for (i = 1 ; i < funccount - 3; i++) {
- fprintf(fp, "%4i %8x: %-40s: %6.2f, %7i\n", i, funcadr_ptr[i],
- (char *)funcadr_ptr[i], 100.0 * (float) count_ptr[i] / sum, count_ptr[i]);
- sump += (float) 100.0 * (float) count_ptr[i] / sum;
- sumc += count_ptr[i];
- }
- fprintf(fp, "%4i %8x: %-40s: %6.2f, %7i\n", funccount-3, funcadr_ptr[funccount-3],
- "greaterthan", 100.0 * (float) count_ptr[funccount-3] / sum,
- count_ptr[funccount-3]);
- sump += (float) 100.0 * (float) count_ptr[funccount-3] / sum;
- sumc += count_ptr[funccount - 3];
-
- fprintf(fp, "==========================================================================\n");
- fprintf(fp, " %6.2f, %7i\n",
- sump, sumc);
- fprintf(fp, "percentage of time spent in fpemulator\n");
- fprintf(fp, "%4i %8x: %-40s: %6.2f, %7i\n", funccount-2, funcadr_ptr[funccount-2],
- "fpemulator", 100.0 * (float) count_ptr[funccount-2] / sum,
- count_ptr[funccount-2]);
-
- fclose(fp);
- free(count_ptr);
- free(funcadr_ptr);
- free(filen);
- }
-
- /* this function is called every 1/100 seconds */
-
- void binsearch(int *adr)
- {
- /* binary search of address table */
- int high = funccount - 1;
- int low = 1;
- extern int expro_fp_return_address;
-
- if ((int) adr < (int) funcadr_ptr[1]) { ++count_ptr[0]; return; }
- if ((int) adr > (int) funcadr_ptr[funccount-2] &&
- (int) adr <= (int) funcadr_ptr[funccount-1]) {
- ++count_ptr[funccount-2]; /* we are in the fpemulator */
- adr = (int*) expro_fp_return_address; /* so use that return address */
- }
- if ((int) adr > (int) funcadr_ptr[funccount-3]) {
- ++count_ptr[funccount-3];
- return;
- }
- while((high - low) > 1){
- int middle = (high + low) / 2;
- if ((int)adr > (int)funcadr_ptr[middle] && (int)adr < (int)funcadr_ptr[middle + 1]) {
- low = middle;
- break;
- }
- if ((int)adr > (int)funcadr_ptr[middle+1])
- low = middle + 1;
- else
- high = middle;
- }
- ++count_ptr[low];
- }
-