Skip to content

Commit 725d331

Browse files
committed
Introduce buffered I/O and replace getc with buffered read
This commit introduces 32k buffer for file I/O operations and 32k buffer for fgetc() replacemnt routines. Some performance gain is observed and 'perf' trace does not show getc operations at all, shifting the burden to actual I/O system routines. In order to improve performance of these, 32k buffer is attached to every opened file by calling setvbuf() function. Due to suspicious way of passing pointers around in flang runtime, all of the I/O buffers had to be allocated statically. In order to prevent memory bloat, only limited number of simultaneously opened files will be buffered, file descriptor ID is used for buffer selection which is a thread-safe solution. Signed-off-by: Paul Osmialowski <[email protected]>
1 parent 6a5cc79 commit 725d331

File tree

18 files changed

+351
-168
lines changed

18 files changed

+351
-168
lines changed

runtime/flang/backspace.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,21 +74,24 @@ _f90io_backspace(__INT_T *unit, __INT_T *bitv, __INT_T *iostat, int swap_bytes)
7474

7575
if (f->nonadvance) {
7676
f->nonadvance = FALSE;
77+
FIO_FCB_INVALIDATE_GETC_BUFFER(f, return __io_errno());
7778
#if defined(WINNT)
78-
if (__fortio_binary_mode(f->fp))
79-
__io_fputc('\r', f->fp);
79+
if (__fortio_binary_mode(f->__io_fp))
80+
__io_fputc('\r', f->__io_fp);
8081
#endif
81-
__io_fputc('\n', f->fp);
82-
if (__io_ferror(f->fp))
82+
__io_fputc('\n', f->__io_fp);
83+
if (__io_ferror(f->__io_fp))
8384
return __io_errno();
8485
}
8586

86-
fp = f->fp;
8787
/* if already at the beginning just return without error */
8888
/* if (f->nextrec < 2) */
89-
if (__io_ftell(fp) == 0) /* use ftell in case file opened 'append' */
89+
if (FIO_FCB_FTELL(f) == 0) /* use ftell in case file opened 'append' */
9090
return 0;
9191

