Skip to content

Commit de6e163

Browse files
committed
[optimization] printf and puts should print full string as one syscall
1 parent 6645759 commit de6e163

File tree

4 files changed

+78
-30
lines changed

4 files changed

+78
-30
lines changed

src/kernel/syscall/console.c

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,30 @@
44

55
#include <lib/utils/output.h>
66

7-
int _console_putchar(char c) {
7+
#define CONSOLE_PUTS_BUFFER_SIZE 128
8+
9+
static int _console_putchar(char c) {
810
print_char(c);
911
return 0;
1012
}
1113

12-
int _console_clrscr() {
14+
static int _console_puts_buffer(int user_ds, const char *__us_str, int len) {
15+
char str[CONSOLE_PUTS_BUFFER_SIZE]={0};
16+
while (len > 0) {
17+
int sub_len = min(CONSOLE_PUTS_BUFFER_SIZE, len);
18+
syscall_strncpy_user_to_kernel(user_ds, __us_str, str, sub_len);
19+
20+
for(int i=0;i<sub_len;i++) {
21+
print_char(str[i]);
22+
}
23+
24+
len -= sub_len;
25+
__us_str += sub_len;
26+
}
27+
return 0;
28+
}
29+
30+
static int _console_clrscr() {
1331
print_rectangle(0, 0, TEXT_WINDOW_WIDTH-1, TEXT_WINDOW_HEIGHT-1);
1432
move_xy(0,0);
1533
}
@@ -20,7 +38,10 @@ int syscall_3_console(int operation, int a1, int a2, int a3, int user_ds) {
2038
return _console_clrscr();
2139
case SYSCALL_CONSOLE_SUB_PUTCHAR:
2240
return _console_putchar((char)a1);
41+
case SYSCALL_CONSOLE_SUB_PUTS_BUFFER:
42+
return _console_puts_buffer(user_ds, (const char*)a1, a2);
2343
}
2444
return -1;
2545
}
2646

47+
#undef CONSOLE_PUTS_BUFFER_SIZE

src/usr/include/stdio.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@
44

55
#define SYSCALL_CONSOLE_SUB_CLRSCR 0
66
#define SYSCALL_CONSOLE_SUB_PUTCHAR 1
7+
#define SYSCALL_CONSOLE_SUB_PUTS_BUFFER 2
78

89
int putchar(int c);
910
int puts(const char *s);
11+
12+
int snprintf(char *s, size_t n, const char *fmt, ...);
1013
int printf(const char *strfmt, ...);
1114

1215
char* gets (char *s);

src/usr/lib/stdio.c

Lines changed: 50 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -12,63 +12,86 @@ int putchar(int c) {
1212

1313
int puts(const char *s) {
1414
if(!s) return 0;
15-
int c = 0;
16-
while ((*s)!='\0') {
17-
putchar(*(s++));
18-
c++;
19-
}
20-
return c;
15+
int len = strlen(s);
16+
return SYSCALL_A3(SYSCALL_CONSOLE, SYSCALL_CONSOLE_SUB_PUTS_BUFFER, s, len);
2117
}
2218

23-
int printf(const char *fmt, ...) {
24-
int len = 0;
25-
int rv = 0;
26-
va_list args;
27-
va_start(args, fmt);
28-
for(;rv >= 0 && (*fmt)!='\0' ; fmt++) {
19+
static int vsnprintf(char *s, size_t n, const char *fmt, va_list args) {
20+
if(n==0) return 0;
21+
if(n==1) {
22+
s[0]='\0';
23+
return 0;
24+
}
25+
n--; // count non-null char
26+
27+
size_t len = 0;
28+
int err = 0;
29+
for(;err >= 0 && len<n && (*fmt)!='\0' ; fmt++) {
2930
if((*fmt)!='%') {
30-
putchar((*fmt));
31-
len++;
31+
s[len++] = (*fmt);
3232
continue;
3333
}
3434
fmt++;
3535
if((*fmt)=='\0') break;
3636

3737
// formatting options
3838
switch(*fmt) {
39+
char *innerstr;
3940
char sbuffer[68];
4041
case '%':
41-
putchar('%');
42-
len++;
42+
s[len++]='%';
4343
break;
4444
case 'c':
45-
putchar(va_arg(args, char));
46-
len++;
45+
s[len++]=va_arg(args, char);
4746
break;
4847
case 's':
49-
rv = puts(va_arg(args, const char*));
50-
if(rv>0) len+=rv;
48+
innerstr = va_arg(args, const char*);
49+
while (len<n && (*innerstr)!='\0') {
50+
s[len++]=*(innerstr++);
51+
}
5152
break;
5253
case 'd':
5354
itoa(va_arg(args, int), sbuffer, 10);
54-
rv = puts(sbuffer);
55-
if(rv>0) len+=rv;
55+
innerstr = sbuffer;
56+
while (len<n && (*innerstr)!='\0') {
57+
s[len++]=*(innerstr++);
58+
}
5659
break;
5760
case 'X':
5861
case 'x': // not an priority for now :)
5962
itoa(va_arg(args, int), sbuffer, 16);
60-
rv = puts(sbuffer);
61-
if(rv>0) len+=rv;
63+
innerstr = sbuffer;
64+
while (len<n && (*innerstr)!='\0') {
65+
s[len++]=*(innerstr++);
66+
}
6267
break;
6368
default:
64-
return -1; // invalid format char
69+
err = -1; // invalid format char, terminate
6570
}
6671
}
67-
va_end(args);
68-
if(rv < 0) return rv;
72+
s[len]='\0';
73+
if(err != 0) return err;
6974
return len;
7075
}
7176

77+
int snprintf(char *s, size_t n, const char *fmt, ...) {
78+
va_list args;
79+
va_start(args, fmt);
80+
int ret = vsnprintf(s, n, fmt, args);
81+
va_end(args);
82+
return ret;
83+
}
84+
85+
int printf(const char *fmt, ...) {
86+
// limitation: it won't print more than 256 bytes in one go.
87+
char buffer[256];
88+
va_list args;
89+
va_start(args, fmt);
90+
int ret = vsnprintf(buffer, sizeof(buffer), fmt, args);
91+
va_end(args);
92+
return puts(buffer);
93+
}
94+
7295
char* gets(char *s) {
7396
char *og = s;
7497
while (1) {

src/usr/local/src/multiprocessing.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,15 @@ int main(int argc,char *argv[]) {
1212
// child process
1313
am_i_child=1;
1414
printf("child process: says Hi\n");
15+
yield(); // force process scheduler
1516
} else {
1617
am_i_child=0;
1718
// parent process
1819
printf("parent process: says Hi\n");
1920
printf("will for child process to exit\n");
2021
waitpid(pid);
2122
}
22-
printf("process exiting. Am I child process=%s\n", (am_i_child)?"Yes":"No");
23+
printf("process exiting. Is correct process the child: %s\n", (am_i_child)?"Yes":"No");
2324

2425
return 0;
2526
}

0 commit comments

Comments
 (0)