OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [libiberty/] [mpw.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/* 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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.