92+
FIO_FCB_INVALIDATE_GETC_BUFFER(f, return __fortio_error(__io_errno()));
93+
fp = f->__io_fp;
94+
9295
if (f->form == FIO_UNFORMATTED) { /* CASE 1: unformatted file */
9396
int reclen;
9497
/* variable length record is stored as length:record:length

runtime/flang/close.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,16 @@ __fortio_close(FIO_FCB *f, int flag)
4747
if (f->nonadvance) {
4848
f->nonadvance = FALSE;
4949
#if defined(WINNT)
50-
if (__fortio_binary_mode(f->fp))
51-
__io_fputc('\r', f->fp);
50+
if (__fortio_binary_mode(f->__io_fp))
51+
__io_fputc('\r', f->__io_fp);
5252
#endif
53-
__io_fputc('\n', f->fp);
54-
if (__io_ferror(f->fp))
53+
__io_fputc('\n', f->__io_fp);
54+
if (__io_ferror(f->__io_fp))
5555
return __io_errno();
5656
}
5757

5858
if (!f->stdunit) {
59-
if (__io_fclose(f->fp) != 0) {
59+
if (__io_fclose(f->__io_fp) != 0) {
6060
return __fortio_error(__io_errno());
6161
}
6262
if (flag == 0 && f->dispose == FIO_DELETE)
@@ -79,7 +79,7 @@ __fortio_close(FIO_FCB *f, int flag)
7979
#if defined(TARGET_OSX)
8080
if (f->unit != 5 && f->unit != -5)
8181
#endif
82-
if (__io_fflush(f->fp) != 0)
82+
if (__io_fflush(f->__io_fp) != 0)
8383
return __fortio_error(__io_errno());
8484
}
8585

@@ -201,10 +201,10 @@ __fortio_cleanup(void)
201201
* consequently, need to extract the 'next' field now.
202202
*/
203203
f_next = f->next;
204-
if (f->fp == NULL) { /* open? */
204+
if (f->__io_fp == NULL) { /* open? */
205205
continue;
206206
}
207-
__io_fflush(f->fp);
207+
__io_fflush(f->__io_fp);
208208
if (f->stdunit) { /* standard unit? */
209209
continue;
210210
}

runtime/flang/error.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -443,10 +443,11 @@ __fortio_error(int errval)
443443
}
444444

445445
fioFcbTbls.error = TRUE;
446-
if (fdesc && fdesc->fp && fdesc->acc == FIO_DIRECT) {
446+
if (fdesc && fdesc->__io_fp && fdesc->acc == FIO_DIRECT) {
447447
/* leave file in consistent state: */
448448
fdesc->nextrec = 1;
449-
__io_fseek(fdesc->fp, 0L, SEEK_SET);
449+
FIO_FCB_INVALIDATE_GETC_BUFFER_BEFORE_FSEEK(fdesc);
450+
__io_fseek(fdesc->__io_fp, 0L, SEEK_SET);
450451
}
451452

452453
if ((iobitv & FIO_BITV_EOR) && (errval == FIO_ETOOBIG)) {
@@ -837,7 +838,7 @@ win_set_binary(FIO_FCB *f)
837838
{
838839
FILE *fil;
839840

840-
fil = f->fp;
841+
fil = f->__io_fp;
841842
if (!__fort_isatty(__fort_getfd(fil))) {
842843
__fortio_setmode_binary(fil);
843844
}
@@ -863,7 +864,7 @@ __fortio_init(void)
863864
/* preconnect stdin as unit -5 for * unit specifier */
864865
f = __fortio_alloc_fcb();
865866

866-
f->fp = __io_stdin();
867+
f->__io_fp = __io_stdin();
867868
f->unit = -5;
868869
f->name = "stdin ";
869870
f->reclen = 0;
@@ -894,7 +895,7 @@ __fortio_init(void)
894895
/* preconnect stdout as unit -6 for * unit specifier */
895896
f = __fortio_alloc_fcb();
896897

897-
f->fp = __io_stdout();
898+
f->__io_fp = __io_stdout();
898899
f->unit = -6;
899900
f->name = "stdout ";
900901
f->reclen = 0;
@@ -925,7 +926,7 @@ __fortio_init(void)
925926
/* preconnect stdin as unit 5 */
926927
f = __fortio_alloc_fcb();
927928

928-
f->fp = __io_stdin();
929+
f->__io_fp = __io_stdin();
929930
f->unit = 5;
930931
f->name = "stdin ";
931932
f->reclen = 0;
@@ -956,7 +957,7 @@ __fortio_init(void)
956957
/* preconnect stdout as unit 6 */
957958
f = __fortio_alloc_fcb();
958959

959-
f->fp = __io_stdout();
960+
f->__io_fp = __io_stdout();
960961
f->unit = 6;
961962
f->name = "stdout ";
962963
f->reclen = 0;
@@ -987,7 +988,7 @@ __fortio_init(void)
987988
/* preconnect stderr as unit 0 */
988989
f = __fortio_alloc_fcb();
989990

990-
f->fp = __io_stderr();
991+
f->__io_fp = __io_stderr();
991992
f->unit = 0;
992993
f->name = "stderr ";
993994
f->reclen = 0;

runtime/flang/flush.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ __INT_T *iostat;
5454
}
5555
}
5656

57-
if (__io_fflush(f->fp) != 0) {
57+
if (__io_fflush(f->__io_fp) != 0) {
5858
s = __fortio_error(__io_errno());
5959
__fortio_errend03();
6060
return s;

runtime/flang/fmtread.c

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3221,7 +3221,7 @@ fr_read_record(void)
32213221
g->rec_buff += g->rec_len; /* point to next record */
32223222
} else { /* external file */
32233223
FIO_FCB *f = g->fcb;
3224-
FILE *fp = f->fp;
3224+
32253225
if (f->pread) {
32263226
int idx = 0;
32273227
char *p = f->pread;
@@ -3230,7 +3230,7 @@ fr_read_record(void)
32303230
while (TRUE) { /* read one char per iteration until '\n' */
32313231
int c = *(p++);
32323232
if (c == EOF) {
3233-
if (__io_feof(fp)) {
3233+
if (__io_feof(f->__io_fp)) {
32343234
if (idx)
32353235
break;
32363236
return FIO_EEOF;
@@ -3264,15 +3264,18 @@ fr_read_record(void)
32643264
if (f->acc == FIO_DIRECT) {
32653265
if (f->nextrec > f->maxrec + 1)
32663266
return FIO_EDREAD; /* attempt to read non-existent rec */
3267-
if (__io_fread(g->rec_buff, 1, g->rec_len, fp) != g->rec_len)
3267+
FIO_FCB_INVALIDATE_GETC_BUFFER(f, return __io_errno());
3268+
if (__io_fread(g->rec_buff, 1, g->rec_len, f->__io_fp) != g->rec_len)
32683269
return __io_errno();
32693270
} else { /* sequential read */
32703271
idx = 0;
32713272

32723273
while (TRUE) { /* read one char per iteration until '\n' */
3273-
int c = __io_fgetc(fp);
3274+
int c;
3275+
3276+
FIO_FCB_BUFFERED_GETC(c, f, return __io_errno());
32743277
if (c == EOF) {
3275-
if (__io_feof(fp)) {
3278+
if (__io_feof(f->__io_fp)) {
32763279
if (idx)
32773280
break;
32783281
if (g->nonadvance && !g->eor_seen && g->rec_len != 0)
@@ -3284,12 +3287,12 @@ fr_read_record(void)
32843287
return __io_errno();
32853288
}
32863289
if (c == '\r' && EOR_CRLF) {
3287-
c = __io_fgetc(fp);
3290+
FIO_FCB_BUFFERED_GETC(c, f, return __io_errno());
32883291
if (c == '\n') {
32893292
g->eor_len = 2;
32903293
break;
32913294
}
3292-
__io_ungetc(c, fp);
3295+
FIO_FCB_BUFFERED_UNGETC(c, f);
32933296
c = '\r';
32943297
}
32953298
if (c == '\n') {
@@ -3382,7 +3385,7 @@ _f90io_fmtr_end(void)
33823385
int i;
33833386
i = g->rec_len - g->curr_pos + g->eor_len;
33843387
--(g->fcb->nextrec); /* decr errmsg recnum */
3385-
if (__io_fseek(g->fcb->fp, (seekoffx_t)-i, SEEK_CUR) != 0) {
3388+
FIO_FCB_FSEEK_CUR(g->fcb, (seekoffx_t)-i, {
33863389
if (g->fcb->stdunit) {
33873390
/*
33883391
* Can't seek stdin, but need to leave the postion
@@ -3393,7 +3396,7 @@ _f90io_fmtr_end(void)
33933396
return 0;
33943397
}
33953398
return __fortio_error(__io_errno());
3396-
}
3399+
});
33973400
}
33983401
}
33993402
}

runtime/flang/fmtwrite.c

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2617,40 +2617,45 @@ fw_write_record(void)
26172617
FIO_FCB *f = g->fcb;
26182618

26192619
if (f->acc == FIO_DIRECT) {
2620-
if (FWRITE(g->rec_buff, 1, g->rec_len, f->fp) != (int)g->rec_len)
2620+
FIO_FCB_INVALIDATE_GETC_BUFFER(f, return __io_errno());
2621+
if (FWRITE(g->rec_buff, 1, g->rec_len, f->__io_fp) != (int)g->rec_len)
26212622
return __io_errno();
26222623
} else { /* sequential write */
26232624
if (g->nonadvance) {
26242625
if (g->curr_pos >= g->max_pos) {
26252626
g->max_pos = g->curr_pos;
26262627
fw_check_size(g->max_pos);
2627-
if (FWRITE(g->rec_buff, 1, g->max_pos, f->fp) != (int)g->max_pos)
2628+
FIO_FCB_INVALIDATE_GETC_BUFFER(f, return __io_errno());
2629+
if (FWRITE(g->rec_buff, 1, g->max_pos, f->__io_fp) != (int)g->max_pos)
26282630
return __io_errno();
26292631
} else if (g->curr_pos < g->max_pos) {
26302632
long len = g->max_pos - g->curr_pos;
26312633

2632-
if (FWRITE(g->rec_buff, 1, g->curr_pos, f->fp) != (int)g->curr_pos)
2634+
FIO_FCB_INVALIDATE_GETC_BUFFER(f, return __io_errno());
2635+
if (FWRITE(g->rec_buff, 1, g->curr_pos, f->__io_fp) != (int)g->curr_pos)
26332636
return __io_errno();
26342637
g->fcb->skip = len;
26352638
g->fcb->skip_buff = malloc(len);
26362639
memcpy(g->fcb->skip_buff, &g->rec_buff[g->curr_pos], len);
26372640
}
26382641
f->nonadvance = TRUE; /* do it later */
26392642
} else {
2640-
if (FWRITE(g->rec_buff, 1, g->max_pos, f->fp) != (int)g->max_pos)
2643+
FIO_FCB_INVALIDATE_GETC_BUFFER(f, return __io_errno());
2644+
if (FWRITE(g->rec_buff, 1, g->max_pos, f->__io_fp) != (int)g->max_pos)
26412645
return __io_errno();
26422646
f->nonadvance = FALSE; /* do it now */
26432647
if (!(g->suppress_crlf)) {
2648+
FIO_FCB_INVALIDATE_GETC_BUFFER(f, return __io_errno());
26442649
/* append carriage return */
26452650
#if defined(WINNT)
2646-
if (__fortio_binary_mode(f->fp))
2647-
__io_fputc('\r', f->fp);
2651+
if (__fortio_binary_mode(f->__io_fp))
2652+
__io_fputc('\r', f->__io_fp);
26482653
#endif
26492654
/* if (g->max_pos > 0)*/
2650-
__io_fputc('\n', f->fp);
2651-
if (__io_ferror(f->fp))
2655+
__io_fputc('\n', f->__io_fp);
2656+
if (__io_ferror(f->__io_fp))
26522657
return __io_errno();
2653-
} else if (fflush(f->fp) != 0)
2658+
} else if (fflush(f->__io_fp) != 0)
26542659
return __io_errno();
26552660
}
26562661
}

runtime/flang/fstat3f.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ int ENT3F(FSTAT, fstat)(int *lu, int *statb)
3535

3636
f = __fio_find_unit(*lu);
3737
if (f && !FIO_FCB_STDUNIT(f)) {
38-
/* need a way to get f->fp's fildes */
38+
/* need a way to get f->__io_fp's fildes */
3939
if (i = _stat32(FIO_FCB_NAME(f), &b))
4040
i = __io_errno();
4141
} else {
@@ -78,7 +78,7 @@ int ENT3F(FSTAT, fstat)(int *lu, int *statb)
7878

7979
f = __fio_find_unit(*lu);
8080
if (f && !FIO_FCB_STDUNIT(f)) {
81-
/** need a way to get f->fp's fildes **/
81+
/** need a way to get f->__io_fp's fildes **/
8282
if ((i = stat(FIO_FCB_NAME(f), &b)))
8383
i = __io_errno();
8484
} else {

runtime/flang/fstat643f.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ int ENT3F(FSTAT64, fstat64)(int *lu, long long *statb)
5959

6060
f = __fio_find_unit(*lu);
6161
if (f && !FIO_FCB_STDUNIT(f)) {
62-
/** need a way to get f->fp's fildes **/
62+
/** need a way to get f->__io_fp's fildes **/
6363
if (i = _stat64(FIO_FCB_NAME(f), bp))
6464
i = __io_errno();
6565
} else {
@@ -102,7 +102,7 @@ int ENT3F(FSTAT64, fstat64)(int *lu, long long *statb)
102102

103103
f = __fio_find_unit(*lu);
104104
if (f && !FIO_FCB_STDUNIT(f)) {
105-
/** need a way to get f->fp's fildes **/
105+
/** need a way to get f->__io_fp's fildes **/
106106
if ((i = stat(FIO_FCB_NAME(f), &b)))
107107
i = __io_errno();
108108
} else {

0 commit comments

Comments
 (0)