]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - libiberty/mpw.c
19990502 sourceware import
[thirdparty/binutils-gdb.git] / libiberty / mpw.c
1 /* MPW-Unix compatibility library.
2 Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
3
4 This file is part of the libiberty library.
5 Libiberty is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 Libiberty is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with libiberty; see the file COPYING.LIB. If
17 not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. */
19
20 /* This should only be compiled and linked under MPW. */
21
22 #include "mpw.h"
23
24 #include <stdlib.h>
25
26 #ifndef USE_MW_HEADERS
27 #include <sys/time.h>
28 #include <sys/resource.h>
29 #endif
30
31 #include <Types.h>
32 #include <Files.h>
33
34 #include <Timer.h>
35
36 /* Initialize to 0 at first, then set to errno_max() later. */
37
38 int sys_nerr = 0;
39
40 /* Debug flag for pathname hacking. Set this to one and rebuild. */
41
42 int DebugPI = -1;
43
44 void
45 mpwify_filename(char *unixname, char *macname)
46 {
47 int i, j;
48
49 /* (should truncate 255 chars from end of name, not beginning) */
50 if (strlen (unixname) > 255)
51 {
52 fprintf (stderr, "Pathname \"%s\" is too long for Macs, truncating\n",
53 unixname);
54 }
55 j = 0;
56 /* If you're going to end up with one or more colons in the middle of a
57 path after an all-Unix relative path is translated, you must add a
58 colon on the front, so that the first component is not thought to be
59 a disk name. */
60 if (unixname[0] != '/' && ! strchr (unixname, ':') && strchr (unixname, '/'))
61 {
62 macname[j++] = ':';
63 }
64 for (i = 0; unixname[i] != '\0' && i < 255; ++i)
65 {
66 if (i == 0 && unixname[i] == '/')
67 {
68 if (strncmp (unixname, "/tmp/", 5) == 0)
69 {
70 /* A temporary name, make a more Mac-flavored tmpname. */
71 /* A better choice would be {Boot}Trash:foo, but
72 that would require being able to identify the
73 boot disk's and trashcan's name. Another option
74 would be to have an env var, so user can point it
75 at a ramdisk. */
76 macname[j++] = ':';
77 macname[j++] = 't';
78 macname[j++] = 'm';
79 macname[j++] = 'p';
80 macname[j++] = '_';
81 i += 4;
82 }
83 else
84 {
85 /* Don't copy the leading slash. */
86 }
87 }
88 else if (unixname[i] == ':' && unixname[i+1] == '/')
89 {
90 macname[j++] = ':';
91 i += 1;
92 }
93 else if (unixname[i] == '.' && unixname[i+1] == '/')
94 {
95 macname[j++] = ':';
96 i += 1;
97 }
98 else if (unixname[i] == '.' && unixname[i+1] == '.' && unixname[i+2] == '/')
99 {
100 macname[j++] = ':';
101 macname[j++] = ':';
102 i += 2;
103 }
104 else if (unixname[i] == '/')
105 {
106 macname[j++] = ':';
107 }
108 else
109 {
110 macname[j++] = unixname[i];
111 }
112 }
113 macname[j] = '\0';
114 /* Allow for getting the debug flag from an env var; quite useful. */
115 if (DebugPI < 0)
116 DebugPI = (*(getenv ("DEBUG_PATHNAMES")) == '1' ? 1 : 0);
117 if (DebugPI)
118 {
119 fprintf (stderr, "# Made \"%s\"\n", unixname);
120 fprintf (stderr, "# into \"%s\"\n", macname);
121 }
122 }
123
124 /* MPW-flavored basename finder. */
125
126 char *
127 mpw_basename (name)
128 char *name;
129 {
130 char *base = name;
131
132 while (*name)
133 {
134 if (*name++ == ':')
135 {
136 base = name;
137 }
138 }
139 return base;
140 }
141
142 /* Mixed MPW/Unix basename finder. This can be led astray by
143 filenames with slashes in them and come up with a basename that
144 either corresponds to no file or (worse) to some other file, so
145 should only be tried if other methods of finding a file via a
146 basename have failed. */
147
148 char *
149 mpw_mixed_basename (name)
150 char *name;
151 {
152 char *base = name;
153
154 while (*name)
155 {
156 if (*name == '/' || *name == ':')
157 {
158 base = name + 1;
159 }
160 ++name;
161 }
162 return base;
163 }
164
165 /* This function is fopen() modified to create files that are type TEXT
166 or 'BIN ', and always of type 'MPS '. */
167
168 FILE *
169 mpw_fopen (char *name, char *mode)
170 {
171 #undef fopen
172 int errnum;
173 FILE *fp;
174 char tmpname[256];
175
176 mpwify_filename (name, tmpname);
177 PROGRESS (1);
178 fp = fopen (tmpname, mode);
179 errnum = errno;
180
181 /* If writing, need to set type and creator usefully. */
182 if (strchr (mode, 'w'))
183 {
184 char *pname = (char *) malloc (strlen (tmpname) + 2);
185 OSErr e;
186 struct FInfo fi;
187
188 pname[0] = strlen (tmpname);
189 strcpy (pname+1, tmpname);
190
191 e = GetFInfo ((ConstStr255Param) pname, 0, &fi);
192 /* should do spiffier error handling */
193 if (e != 0)
194 fprintf(stderr, "GetFInfo returns %d\n", e);
195 if (strchr (mode, 'b'))
196 {
197 fi.fdType = (OSType) 'BIN ';
198 }
199 else
200 {
201 fi.fdType = (OSType) 'TEXT';
202 }
203 fi.fdCreator = (OSType) 'MPS ';
204 e = SetFInfo ((ConstStr255Param) pname, 0, &fi);
205 if (e != 0)
206 fprintf(stderr, "SetFInfo returns %d\n", e);
207 free (pname);
208 }
209 if (fp == NULL)
210 errno = errnum;
211 return fp;
212 }
213
214 /* This is a version of fseek() modified to fill the file with zeros
215 if seeking past the end of it. */
216
217 #define ZEROBLKSIZE 4096
218
219 char zeros[ZEROBLKSIZE];
220
221 int
222 mpw_fseek (FILE *fp, int offset, int whence)
223 {
224 #undef fseek
225 int cursize, numleft;
226
227 PROGRESS (1);
228 if (whence == SEEK_SET)
229 {
230 fseek (fp, 0, SEEK_END);
231 cursize = ftell (fp);
232 if (offset > cursize)
233 {
234 numleft = offset - cursize;
235 while (numleft > ZEROBLKSIZE)
236 {
237 /* This might fail, should check for that. */
238 PROGRESS (1);
239 fwrite (zeros, 1, ZEROBLKSIZE, fp);
240 numleft -= ZEROBLKSIZE;
241 }
242 PROGRESS (1);
243 fwrite (zeros, 1, numleft, fp);
244 fflush (fp);
245 }
246 }
247 return fseek (fp, offset, whence);
248 }
249
250 int
251 mpw_fread (char *ptr, int size, int nitems, FILE *stream)
252 {
253 #undef fread
254 int rslt;
255
256 PROGRESS (1);
257 rslt = fread (ptr, size, nitems, stream);
258 PROGRESS (1);
259 return rslt;
260 }
261
262 int
263 mpw_fwrite (char *ptr, int size, int nitems, FILE *stream)
264 {
265 #undef fwrite
266 int rslt;
267
268 PROGRESS (1);
269 rslt = fwrite (ptr, size, nitems, stream);
270 PROGRESS (1);
271 return rslt;
272 }
273
274 int
275 link ()
276 {
277 fprintf (stderr, "link not available!\n");
278 mpw_abort ();
279 }
280
281 int
282 fork ()
283 {
284 fprintf (stderr, "fork not available!\n");
285 mpw_abort ();
286 }
287
288 int
289 vfork ()
290 {
291 fprintf (stderr, "vfork not available!\n");
292 mpw_abort ();
293 return (-1);
294 }
295
296 int
297 pipe (int *fd)
298 {
299 fprintf (stderr, "pipe not available!\n");
300 mpw_abort ();
301 return (-1);
302 }
303
304 #ifndef USE_MW_HEADERS
305 int
306 execvp (char *file, char **argv)
307 {
308 fprintf (stderr, "execvp not available!\n");
309 mpw_abort ();
310 return (-1);
311 }
312
313 int
314 execv (char *path, char **argv)
315 {
316 fprintf (stderr, "execv not available!\n");
317 mpw_abort ();
318 return (-1);
319 }
320 #endif
321
322 int
323 kill (int pid, int sig)
324 {
325 fprintf (stderr, "kill not available!\n");
326 mpw_abort ();
327 return (-1);
328 }
329
330 int
331 wait (int *status)
332 {
333 *status = 0;
334 return 0;
335 }
336
337 #ifndef USE_MW_HEADERS
338 int
339 sleep (int seconds)
340 {
341 unsigned long start_time, now;
342
343 time (&start_time);
344
345 while (1)
346 {
347 PROGRESS (1);
348 time (&now);
349 if (now > start_time + seconds)
350 return 0;
351 }
352 }
353 #endif
354
355 void
356 putenv (char *str)
357 {
358 /* The GCC driver calls this to do things for collect2, but we
359 don't care about collect2. */
360 }
361
362 int
363 chmod (char *path, int mode)
364 {
365 /* Pretend it was all OK. */
366 return 0;
367 }
368
369 #ifndef USE_MW_HEADERS
370 int
371 getuid ()
372 {
373 /* One value is as good as another... */
374 return 0;
375 }
376
377 int
378 getgid ()
379 {
380 /* One value is as good as another... */
381 return 0;
382 }
383 #endif
384
385 /* Instead of coredumping, which is not a normal Mac facility, we
386 drop into Macsbug. If we then "g" from Macsbug, the program will
387 exit cleanly. */
388
389 void
390 mpw_abort ()
391 {
392 /* Make sure no output still buffered up, then zap into MacsBug. */
393 fflush(stdout);
394 fflush(stderr);
395 printf("## Abort! ##\n");
396 #ifdef MPW_SADE
397 SysError(8005);
398 #else
399 Debugger();
400 #endif
401 /* "g" in MacsBug will then cause a regular error exit. */
402 exit (1);
403 }
404
405 /* Imitation getrusage based on the ANSI clock() function. */
406
407 int
408 getrusage (int who, struct rusage *rusage)
409 {
410 int clk = clock ();
411
412 #if 0
413 rusage->ru_utime.tv_sec = clk / CLOCKS_PER_SEC;
414 rusage->ru_utime.tv_usec = ((clk * 1000) / CLOCKS_PER_SEC) * 1000;
415 rusage->ru_stime.tv_sec = 0;
416 rusage->ru_stime.tv_usec = 0;
417 #endif
418 }
419
420 int
421 sbrk ()
422 {
423 return 0;
424 }
425
426 #ifndef USE_MW_HEADERS
427 int
428 isatty (int fd)
429 {
430 return 0;
431 }
432
433 /* This is inherited from Timothy Murray's Posix library. */
434
435 #include "utime.h"
436
437 int
438 utime (char *filename, struct utimbuf *times)
439 {
440 CInfoPBRec cipbr;
441 HFileInfo *fpb = (HFileInfo *) &cipbr;
442 DirInfo *dpb = (DirInfo *) &cipbr;
443 unsigned char pname[256];
444 short err;
445
446 strcpy ((char *) pname, filename);
447 c2pstr (pname);
448
449 dpb->ioDrDirID = 0L;
450 fpb->ioNamePtr = pname;
451 fpb->ioVRefNum = 0;
452 fpb->ioFDirIndex = 0;
453 fpb->ioFVersNum = 0;
454 err = PBGetCatInfo (&cipbr, 0);
455 if (err != noErr) {
456 errno = ENOENT;
457 return -1;
458 }
459 dpb->ioDrDirID = 0L;
460 fpb->ioFlMdDat = times->modtime;
461 fpb->ioFlCrDat = times->actime;
462 err = PBSetCatInfo (&cipbr, 0);
463 if (err != noErr) {
464 errno = EACCES;
465 return -1;
466 }
467 return 0;
468 }
469
470 int
471 mkdir (char *path, int mode)
472 {
473 errno = ENOSYS;
474 return -1;
475 }
476
477 int
478 rmdir ()
479 {
480 errno = ENOSYS;
481 return -1;
482 }
483 #endif
484
485 chown ()
486 {
487 errno = ENOSYS;
488 return -1;
489 }
490
491 char *myenviron[] = {NULL};
492
493 char **environ = myenviron;
494
495 #ifndef USE_MW_HEADERS
496
497 /* Minimal 'stat' emulation: tells directories from files and
498 gives length and mtime.
499
500 Derived from code written by Guido van Rossum, CWI, Amsterdam
501 and placed by him in the public domain. */
502
503 extern int __uid, __gid;
504
505 int __uid = 0;
506 int __gid = 0;
507
508 /* Bits in ioFlAttrib: */
509 #define LOCKBIT (1<<0) /* File locked */
510 #define DIRBIT (1<<4) /* It's a directory */
511
512 /* Macified "stat" in which filename is given relative to a directory,
513 specified by long DirID. */
514
515 static int
516 _stat (char *name, long dirid, struct stat *buf)
517 {
518 CInfoPBRec cipbr;
519 HFileInfo *fpb = (HFileInfo*) &cipbr;
520 DirInfo *dpb = (DirInfo*) &cipbr;
521 Str255 pname;
522 short err;
523
524 /* Make a temp copy of the name and pascalize. */
525 strcpy ((char *) pname, name);
526 c2pstr (pname);
527
528 cipbr.dirInfo.ioDrDirID = dirid;
529 cipbr.hFileInfo.ioNamePtr = pname;
530 cipbr.hFileInfo.ioVRefNum = 0;
531 cipbr.hFileInfo.ioFDirIndex = 0;
532 cipbr.hFileInfo.ioFVersNum = 0;
533 err = PBGetCatInfo (&cipbr, 0);
534 if (err != noErr)
535 {
536 errno = ENOENT;
537 return -1;
538 }
539 /* Mac files are readable if they can be accessed at all. */
540 buf->st_mode = 0444;
541 /* Mark unlocked files as writeable. */
542 if (!(fpb->ioFlAttrib & LOCKBIT))
543 buf->st_mode |= 0222;
544 if (fpb->ioFlAttrib & DIRBIT)
545 {
546 /* Mark directories as "executable". */
547 buf->st_mode |= 0111 | S_IFDIR;
548 buf->st_size = dpb->ioDrNmFls;
549 buf->st_rsize = 0;
550 }
551 else
552 {
553 buf->st_mode |= S_IFREG;
554 /* Mark apps as "executable". */
555 if (fpb->ioFlFndrInfo.fdType == 'APPL')
556 buf->st_mode |= 0111;
557 /* Fill in the sizes of data and resource forks. */
558 buf->st_size = fpb->ioFlLgLen;
559 buf->st_rsize = fpb->ioFlRLgLen;
560 }
561 /* Fill in various times. */
562 buf->st_atime = fpb->ioFlCrDat;
563 buf->st_mtime = fpb->ioFlMdDat;
564 buf->st_ctime = fpb->ioFlCrDat;
565 /* Set up an imitation inode number. */
566 buf->st_ino = (unsigned short) fpb->ioDirID;
567 /* Set up an imitation device. */
568 GetVRefNum (buf->st_ino, &buf->st_dev);
569 buf->st_uid = __uid;
570 buf->st_gid = __gid;
571 /* buf->st_FlFndrInfo = fpb->ioFlFndrInfo; */
572 return 0;
573 }
574
575 /* stat() sets up an empty dirid. */
576
577 int
578 stat (char *path, struct stat *buf)
579 {
580 long rslt, errnum;
581 char tmpname[256];
582
583 mpwify_filename (path, tmpname);
584 if (DebugPI)
585 fprintf (stderr, "# stat (%s, %x)", tmpname, buf);
586 PROGRESS (1);
587 rslt = _stat (tmpname, 0L, buf);
588 errnum = errno;
589 if (DebugPI)
590 {
591 fprintf (stderr, " -> %d", rslt);
592 if (rslt != 0)
593 fprintf (stderr, " (errno is %d)", errnum);
594 fprintf (stderr, "\n");
595 fflush (stderr);
596 }
597 if (rslt != 0)
598 errno = errnum;
599 return rslt;
600 }
601
602 int
603 fstat (int fd, struct stat *buf)
604 {
605 FCBPBRec fcb;
606 FILE *fp;
607 Str255 pathname;
608 long dirid = 0L, temp;
609 long rslt, errnum;
610 short err;
611
612 if (DebugPI < 0)
613 DebugPI = (*(getenv ("DEBUG_PATHNAMES")) == '1' ? 1 : 0);
614 if (DebugPI)
615 fprintf (stderr, "# fstat (%d, %x)", fd, buf);
616 PROGRESS (1);
617 pathname[0] = 0;
618 #ifdef FIOFNAME
619 /* Use an MPW-specific ioctl to get the pathname associated with
620 the file descriptor. */
621 ioctl (fd, FIOFNAME, (long *) pathname);
622 #else
623 you lose
624 #endif
625 if (DebugPI)
626 fprintf (stderr, " (name is %s)", pathname);
627 dirid = 0L /* fcb.ioFCBParID */ ;
628 rslt = _stat ((char *) pathname, dirid, buf);
629 errnum = errno;
630 if (DebugPI)
631 {
632 fprintf (stderr, " -> %d", rslt);
633 if (rslt != 0)
634 fprintf (stderr, " (errno is %d)", errnum);
635 fprintf (stderr, "\n");
636 fflush (stderr);
637 }
638 if (rslt != 0)
639 errno = errnum;
640 return rslt;
641 }
642
643 #endif /* n USE_MW_HEADERS */
644
645 chdir ()
646 {
647 errno = ENOSYS;
648 return (-1);
649 }
650
651 char *
652 getcwd (char *buf, int size)
653 {
654 if (buf == NULL)
655 buf = (char *) malloc (size);
656 strcpy(buf, ":");
657 return buf;
658 }
659
660 /* This should probably be more elaborate for MPW. */
661
662 char *
663 getpwd ()
664 {
665 return ":";
666 }
667
668 int
669 mpw_open (char *filename, int arg2, int arg3)
670 {
671 #undef open
672 int fd, errnum = 0;
673 char tmpname[256];
674
675 mpwify_filename (filename, tmpname);
676 fd = open (tmpname, arg2);
677 errnum = errno;
678
679 if (DebugPI)
680 {
681 fprintf (stderr, "# open (%s, %d, %d)", tmpname, arg2, arg3);
682 fprintf (stderr, " -> %d", fd);
683 if (fd == -1)
684 fprintf (stderr, " (errno is %d)", errnum);
685 fprintf (stderr, "\n");
686 }
687 if (fd == -1)
688 errno = errnum;
689 return fd;
690 }
691
692 int
693 mpw_access (char *filename, unsigned int cmd)
694 {
695 #undef access
696
697 int rslt, errnum = 0;
698 struct stat st;
699 char tmpname[256];
700
701 mpwify_filename (filename, tmpname);
702 if (cmd & R_OK || cmd & X_OK)
703 {
704 rslt = stat (tmpname, &st);
705 errnum = errno;
706 if (rslt >= 0)
707 {
708 if ((((st.st_mode & 004) == 0) && (cmd & R_OK))
709 || (((st.st_mode & 002) == 0) && (cmd & W_OK))
710 || (((st.st_mode & 001) == 0) && (cmd & X_OK)))
711 {
712 rslt = -1;
713 errnum = EACCES;
714 }
715 }
716 }
717 if (DebugPI)
718 {
719 fprintf (stderr, "# mpw_access (%s, %d)", tmpname, cmd);
720 fprintf (stderr, " -> %d", rslt);
721 if (rslt != 0)
722 fprintf (stderr, " (errno is %d)", errnum);
723 fprintf (stderr, "\n");
724 }
725 if (rslt != 0)
726 errno = errnum;
727 return rslt;
728 }
729
730 /* The MPW library creat() has no mode argument. */
731
732 int
733 mpw_creat (char *path, /* mode_t */ int mode)
734 {
735 #undef creat
736
737 #ifdef USE_MW_HEADERS
738 return creat (path, mode);
739 #else
740 return creat (path);
741 #endif
742 }
743
744 /* This is a hack to get control in an MPW tool before it crashes the
745 machine. */
746
747 mpw_special_init (name)
748 char *name;
749 {
750 if (strstr (name, "DEBUG"))
751 DebugStr("\pat beginning of program");
752 }
753
754 static int current_umask;
755
756 int
757 umask(int mask)
758 {
759 int oldmask = current_umask;
760
761 current_umask = mask;
762 return oldmask;
763 }
764
765 /* Cursor-spinning stuff that includes metering of spin rate and delays. */
766
767 /* Nonzero when cursor spinning has been set up properly. */
768
769 int cursor_inited;
770
771 /* Nonzero if spin should be measured and excessive delays reported. */
772
773 int measure_spin;
774
775 /* Nonzero if spin histogram and rate data should be written out. */
776
777 int dump_spin_data;
778
779 long warning_threshold = 400000;
780
781 long bucket_size = 1024;
782
783 long bucket_power = 10;
784
785 long numbuckets = 300;
786
787 int *delay_counts;
788
789 int overflow_count;
790
791 char *current_progress;
792
793 static UnsignedWide last_microseconds;
794
795 static char *last_spin_file = "";
796
797 static int last_spin_line;
798
799 void
800 warn_if_spin_delay (char *file, int line)
801 {
802 long diff, ix;
803 UnsignedWide now;
804
805 Microseconds(&now);
806
807 diff = now.lo - last_microseconds.lo;
808
809 if (diff > warning_threshold)
810 fprintf (stderr, "# %s: %ld.%06ld sec delay getting from %s:%d to %s:%d\n",
811 (current_progress ? current_progress : ""),
812 diff / 1000000, diff % 1000000,
813 last_spin_file, last_spin_line, file, line);
814 if (dump_spin_data)
815 {
816 if (diff >= 0)
817 {
818 ix = diff >> bucket_power;
819 if (ix >= 0 && ix < numbuckets && delay_counts != NULL)
820 ++delay_counts[ix];
821 else
822 ++overflow_count;
823 }
824 else
825 fprintf (stderr, "raw diff is %ld (?)\n", diff);
826 }
827 }
828
829 void
830 record_for_spin_delay (char *file, int line)
831 {
832 Microseconds (&last_microseconds);
833 last_spin_file = file;
834 last_spin_line = line;
835 }
836
837 void
838 mpw_start_progress (char *str, int n, char *file, int line)
839 {
840 int i;
841 char *measure, *threshold;
842
843 if (!cursor_inited)
844 {
845 InitCursorCtl (nil);
846 cursor_inited = 1;
847 record_for_spin_delay (file, line);
848 measure = getenv ("MEASURE_SPIN");
849 if (measure != NULL && measure[0] != '\0')
850 {
851 measure_spin = 1;
852 if (strcmp (measure, "all") == 0)
853 dump_spin_data = 1;
854 }
855 threshold = getenv ("SPIN_WARN_THRESHOLD");
856 if (threshold != NULL && threshold[0] != '\0')
857 warning_threshold = atol (threshold);
858 if (dump_spin_data)
859 {
860 if (delay_counts == NULL)
861 delay_counts = (int *) malloc (numbuckets * sizeof (int));
862 for (i = 0; i < numbuckets; ++i)
863 delay_counts[i] = 0;
864 overflow_count = 0;
865 }
866 }
867 current_progress = str;
868
869 sys_nerr = errno_max ();
870
871 mpw_special_init (str);
872 }
873
874 void
875 mpw_progress (int n)
876 {
877 SpinCursor (32);
878 }
879
880 void
881 mpw_progress_measured (int n, char *file, int line)
882 {
883 if (measure_spin)
884 warn_if_spin_delay (file, line);
885 SpinCursor (32);
886 if (measure_spin)
887 record_for_spin_delay (file, line);
888 }
889
890 void
891 mpw_end_progress (char *str, char *file, int line)
892 {
893 long i, delay, count = 0, sum = 0, avgdelay, spinrate;
894 long curpower = 0, curgroup = 0;
895
896 /* Warn if it's been a while since the last spin. */
897 if (measure_spin)
898 warn_if_spin_delay (file, line);
899
900 /* Dump all the nonzero delay counts and an approximation of the delay. */
901 if (dump_spin_data && delay_counts != NULL)
902 {
903 for (i = 0; i < numbuckets; ++i)
904 {
905 delay = (i + 1) * bucket_size;
906 sum += delay_counts[i] * (i + 1);
907 count += delay_counts[i];
908 if (delay <= (1 << curpower))
909 {
910 curgroup += delay_counts[i];
911 }
912 else
913 {
914 if (curgroup > 0)
915 fprintf (stderr,
916 "# %s: %d delays between %ld.%06ld and %ld.%06ld sec\n",
917 (str ? str : ""),
918 curgroup,
919 (1 << curpower) / 1000000,
920 (1 << curpower) % 1000000,
921 (1 << (curpower + 1)) / 1000000,
922 (1 << (curpower + 1)) % 1000000);
923 ++curpower;
924 curgroup = 0;
925 }
926 }
927 if (count > 0)
928 {
929 avgdelay = (sum * bucket_size) / count;
930 spinrate = 1000000 / avgdelay;
931 fprintf (stderr, "# %s: Average spin rate is %d times/sec\n",
932 (str ? str : ""), spinrate);
933 }
934 }
935 }
936
937 #ifdef PROGRESS_TEST
938
939 /* Test program. */
940
941 main ()
942 {
943 int i, j;
944 double x = 1.0, y = 2.4;
945 long start = Microseconds (), tm; FIXME
946
947 START_PROGRESS ("hi", 0);
948
949 for (i = 0; i < 1000; ++i)
950 {
951 PROGRESS (1);
952
953 for (j = 0; j < (i * 100); ++j)
954 {
955 x += (x * y) / j;
956 }
957 }
958
959 END_PROGRESS ("hi");
960
961 tm = Microseconds () - start;
962
963 printf ("Total time is %d.%d secs\n", tm / 1000000, tm % 1000000);
964 }
965
966 #endif
967
968 #ifdef USE_MW_HEADERS
969 /* Empty definitions for Metrowerks' SIOUX console library. */
970
971 #ifndef __CONSOLE__
972 #include <console.h>
973 #endif
974
975 short
976 InstallConsole(short fd)
977 {
978 #pragma unused (fd)
979 return 0;
980 }
981
982 void
983 RemoveConsole(void)
984 {
985 }
986
987 long
988 WriteCharsToConsole(char *buf, long n)
989 {
990 #pragma unused (buf, n)
991 return 0;
992 }
993
994 long ReadCharsFromConsole(char *buf, long n)
995 {
996 #pragma unused (buf, n)
997 return 0;
998 }
999
1000 extern char *
1001 __ttyname(long fd)
1002 {
1003 static char *__devicename = "null device";
1004
1005 if (fd >= 0 && fd <= 2)
1006 return (__devicename);
1007 return NULL;
1008 }
1009
1010 #endif