diff --git a/Makefile b/Makefile index a26f3db..0893966 100644 --- a/Makefile +++ b/Makefile @@ -151,6 +151,7 @@ UPROGS=\ $U/_forphan\ $U/_dorphan\ $U/_sync\ + $U/_readcount\ fs.img: mkfs/mkfs README $(UPROGS) mkfs/mkfs fs.img README $(UPROGS) diff --git a/kernel/syscall.c b/kernel/syscall.c index 1800f20..45cd5e2 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -103,6 +103,7 @@ extern uint64 sys_link(void); extern uint64 sys_mkdir(void); extern uint64 sys_close(void); extern uint64 sys_sync(void); +extern uint64 sys_getreadcount(void); // An array mapping syscall numbers from syscall.h // to the function that handles the system call. @@ -130,6 +131,7 @@ static uint64 (*syscalls[])(void) = { [SYS_mkdir] = sys_mkdir, [SYS_close] = sys_close, [SYS_sync] = sys_sync, + [SYS_getreadcount] = sys_getreadcount, // clang-format on }; diff --git a/kernel/syscall.h b/kernel/syscall.h index 5a4a39f..b337d29 100644 --- a/kernel/syscall.h +++ b/kernel/syscall.h @@ -21,3 +21,4 @@ #define SYS_mkdir 20 #define SYS_close 21 #define SYS_sync 22 +#define SYS_getreadcount 23 diff --git a/kernel/sysfile.c b/kernel/sysfile.c index 7781287..7390195 100644 --- a/kernel/sysfile.c +++ b/kernel/sysfile.c @@ -65,6 +65,9 @@ sys_dup(void) return fd; } +// Llamadas a read() desde el arranque. +uint64 readcount = 0; + uint64 sys_read(void) { @@ -72,6 +75,9 @@ sys_read(void) int n; uint64 p; + // Varios CPUs a la vez: suma atómica. + __atomic_fetch_add(&readcount, 1, + __ATOMIC_RELAXED); argaddr(1, &p); argint(2, &n); if (argfd(0, 0, &f) < 0) diff --git a/kernel/sysproc.c b/kernel/sysproc.c index cd25557..3a9f5da 100644 --- a/kernel/sysproc.c +++ b/kernel/sysproc.c @@ -22,6 +22,15 @@ sys_getpid(void) return myproc()->pid; } +extern uint64 readcount; // en kernel/sysfile.c + +uint64 +sys_getreadcount(void) +{ + // Un solo ld de 64 bits: no se corta. + return readcount; +} + uint64 sys_fork(void) { diff --git a/user/readcount.c b/user/readcount.c new file mode 100644 index 0000000..b775e6b --- /dev/null +++ b/user/readcount.c @@ -0,0 +1,17 @@ +#include "kernel/types.h" +#include "kernel/fcntl.h" +#include "user/user.h" + +int +main(void) +{ + char buf[64]; + int before = getreadcount(); + int fd = open("README", O_RDONLY); + while (read(fd, buf, sizeof(buf)) > 0) + ; + close(fd); + int after = getreadcount(); + printf("antes %d, despues %d\n", before, after); + exit(0); +} diff --git a/user/user.h b/user/user.h index 29aad59..501d3bb 100644 --- a/user/user.h +++ b/user/user.h @@ -25,6 +25,7 @@ char *sys_sbrk(int, int); int pause(int); int uptime(void); int sync(void); +int getreadcount(void); // ulib.c int stat(const char *, struct stat *); diff --git a/user/usys.pl b/user/usys.pl index 4d054e8..f5d3cd7 100755 --- a/user/usys.pl +++ b/user/usys.pl @@ -43,3 +43,4 @@ entry("sbrk"); entry("pause"); entry("uptime"); entry("sync"); +entry("getreadcount");