
between being commited to a machno and having acquired the lock, the scheduler could come in an schedule us on a different processor. the solution is to have dtmachlock() take a special -1 argument to mean "current mach" and return the actual mach number after the lock has been acquired and interrupts being disabled.
267 lines
8.2 KiB
C
267 lines
8.2 KiB
C
#include "u.h"
|
|
#include "../port/lib.h"
|
|
#include "mem.h"
|
|
#include "dat.h"
|
|
#include "fns.h"
|
|
#include "../port/error.h"
|
|
|
|
#include "/sys/src/libc/9syscall/sys.h"
|
|
|
|
#include <dtracy.h>
|
|
#include <ctype.h>
|
|
|
|
static DTProbe **dtpsysentry, **dtpsysreturn;
|
|
|
|
typedef uintptr Syscall(va_list);
|
|
extern Syscall *systab[];
|
|
|
|
#define WRAP0(x,y,z)\
|
|
Syscall z; uintptr x(va_list va){\
|
|
uintptr rc;\
|
|
DTTrigInfo info;\
|
|
memset(&info, 0, sizeof(info));\
|
|
dtptrigger(dtpsysentry[y], &info);\
|
|
rc = z(va);\
|
|
info.arg[9] = (uvlong) rc;\
|
|
dtptrigger(dtpsysreturn[y], &info);\
|
|
return rc;\
|
|
}
|
|
#define WRAP1(x,y,z,type0)\
|
|
Syscall z; uintptr x(va_list va){\
|
|
uintptr rc;\
|
|
va_list vb = va;\
|
|
DTTrigInfo info;\
|
|
memset(&info, 0, sizeof(info));\
|
|
info.arg[0] = (uvlong) va_arg(vb, type0);\
|
|
dtptrigger(dtpsysentry[y], &info);\
|
|
rc = z(va);\
|
|
info.arg[9] = (uvlong) rc;\
|
|
dtptrigger(dtpsysreturn[y], &info);\
|
|
return rc;\
|
|
}
|
|
#define WRAP2(x,y,z,type0,type1)\
|
|
Syscall z; uintptr x(va_list va){\
|
|
uintptr rc;\
|
|
va_list vb = va;\
|
|
DTTrigInfo info;\
|
|
memset(&info, 0, sizeof(info));\
|
|
info.arg[0] = (uvlong) va_arg(vb, type0);\
|
|
info.arg[1] = (uvlong) va_arg(vb, type1);\
|
|
dtptrigger(dtpsysentry[y], &info);\
|
|
rc = z(va);\
|
|
info.arg[9] = (uvlong) rc;\
|
|
dtptrigger(dtpsysreturn[y], &info);\
|
|
return rc;\
|
|
}
|
|
#define WRAP3(x,y,z,type0,type1,type2)\
|
|
Syscall z; uintptr x(va_list va){\
|
|
uintptr rc;\
|
|
va_list vb = va;\
|
|
DTTrigInfo info;\
|
|
memset(&info, 0, sizeof(info));\
|
|
info.arg[0] = (uvlong) va_arg(vb, type0);\
|
|
info.arg[1] = (uvlong) va_arg(vb, type1);\
|
|
info.arg[2] = (uvlong) va_arg(vb, type2);\
|
|
dtptrigger(dtpsysentry[y], &info);\
|
|
rc = z(va);\
|
|
info.arg[9] = (uvlong) rc;\
|
|
dtptrigger(dtpsysreturn[y], &info);\
|
|
return rc;\
|
|
}
|
|
#define WRAP4(x,y,z,type0,type1,type2,type3)\
|
|
Syscall z; uintptr x(va_list va){\
|
|
uintptr rc;\
|
|
va_list vb = va;\
|
|
DTTrigInfo info;\
|
|
memset(&info, 0, sizeof(info));\
|
|
info.arg[0] = (uvlong) va_arg(vb, type0);\
|
|
info.arg[1] = (uvlong) va_arg(vb, type1);\
|
|
info.arg[2] = (uvlong) va_arg(vb, type2);\
|
|
info.arg[3] = (uvlong) va_arg(vb, type3);\
|
|
dtptrigger(dtpsysentry[y], &info);\
|
|
rc = z(va);\
|
|
info.arg[9] = (uvlong) rc;\
|
|
dtptrigger(dtpsysreturn[y], &info);\
|
|
return rc;\
|
|
}
|
|
/*TODO*/
|
|
#define WRAP5(x,y,z,type0,type1,type2,type3,type4)\
|
|
Syscall z; uintptr x(va_list va){\
|
|
uintptr rc;\
|
|
va_list vb = va;\
|
|
DTTrigInfo info;\
|
|
memset(&info, 0, sizeof(info));\
|
|
info.arg[0] = (uvlong) va_arg(vb, type0);\
|
|
info.arg[1] = (uvlong) va_arg(vb, type1);\
|
|
info.arg[2] = (uvlong) va_arg(vb, type2);\
|
|
info.arg[3] = (uvlong) va_arg(vb, type3);\
|
|
info.arg[4] = (uvlong) va_arg(vb, type4);\
|
|
dtptrigger(dtpsysentry[y], &info);\
|
|
rc = z(va);\
|
|
info.arg[9] = (uvlong) rc;\
|
|
dtptrigger(dtpsysreturn[y], &info);\
|
|
return rc;\
|
|
}
|
|
|
|
WRAP0(dtwrap_sysr1, SYSR1, sysr1)
|
|
WRAP1(dtwrap_sys_errstr, _ERRSTR, sys_errstr, char*)
|
|
WRAP3(dtwrap_sysbind, BIND, sysbind, char*, char*, int)
|
|
WRAP1(dtwrap_syschdir, CHDIR, syschdir, char*)
|
|
WRAP1(dtwrap_sysclose, CLOSE, sysclose, int)
|
|
WRAP2(dtwrap_sysdup, DUP, sysdup, int, int)
|
|
WRAP1(dtwrap_sysalarm, ALARM, sysalarm, ulong)
|
|
WRAP2(dtwrap_sysexec, EXEC, sysexec, char *, char **)
|
|
WRAP1(dtwrap_sysexits, EXITS, sysexits, char *)
|
|
WRAP3(dtwrap_sys_fsession, _FSESSION, sys_fsession, int, char *, uint)
|
|
WRAP2(dtwrap_sysfauth, FAUTH, sysfauth, int, char *)
|
|
WRAP2(dtwrap_sys_fstat, _FSTAT, sys_fstat, int, uchar *)
|
|
WRAP1(dtwrap_syssegbrk, SEGBRK, syssegbrk, void *)
|
|
WRAP4(dtwrap_sys_mount, _MOUNT, sys_mount, int, char *, int, char *)
|
|
WRAP2(dtwrap_sysopen, OPEN, sysopen, char *, int)
|
|
WRAP3(dtwrap_sys_read, _READ, sys_read, int, void*, long)
|
|
WRAP3(dtwrap_sysoseek, OSEEK, sysoseek, int, long, int)
|
|
WRAP1(dtwrap_syssleep, SLEEP, syssleep, long)
|
|
WRAP2(dtwrap_sys_stat, _STAT, sys_stat, char *, uchar *)
|
|
WRAP1(dtwrap_sysrfork, RFORK, sysrfork, int)
|
|
WRAP3(dtwrap_sys_write, _WRITE, sys_write, int, void *, long)
|
|
WRAP1(dtwrap_syspipe, PIPE, syspipe, int*)
|
|
WRAP3(dtwrap_syscreate, CREATE, syscreate, char*, int, int)
|
|
WRAP3(dtwrap_sysfd2path, FD2PATH, sysfd2path, int, char*, uint)
|
|
WRAP1(dtwrap_sysbrk_, BRK_, sysbrk_, uintptr)
|
|
WRAP1(dtwrap_sysremove, REMOVE, sysremove, char *)
|
|
WRAP0(dtwrap_sys_wstat, _WSTAT, sys_wstat)
|
|
WRAP0(dtwrap_sys_fwstat, _FWSTAT, sys_fwstat)
|
|
WRAP2(dtwrap_sysnotify, NOTIFY, sysnotify, char *, void *)
|
|
WRAP1(dtwrap_sysnoted, NOTED, sysnoted, int)
|
|
WRAP4(dtwrap_syssegattach, SEGATTACH, syssegattach, int, char *, uintptr, ulong)
|
|
WRAP1(dtwrap_syssegdetach, SEGDETACH, syssegdetach, uintptr)
|
|
WRAP2(dtwrap_syssegfree, SEGFREE, syssegfree, uintptr, ulong)
|
|
WRAP2(dtwrap_syssegflush, SEGFLUSH, syssegflush, void*, ulong)
|
|
WRAP2(dtwrap_sysrendezvous, RENDEZVOUS, sysrendezvous, uintptr, uintptr)
|
|
WRAP2(dtwrap_sysunmount, UNMOUNT, sysunmount, char *, char *)
|
|
WRAP1(dtwrap_sys_wait, _WAIT, sys_wait, void*)
|
|
WRAP2(dtwrap_syssemacquire, SEMACQUIRE, syssemacquire, long*, int)
|
|
WRAP2(dtwrap_syssemrelease, SEMRELEASE, syssemrelease, long*, long)
|
|
WRAP4(dtwrap_sysfversion, FVERSION, sysfversion, int, int, char *, int)
|
|
WRAP2(dtwrap_syserrstr, ERRSTR, syserrstr, char *, uint)
|
|
WRAP3(dtwrap_sysstat, STAT, sysstat, char *, uchar *, uint)
|
|
WRAP3(dtwrap_sysfstat, FSTAT, sysfstat, int, uchar *, uint)
|
|
WRAP3(dtwrap_syswstat, WSTAT, syswstat, char *, uchar *, uint)
|
|
WRAP3(dtwrap_sysfwstat, FWSTAT, sysfwstat, int, uchar *, uint)
|
|
WRAP5(dtwrap_sysmount, MOUNT, sysmount, int, int, char *, int, char *)
|
|
WRAP2(dtwrap_sysawait, AWAIT, sysawait, char *, uint)
|
|
WRAP4(dtwrap_syspread, PREAD, syspread, int, void *, long, vlong)
|
|
WRAP4(dtwrap_syspwrite, PWRITE, syspwrite, int, void *, long, vlong)
|
|
WRAP2(dtwrap_systsemacquire, TSEMACQUIRE, systsemacquire, long *, ulong)
|
|
|
|
|
|
/* TODO: amd64 */
|
|
WRAP4(dtwrap_sysseek, SEEK, sysseek, vlong*, int, vlong, int)
|
|
WRAP1(dtwrap_sys_nsec, _NSEC, sys_nsec, vlong*)
|
|
|
|
static Syscall *wraptab[]={
|
|
[SYSR1] dtwrap_sysr1,
|
|
[_ERRSTR] dtwrap_sys_errstr,
|
|
[BIND] dtwrap_sysbind,
|
|
[CHDIR] dtwrap_syschdir,
|
|
[CLOSE] dtwrap_sysclose,
|
|
[DUP] dtwrap_sysdup,
|
|
[ALARM] dtwrap_sysalarm,
|
|
[EXEC] dtwrap_sysexec,
|
|
[EXITS] dtwrap_sysexits,
|
|
[_FSESSION] dtwrap_sys_fsession,
|
|
[FAUTH] dtwrap_sysfauth,
|
|
[_FSTAT] dtwrap_sys_fstat,
|
|
[SEGBRK] dtwrap_syssegbrk,
|
|
[_MOUNT] dtwrap_sys_mount,
|
|
[OPEN] dtwrap_sysopen,
|
|
[_READ] dtwrap_sys_read,
|
|
[OSEEK] dtwrap_sysoseek,
|
|
[SLEEP] dtwrap_syssleep,
|
|
[_STAT] dtwrap_sys_stat,
|
|
[RFORK] dtwrap_sysrfork,
|
|
[_WRITE] dtwrap_sys_write,
|
|
[PIPE] dtwrap_syspipe,
|
|
[CREATE] dtwrap_syscreate,
|
|
[FD2PATH] dtwrap_sysfd2path,
|
|
[BRK_] dtwrap_sysbrk_,
|
|
[REMOVE] dtwrap_sysremove,
|
|
[_WSTAT] dtwrap_sys_wstat,
|
|
[_FWSTAT] dtwrap_sys_fwstat,
|
|
[NOTIFY] dtwrap_sysnotify,
|
|
[NOTED] dtwrap_sysnoted,
|
|
[SEGATTACH] dtwrap_syssegattach,
|
|
[SEGDETACH] dtwrap_syssegdetach,
|
|
[SEGFREE] dtwrap_syssegfree,
|
|
[SEGFLUSH] dtwrap_syssegflush,
|
|
[RENDEZVOUS] dtwrap_sysrendezvous,
|
|
[UNMOUNT] dtwrap_sysunmount,
|
|
[_WAIT] dtwrap_sys_wait,
|
|
[SEMACQUIRE] dtwrap_syssemacquire,
|
|
[SEMRELEASE] dtwrap_syssemrelease,
|
|
[SEEK] dtwrap_sysseek,
|
|
[FVERSION] dtwrap_sysfversion,
|
|
[ERRSTR] dtwrap_syserrstr,
|
|
[STAT] dtwrap_sysstat,
|
|
[FSTAT] dtwrap_sysfstat,
|
|
[WSTAT] dtwrap_syswstat,
|
|
[FWSTAT] dtwrap_sysfwstat,
|
|
[MOUNT] dtwrap_sysmount,
|
|
[AWAIT] dtwrap_sysawait,
|
|
[PREAD] dtwrap_syspread,
|
|
[PWRITE] dtwrap_syspwrite,
|
|
[TSEMACQUIRE] dtwrap_systsemacquire,
|
|
[_NSEC] dtwrap_sys_nsec,
|
|
};
|
|
|
|
static void
|
|
sysprovide(DTProvider *prov)
|
|
{
|
|
char buf[32], pname[32];
|
|
int i;
|
|
|
|
dtpsysentry = smalloc(sizeof(Syscall *) * nsyscall);
|
|
dtpsysreturn = smalloc(sizeof(Syscall *) * nsyscall);
|
|
for(i = 0; i < nsyscall; i++){
|
|
if(systab[i] == nil || sysctab[i] == nil) continue;
|
|
strecpy(buf, buf + sizeof(buf), sysctab[i]);
|
|
if(isupper(buf[0])) buf[0] += 'a' - 'A';
|
|
if(i == SYSR1) strcpy(buf, "r1");
|
|
snprint(pname, sizeof(pname), "sys:%s:entry", buf);
|
|
dtpsysentry[i] = dtpnew(pname, prov, (void *) i);
|
|
snprint(pname, sizeof(pname), "sys:%s:return", buf);
|
|
dtpsysreturn[i] = dtpnew(pname, prov, (void *) i);
|
|
}
|
|
}
|
|
|
|
static int
|
|
sysenable(DTProbe *p)
|
|
{
|
|
int i;
|
|
Syscall *z;
|
|
|
|
i = (int)(uintptr)p->aux;
|
|
assert(i >= 0 && i < nsyscall);
|
|
if(dtpsysentry[i]->nenable + dtpsysreturn[i]->nenable == 0)
|
|
z = systab[i], systab[i] = wraptab[i], wraptab[i] = z;
|
|
return 0;
|
|
}
|
|
|
|
static void
|
|
sysdisable(DTProbe *p)
|
|
{
|
|
int i;
|
|
Syscall *z;
|
|
|
|
i = (int)(uintptr)p->aux;
|
|
assert(i >= 0 && i < nsyscall);
|
|
if(dtpsysentry[i]->nenable + dtpsysreturn[i]->nenable == 0)
|
|
z = systab[i], systab[i] = wraptab[i], wraptab[i] = z;
|
|
}
|
|
|
|
DTProvider dtracysysprov = {
|
|
.name = "sys",
|
|
.provide = sysprovide,
|
|
.enable = sysenable,
|
|
.disable = sysdisable,
|
|
};
|