First patch by Salvatore to implement XSI semaphores with a few changes

by myself:
* renamed xsi_do_undo() to xsi_sem_undo() (there is more to XSI than sems).
* Fixed coding style issues in sys/sem.h and xsi_sem.cpp.
* Added _kern_*() syscall prototypes to syscalls.h.
* Added a TODO in xsi_sem.cpp and xsi_semaphore.h about moving union semun to
  a shared header.
* Made the team::xsi_sem_undo_requests int32 - due to padding, it would have
  needed 4 bytes anyway; please always use specific types over int/short/long.
* xsi_sem_undo() now checks if it needs to do anything - the calls in team.cpp
  no longer needs to do this.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26676 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2008-07-29 12:03:41 +00:00
parent ecc1c87fc7
commit 47ca7595ca
13 changed files with 1374 additions and 18 deletions

View File

@ -6,8 +6,8 @@
#define _SYS_IPC_H
#include <sys/cdefs.h>
#include <sys/types.h>
#error functionality has not yet been implemented
/* Mode bits for msgget(), semget(), and shmget() */
@ -17,15 +17,15 @@
/* Control commands for msgctl(), semctl(), and shmctl() */
#define IPC_RMID 0 /* remove identifier */
#define IPC_SET 1
#define IPC_STAT 2
#define IPC_SET 1 /* set options */
#define IPC_STAT 2 /* get options */
/* Private key */
#define IPC_PRIVATE 0
#define IPC_PRIVATE (key_t)0
struct ipc_perm {
key_t key;
key_t key; /* IPC identifier */
uid_t uid; /* owner's user ID */
gid_t gid; /* owner's group ID */
uid_t cuid; /* creator's user ID */
@ -34,14 +34,10 @@ struct ipc_perm {
};
#ifdef __cplusplus
extern "C" {
#endif
__BEGIN_DECLS
key_t ftok(const char *path, int id);
#ifdef __cplusplus
}
#endif
__END_DECLS
#endif /* _SYS_IPC_H */

64
headers/posix/sys/sem.h Normal file
View File

@ -0,0 +1,64 @@
/*
* Copyright 2008, Haiku Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _SYS_SEM_H
#define _SYS_SEM_H
#include <sys/cdefs.h>
#include <sys/ipc.h>
#include <sys/types.h>
/* Semaphore operation flags */
#define SEM_UNDO 10
/* Command definition for semctl */
#define GETPID 3 /* Get process ID of last element manipulating */
#define GETVAL 4 /* Get semval */
#define GETALL 5 /* Get all semval */
#define GETNCNT 6 /* Get semncnt */
#define GETZCNT 7 /* Get semzcnt */
#define SETVAL 8 /* Set semval */
#define SETALL 9 /* Set all semval */
struct semid_ds {
struct ipc_perm sem_perm; /* Operation permission structure */
unsigned short sem_nsems; /* Number of semaphores in set */
time_t sem_otime; /* Last semop */
time_t sem_ctime; /* Last time changed by semctl */
};
/* Structure passed as parameter to the semop function */
struct sembuf {
unsigned short sem_num; /* Semaphore number */
short sem_op; /* Semaphore operation */
short sem_flg; /* Operation flags */
};
/*
* Semaphore info structure. Useful for the ipcs
* standard utily
*/
struct seminfo {
int semmni; /* Number of semaphore identifies */
int semmns; /* Number of semaphore in system */
int semmnu; /* Number of undo structures in system */
int semmsl; /* Max number of semaphores per id */
int semopm; /* Max number of operations per semop call */
int semume; /* Max number of undo entries per process */
int semusz; /* Size in bytes of undo structure */
int semvmx; /* Semaphore maximum valure */
int semaem; /* adjust on exit max value */
};
__BEGIN_DECLS
int semctl(int semID, int semNum, int command, ...);
int semget(key_t key, int numSems, int semFlags);
int semop(int semID, struct sembuf *semOps, size_t numSemOps);
__END_DECLS
#endif /* _SYS_SEM_H */

View File

@ -0,0 +1,39 @@
/*
* Copyright 2008, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef KERNEL_XSI_SEMAPHORE_H
#define KERNEL_XSI_SEMAPHORE_H
#include <sys/sem.h>
#include <sys/cdefs.h>
#include <OS.h>
#include <kernel.h>
// TODO: move into a system/posix/xsi_semaphore_defs.h file to be shared with
// xsi_sem.cpp in libroot!
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
};
__BEGIN_DECLS
extern void xsi_ipc_init();
extern void xsi_sem_undo(team_id teamID, int32 numberOfUndos);
/* user calls */
int _user_xsi_semget(key_t key, int numberOfSemaphores, int flags);
int _user_xsi_semctl(int semaphoreID, int semaphoreNumber, int command,
union semun* args);
status_t _user_xsi_semop(int semaphoreID, struct sembuf *semOps,
size_t numSemOps);
__END_DECLS
#endif /* KERNEL_XSI_SEMAPHORE_H */

View File

@ -182,6 +182,7 @@ struct team {
int32 flags;
void *io_context;
struct realtime_sem_context *realtime_sem_context;
int32 xsi_sem_undo_requests;
sem_id death_sem; // semaphore to wait on for dying threads
struct list dead_threads;
int dead_threads_count;

View File

@ -30,6 +30,8 @@ struct rlimit;
struct sigaction;
struct stat;
struct _sem_t;
struct sembuf;
union semun;
struct disk_device_job_progress_info;
struct partitionable_space_data;
@ -55,24 +57,26 @@ extern int _kern_getrlimit(int resource, struct rlimit * rlp);
extern int _kern_setrlimit(int resource, const struct rlimit * rlp);
extern status_t _kern_shutdown(bool reboot);
extern status_t _kern_get_safemode_option(const char *parameter, char *buffer, size_t *_bufferSize);
extern status_t _kern_get_safemode_option(const char *parameter,
char *buffer, size_t *_bufferSize);
extern ssize_t _kern_wait_for_objects(object_wait_info* infos, int numInfos,
uint32 flags, bigtime_t timeout);
/* sem functions */
extern sem_id _kern_create_sem(int count, const char *name);
extern status_t _kern_delete_sem(sem_id id);
extern status_t _kern_switch_sem(sem_id releaseSem, sem_id id);
extern status_t _kern_switch_sem_etc(sem_id releaseSem, sem_id id, uint32 count,
uint32 flags, bigtime_t timeout);
extern status_t _kern_switch_sem_etc(sem_id releaseSem, sem_id id,
uint32 count, uint32 flags, bigtime_t timeout);
extern status_t _kern_acquire_sem(sem_id id);
extern status_t _kern_acquire_sem_etc(sem_id id, uint32 count, uint32 flags, bigtime_t timeout);
extern status_t _kern_acquire_sem_etc(sem_id id, uint32 count, uint32 flags,
bigtime_t timeout);
extern status_t _kern_release_sem(sem_id id);
extern status_t _kern_release_sem_etc(sem_id id, uint32 count, uint32 flags);
extern status_t _kern_get_sem_count(sem_id id, int32* thread_count);
extern status_t _kern_get_sem_info(sem_id semaphore, struct sem_info *info, size_t size);
extern status_t _kern_get_sem_info(sem_id semaphore, struct sem_info *info,
size_t size);
extern status_t _kern_get_next_sem_info(team_id team, int32 *cookie,
struct sem_info *info, size_t size);
extern status_t _kern_set_sem_owner(sem_id id, team_id proc);
@ -89,8 +93,14 @@ extern status_t _kern_realtime_sem_get_value(sem_id semID, int* value);
extern status_t _kern_realtime_sem_post(sem_id semID);
extern status_t _kern_realtime_sem_wait(sem_id semID, bigtime_t timeout);
/* team & thread syscalls */
/* POSIX XSI semaphore syscalls */
extern int _kern_xsi_semget(key_t key, int numSems, int flags);
extern int _kern_xsi_semctl(int semID, int semNumber, int command,
union semun* args);
extern status_t _kern_xsi_semop(int semID, struct sembuf *semOps,
size_t numSemOps);
/* team & thread syscalls */
extern thread_id _kern_load_image(const char* const* flatArgs,
size_t flatArgsSize, int32 argCount, int32 envCount,
int32 priority, uint32 flags, port_id errorPort,

View File

@ -37,6 +37,7 @@
#include <Notifications.h>
#include <port.h>
#include <posix/realtime_sem.h>
#include <posix/xsi_semaphore.h>
#include <real_time_clock.h>
#include <sem.h>
#include <smp.h>
@ -174,7 +175,9 @@ _start(kernel_args *bootKernelArgs, int currentCPU)
TRACE("init kernel daemons\n");
kernel_daemon_init();
arch_platform_init_post_thread(&sKernelArgs);
TRACE("init posix semaphores\n");
realtime_sem_init();
xsi_ipc_init();
TRACE("init VM threads\n");
vm_init_post_thread(&sKernelArgs);

View File

@ -4,6 +4,7 @@ UsePrivateHeaders shared ;
KernelMergeObject kernel_posix.o :
realtime_sem.cpp
xsi_semaphore.cpp
: $(TARGET_KERNEL_PIC_CCFLAGS)
;

File diff suppressed because it is too large Load Diff

View File

@ -17,6 +17,7 @@
#include <vm.h>
#include <thread.h>
#include <posix/realtime_sem.h>
#include <posix/xsi_semaphore.h>
#include <sem.h>
#include <port.h>
#include <cpu.h>

View File

@ -31,6 +31,7 @@
#include <ksignal.h>
#include <port.h>
#include <posix/realtime_sem.h>
#include <posix/xsi_semaphore.h>
#include <sem.h>
#include <syscall_process_info.h>
#include <syscall_restart.h>
@ -699,6 +700,7 @@ create_team_struct(const char *name, bool kernel)
team->io_context = NULL;
team->address_space = NULL;
team->realtime_sem_context = NULL;
team->xsi_sem_undo_requests = 0;
team->thread_list = NULL;
team->main_thread = NULL;
team->loading_info = NULL;
@ -1322,6 +1324,7 @@ exec_team(const char *path, char**& _flatArgs, size_t flatArgsSize,
delete_team_user_data(team);
vm_delete_areas(team->address_space);
xsi_sem_undo(team->id, team->xsi_sem_undo_requests);
delete_owned_ports(team->id);
sem_delete_owned_sems(team->id);
remove_images(team);
@ -2338,6 +2341,7 @@ team_delete_team(struct team *team)
vfs_free_io_context(team->io_context);
delete_realtime_sem_context(team->realtime_sem_context);
xsi_sem_undo(team->id, team->xsi_sem_undo_requests);
delete_owned_ports(teamID);
sem_delete_owned_sems(teamID);
remove_images(team);

View File

@ -7,6 +7,7 @@ MergeObject posix_sys.o :
chmod.c
flock.c
ftime.c
ftok.c
getrusage.c
gettimeofday.c
itimer.c
@ -23,4 +24,5 @@ MergeObject posix_sys.o :
uname.c
utimes.c
wait.c
xsi_sem.cpp
;

View File

@ -0,0 +1,22 @@
/*
* Copyright 2008, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Salvatore Benedetto <salvatore.benedetto@gmail.com>
*/
#include <sys/ipc.h>
#include <sys/stat.h>
key_t
ftok(const char *path, int id)
{
struct stat st;
if (stat(path, &st) < 0)
return (key_t)-1;
return (key_t)(id << 24 | (st.st_dev & 0xff) << 16 | (st.st_ino & 0xffff));
}

View File

@ -0,0 +1,77 @@
/*
* Copyright 2008, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Salvatore Benedetto <salvatore.benedetto@gmail.com>
*/
#include <sys/sem.h>
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdlib.h>
#include <OS.h>
//#include <posix/xsi_semaphore_defs.h>
#include <syscall_utils.h>
#include <syscalls.h>
// TODO: this should be removed when the above commented header exists
#if 1
/*
* For the semctl option argument, the user
* should declare explicitly the following union
*/
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
};
#endif
int
semget(key_t key, int numSems, int semFlags)
{
RETURN_AND_SET_ERRNO(_kern_xsi_semget(key, numSems, semFlags));
}
int
semctl(int semID, int semNum, int command, ...)
{
union semun arg;
va_list args;
switch (command) {
case GETVAL:
case GETPID:
case GETNCNT:
case GETZCNT:
case IPC_RMID:
RETURN_AND_SET_ERRNO(_kern_xsi_semctl(semID, semNum, command, 0));
case SETVAL:
case GETALL:
case SETALL:
case IPC_STAT:
case IPC_SET:
va_start(args, command);
arg = va_arg(args, union semun);
va_end(args);
RETURN_AND_SET_ERRNO(_kern_xsi_semctl(semID, semNum, command,
&arg));
default:
return EINVAL;
}
}
int
semop(int semID, struct sembuf *semOps, size_t numSemOps)
{
RETURN_AND_SET_ERRNO(_kern_xsi_semop(semID, semOps, numSemOps));
}