diff options
author | Alistair Francis <alistair.francis@wdc.com> | 2020-01-16 21:49:34 -0800 |
---|---|---|
committer | Alistair Francis <alistair.francis@wdc.com> | 2020-01-16 21:49:34 -0800 |
commit | db7aefbcd9674072eb20304f1ca65403ffbdbd8f (patch) | |
tree | 2fbb9b99a1aa924a52dfc49cf8803911f6b07d32 | |
parent | 78dcaf2ea7d74e02700fd1c97fccdd1635de2799 (diff) | |
download | glibc-alistair/rv32.wip.tar.gz glibc-alistair/rv32.wip.tar.xz glibc-alistair/rv32.wip.zip |
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
-rw-r--r-- | sysdeps/unix/sysv/linux/bits/sem.h | 12 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/semctl.c | 27 |
2 files changed, 35 insertions, 4 deletions
diff --git a/sysdeps/unix/sysv/linux/bits/sem.h b/sysdeps/unix/sysv/linux/bits/sem.h index e0f4155c67..6ea5a69969 100644 --- a/sysdeps/unix/sysv/linux/bits/sem.h +++ b/sysdeps/unix/sysv/linux/bits/sem.h @@ -57,6 +57,18 @@ struct semid_ds __syscall_ulong_t __glibc_reserved4; }; +struct __semid_ds32 { + struct ipc_perm sem_perm; /* operation permission struct */ + __syscall_ulong_t sem_otime; /* last semop() time */ + __syscall_ulong_t sem_otime_high; /* last semop() time high */ + __syscall_ulong_t sem_ctime; /* last time changed by semctl() */ + __syscall_ulong_t sem_ctime_high; /* last time changed by semctl() high */ + __syscall_ulong_t sem_nsems; /* number of semaphores in set */ + __syscall_ulong_t __glibc_reserved3; + __syscall_ulong_t __glibc_reserved4; +}; + + /* The user should define a union like the following to use it for arguments for `semctl'. diff --git a/sysdeps/unix/sysv/linux/semctl.c b/sysdeps/unix/sysv/linux/semctl.c index 0c3eb0932f..22fce7a770 100644 --- a/sysdeps/unix/sysv/linux/semctl.c +++ b/sysdeps/unix/sysv/linux/semctl.c @@ -28,6 +28,7 @@ union semun { int val; /* value for SETVAL */ struct semid_ds *buf; /* buffer for IPC_STAT & IPC_SET */ + struct __semid_ds32 *buf32; unsigned short int *array; /* array for GETALL & SETALL */ struct seminfo *__buf; /* buffer for IPC_INFO */ }; @@ -43,12 +44,30 @@ union semun static int semctl_syscall (int semid, int semnum, int cmd, union semun arg) { -#ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS - return INLINE_SYSCALL_CALL (semctl, semid, semnum, cmd | __IPC_64, - arg.array); +#if __TIMESZIE == 64 && __WORDSIZE == 32 + int ret; +# ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS + ret = INLINE_SYSCALL_CALL (semctl, semid, semnum, cmd | __IPC_64, + arg.array); +# else + ret = INLINE_SYSCALL_CALL (ipc, IPCOP_semctl, semid, semnum, cmd | __IPC_64, + SEMCTL_ARG_ADDRESS (arg)); +# endif + if (ret == 0) + { + arg.buf.sem_ctime = arg.buf32.sem_ctime + arg.buf32.sem_ctime_high; + arg.buf.sem_otime = arg.buf32.sem_otime + arg.buf32.sem_otime_high; + } + return ret; #else +# ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS + return INLINE_SYSCALL_CALL (semctl, semid, semnum, cmd | __IPC_64, + arg.array); +# else return INLINE_SYSCALL_CALL (ipc, IPCOP_semctl, semid, semnum, cmd | __IPC_64, - SEMCTL_ARG_ADDRESS (arg)); + SEMCTL_ARG_ADDRESS (arg)); +# endif + #endif } |