From db5505d87f68151af943f2f09e3fdf3dacaa7685 Mon Sep 17 00:00:00 2001 From: deuce <> Date: Sat, 26 Apr 2003 17:31:45 +0000 Subject: [PATCH] Initial NetBSD and QNX support. --- src/xpdev/GNUmakefile | 22 +++- src/xpdev/filewrap.c | 14 ++- src/xpdev/filewrap.h | 44 ++++--- src/xpdev/genwrap.c | 2 +- src/xpdev/genwrap.h | 19 +++ src/xpdev/sem.c | 255 ++++++++++++++++++++++++++++++++++++----- src/xpdev/sem.h | 78 +++++++++++-- src/xpdev/threadwrap.c | 4 +- 8 files changed, 372 insertions(+), 66 deletions(-) diff --git a/src/xpdev/GNUmakefile b/src/xpdev/GNUmakefile index 6c68724473..0d87bd9fa2 100644 --- a/src/xpdev/GNUmakefile +++ b/src/xpdev/GNUmakefile @@ -53,11 +53,21 @@ else ifeq ($(os),openbsd) # OpenBSD CFLAGS += -D_THREAD_SAFE LFLAGS := -pthread - else # Linux / Other UNIX - ifdef bcc - LFLAGS := libpthread.a + else + ifeq ($(os),netbsd) # NetBSD + CFLAGS += -D_THREAD_SAFE -D__unix__ -D_NEED_SEM -I/usr/pkg/include + LFLAGS := -lpth -lpthread -L/usr/pkg/lib else - LFLAGS := -lpthread + ifeq ($(os),qnx) # QNX + CFLAGS += -D_THREAD_SAFE + LFLAGS := + else # Linux / Other UNIX + ifdef bcc + LFLAGS := libpthread.a + else + LFLAGS := -lpthread + endif + endif endif endif endif @@ -77,6 +87,10 @@ endif include objects.mk # defines $(OBJS) include targets.mk # defines all and clean targets +ifeq ($(os),netbsd) + OBJS += $(ODIR)$(SLASH)sem.$(OFILE) +endif + # Implicit C Compile Rule $(ODIR)/%.o : %.c @echo Compiling $< diff --git a/src/xpdev/filewrap.c b/src/xpdev/filewrap.c index 82446f24f1..3b89c85e84 100644 --- a/src/xpdev/filewrap.c +++ b/src/xpdev/filewrap.c @@ -82,7 +82,11 @@ long DLLCALL filelength(int fd) } /* Sets a lock on a portion of a file */ +#ifdef __QNX__ +int DLLCALL lock(int fd, long pos, long len) +#else int DLLCALL lock(int fd, long pos, int len) +#endif { #if defined(F_SANERDLCKNO) || !defined(BSD) struct flock alock; @@ -101,7 +105,7 @@ int DLLCALL lock(int fd, long pos, int len) #endif alock.l_whence = L_SET; /* SEEK_SET */ alock.l_start = pos; - alock.l_len = len; + alock.l_len = (int)len; if(fcntl(fd, F_SETLK, &alock)==-1) return(-1); @@ -117,7 +121,11 @@ int DLLCALL lock(int fd, long pos, int len) } /* Removes a lock from a file record */ +#ifdef __QNX__ +int DLLCALL unlock(int fd, long pos, long len) +#else int DLLCALL unlock(int fd, long pos, int len) +#endif { #if defined(F_SANEUNLCK) || !defined(BSD) @@ -129,7 +137,7 @@ int DLLCALL unlock(int fd, long pos, int len) #endif alock.l_whence = L_SET; alock.l_start = pos; - alock.l_len = len; + alock.l_len = (int)len; if(fcntl(fd, F_SETLK, &alock)==-1) return(-1); #endif @@ -143,6 +151,7 @@ int DLLCALL unlock(int fd, long pos, int len) return(0); } +#ifndef __QNX__ /* Opens a file in specified sharing (file-locking) mode */ int DLLCALL sopen(char *fn, int access, int share) { @@ -189,6 +198,7 @@ int DLLCALL sopen(char *fn, int access, int share) return fd; } +#endif #elif defined _MSC_VER || defined __MINGW32__ diff --git a/src/xpdev/filewrap.h b/src/xpdev/filewrap.h index f4f2aa4235..e15b080a93 100644 --- a/src/xpdev/filewrap.h +++ b/src/xpdev/filewrap.h @@ -72,24 +72,28 @@ #include <fcntl.h> - #define O_TEXT 0 /* all files in binary mode on Unix */ - #define O_BINARY 0 /* all files in binary mode on Unix */ - #undef O_DENYNONE - #define O_DENYNONE (1<<31) /* req'd for Baja/nopen compatibility */ - - #define SH_DENYNO 2 // no locks -#ifdef F_SANEWRLCKNO - #define SH_DENYRW F_SANEWRLCKNO // exclusive lock -#else - #define SH_DENYRW F_WRLCK // exclusive lock -#endif - -#ifdef F_SANERDLCKNO - #define SH_DENYWR F_SANERDLCKNO // shareable lock -#else - #define SH_DENYWR F_RDLCK // shareable lock -#endif - + #ifdef __QNX__ + #include <share.h> /* SH_DENY */ + #define L_SET SEEK_SET + #else + #define O_TEXT 0 /* all files in binary mode on Unix */ + #define O_BINARY 0 /* all files in binary mode on Unix */ + #undef O_DENYNONE + #define O_DENYNONE (1<<31) /* req'd for Baja/nopen compatibility */ + + #define SH_DENYNO 2 // no locks + #ifdef F_SANEWRLCKNO + #define SH_DENYRW F_SANEWRLCKNO // exclusive lock + #else + #define SH_DENYRW F_WRLCK // exclusive lock + #endif + + #ifdef F_SANERDLCKNO + #define SH_DENYWR F_SANERDLCKNO // shareable lock + #else + #define SH_DENYWR F_RDLCK // shareable lock + #endif + #endif #define chsize(fd,size) ftruncate(fd,size) #define tell(fd) lseek(fd,0,SEEK_CUR) @@ -111,13 +115,15 @@ extern "C" { #endif -#if !defined(__BORLANDC__) +#if !defined(__BORLANDC__) && !defined(__QNX__) DLLEXPORT int DLLCALL lock(int fd, long pos, int len); DLLEXPORT int DLLCALL unlock(int fd, long pos, int len); #endif #if !defined(__BORLANDC__) && defined(__unix__) +#if !defined(__QNX__) DLLEXPORT int DLLCALL sopen(char *fn, int access, int share); +#endif DLLEXPORT long DLLCALL filelength(int fd); #endif diff --git a/src/xpdev/genwrap.c b/src/xpdev/genwrap.c index 03b3fb3cb0..565e8b8047 100644 --- a/src/xpdev/genwrap.c +++ b/src/xpdev/genwrap.c @@ -123,7 +123,7 @@ void DLLCALL unix_beep(int freq, int dur) { static int console_fd=-1; -#if !defined(__OpenBSD__) && !defined(__GNU__) +#if !defined(__OpenBSD__) && !defined(__GNU__) && !defined(__NetBSD__) && !defined(__QNX__) if(console_fd == -1) console_fd = open("/dev/console", O_NOCTTY); diff --git a/src/xpdev/genwrap.h b/src/xpdev/genwrap.h index 47c850ad45..a2f3169a55 100644 --- a/src/xpdev/genwrap.h +++ b/src/xpdev/genwrap.h @@ -45,6 +45,13 @@ #if defined(__unix__) #include <unistd.h> /* usleep */ #include <sys/time.h> /* struct timeval */ + #if defined(_NEED_SEM) /* Assumes that if you don't have semaphores, you're using the GNU Pth lib */ + #include <pth.h> + #endif +#endif + +#if defined(__QNX__) + #include <strings.h> /* strcasecmp() */ #endif #if defined(__cplusplus) @@ -100,6 +107,8 @@ extern "C" { #define PLATFORM_DESC "FreeBSD" #elif defined(__OpenBSD__) #define PLATFORM_DESC "OpenBSD" +#elif defined(__NetBSD__) + #define PLATFORM_DESC "NetBSD" #elif defined(BSD) #define PLATFORM_DESC "BSD" #elif defined(__solaris__) @@ -108,6 +117,8 @@ extern "C" { #define PLATFORM_DESC "SunOS" #elif defined(__gnu__) #define PLATFORM_DESC "GNU/Hurd" +#elif defined(__QNX__) + #define PLATFORM_DESC "QNX" #elif defined(__unix__) #define PLATFORM_DESC "Unix" #else @@ -161,6 +172,14 @@ extern "C" { #define SLEEP(x) DosSleep(x) #define BEEP(freq,dur) DosBeep(freq,dur) +#elif defined(_PTH_H_) + + #define SLEEP(x) ({ int y=x; struct timeval tv; \ + tv.tv_sec=(y/1000); tv.tv_usec=((y%1000)*1000); \ + pth_nap(tv); }) + #define BEEP(freq,dur) unix_beep(freq,dur) + DLLEXPORT void DLLCALL unix_beep(int freq, int dur); + #elif defined(__unix__) /* usleep() apparently doesn't work right (100% CPU utilization) */ diff --git a/src/xpdev/sem.c b/src/xpdev/sem.c index 825653e603..ea6d5ed248 100644 --- a/src/xpdev/sem.c +++ b/src/xpdev/sem.c @@ -1,45 +1,238 @@ +/* + * $Id$ + * + * Copyright (C) 2000 Jason Evans <jasone@freebsd.org>. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD: src/lib/libc_r/uthread/uthread_sem.c,v 1.3.2.1 2000/07/18 02:05:57 jasone Exp $ + */ + #include <errno.h> -#include <stdlib.h> -#include <unistd.h> -#include "genwrap.h" #include "sem.h" +#include <pthread.h> +#include "pthread_private.h" + +int +sem_init(sem_t *sem, int pshared, unsigned int value) +{ + int retval; + + /* + * Range check the arguments. + */ + if (pshared != 0) { + /* + * The user wants a semaphore that can be shared among + * processes, which this implementation can't do. Sounds like a + * permissions problem to me (yeah right). + */ + errno = EPERM; + retval = -1; + goto RETURN; + } + + if (value > SEM_VALUE_MAX) { + errno = EINVAL; + retval = -1; + goto RETURN; + } -int sem_init(sem_t *sem, int pshared, unsigned int value) { - sem=malloc(sizeof(sem_t)); - if(sem==NULL) { - errno=ENOSPC; - return(-1); + *sem = (sem_t)malloc(sizeof(struct sem)); + if (*sem == NULL) { + errno = ENOSPC; + retval = -1; + goto RETURN; } - if(pipe((int *)sem)) { - errno=EPERM; - return(-1); + + /* + * Initialize the semaphore. + */ + if (pthread_mutex_init(&(*sem)->lock, NULL) != 0) { + free(*sem); + errno = ENOSPC; + retval = -1; + goto RETURN; + } + + if (pthread_cond_init(&(*sem)->gtzero, NULL) != 0) { + pthread_mutex_destroy(&(*sem)->lock); + free(*sem); + errno = ENOSPC; + retval = -1; + goto RETURN; + } + + (*sem)->count = (u_int32_t)value; + (*sem)->nwaiters = 0; + (*sem)->magic = SEM_MAGIC; + + retval = 0; + RETURN: + return retval; +} + +int +sem_destroy(sem_t *sem) +{ + int retval; + + _SEM_CHECK_VALIDITY(sem); + + /* Make sure there are no waiters. */ + pthread_mutex_lock(&(*sem)->lock); + if ((*sem)->nwaiters > 0) { + pthread_mutex_unlock(&(*sem)->lock); + errno = EBUSY; + retval = -1; + goto RETURN; } - return(0); + pthread_mutex_unlock(&(*sem)->lock); + + pthread_mutex_destroy(&(*sem)->lock); + pthread_cond_destroy(&(*sem)->gtzero); + (*sem)->magic = 0; + + free(*sem); + + retval = 0; + RETURN: + return retval; } -int sem_destroy(sem_t *sem) { - close(sem->read); - close(sem->write); - sem=NULL; - return(0); +sem_t * +sem_open(const char *name, int oflag, ...) +{ + errno = ENOSYS; + return SEM_FAILED; } -int sem_post(sem_t *sem) { - if(sem==NULL) { - errno=EINVAL; - return(-1); +int +sem_close(sem_t *sem) +{ + errno = ENOSYS; + return -1; +} + +int +sem_unlink(const char *name) +{ + errno = ENOSYS; + return -1; +} + +int +sem_wait(sem_t *sem) +{ + int retval; + + pthread_testcancel(); + + _SEM_CHECK_VALIDITY(sem); + + pthread_mutex_lock(&(*sem)->lock); + + while ((*sem)->count == 0) { + (*sem)->nwaiters++; + pthread_cond_wait(&(*sem)->gtzero, &(*sem)->lock); + (*sem)->nwaiters--; } - write(sem->write,"-",1)==1; - return(0); + (*sem)->count--; + + pthread_mutex_unlock(&(*sem)->lock); + + retval = 0; + RETURN: + + pthread_testcancel(); + return retval; } -int sem_wait(sem_t *sem) { - char buf; - if(sem==NULL) { - errno=EINVAL; - return(-1); +int +sem_trywait(sem_t *sem) +{ + int retval; + + _SEM_CHECK_VALIDITY(sem); + + pthread_mutex_lock(&(*sem)->lock); + + if ((*sem)->count > 0) { + (*sem)->count--; + retval = 0; + } else { + errno = EAGAIN; + retval = -1; } - while(read(sem->read,&buf,1)<1) - SLEEP(1); - return(0); + + pthread_mutex_unlock(&(*sem)->lock); + + RETURN: + return retval; +} + +int +sem_post(sem_t *sem) +{ + int retval; + + _SEM_CHECK_VALIDITY(sem); + + pthread_mutex_lock(&(*sem)->lock); + + (*sem)->count++; + if ((*sem)->nwaiters > 0) { + /* + * We must use pthread_cond_broadcast() rather than + * pthread_cond_signal() in order to assure that the highest + * priority thread is run by the scheduler, since + * pthread_cond_signal() signals waiting threads in FIFO order. + */ + pthread_cond_broadcast(&(*sem)->gtzero); + } + + pthread_mutex_unlock(&(*sem)->lock); + + retval = 0; + RETURN: + return retval; +} + +int +sem_getvalue(sem_t *sem, int *sval) +{ + int retval; + + _SEM_CHECK_VALIDITY(sem); + + pthread_mutex_lock(&(*sem)->lock); + *sval = (int)(*sem)->count; + pthread_mutex_unlock(&(*sem)->lock); + + retval = 0; + RETURN: + return retval; } diff --git a/src/xpdev/sem.h b/src/xpdev/sem.h index 9dbdd9eb90..1c601c78a8 100644 --- a/src/xpdev/sem.h +++ b/src/xpdev/sem.h @@ -1,10 +1,72 @@ -typedef struct { - int read; - int write; -} sem_t; +#ifndef _SEMAPHORE_H_ +#define _SEMAPHORE_H_ -int sem_init(sem_t *sem, int pshared, unsigned int value); -int sem_destroy(sem_t *sem); -int sem_post(sem_t *sem); -int sem_wait(sem_t *sem); +/* + * $Id$ + * + * semaphore.h: POSIX 1003.1b semaphores +*/ +/*- + * Copyright (c) 1996, 1997 + * HD Associates, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by HD Associates, Inc + * 4. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY HD ASSOCIATES AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL HD ASSOCIATES OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/sys/posix4/semaphore.h,v 1.6 2000/01/20 07:55:42 jasone Exp $ + */ + +#include <machine/limits.h> + +#include <sys/types.h> +#include <fcntl.h> + +/* Opaque type definition. */ +struct sem; +typedef struct sem *sem_t; + +#define SEM_FAILED ((sem_t *)0) +#define SEM_VALUE_MAX UINT_MAX + +#ifndef KERNEL +#include <sys/cdefs.h> + +__BEGIN_DECLS +int sem_init __P((sem_t *, int, unsigned int)); +int sem_destroy __P((sem_t *)); +sem_t *sem_open __P((const char *, int, ...)); +int sem_close __P((sem_t *)); +int sem_unlink __P((const char *)); +int sem_wait __P((sem_t *)); +int sem_trywait __P((sem_t *)); +int sem_post __P((sem_t *)); +int sem_getvalue __P((sem_t *, int *)); +__END_DECLS +#endif /* KERNEL */ + +#endif /* _SEMAPHORE_H_ */ diff --git a/src/xpdev/threadwrap.c b/src/xpdev/threadwrap.c index 00337c5d9b..f958c54ce0 100644 --- a/src/xpdev/threadwrap.c +++ b/src/xpdev/threadwrap.c @@ -37,6 +37,7 @@ #if defined(__unix__) #include <unistd.h> /* _POSIX_THREADS */ + #include <sys/param.h> /* BSD */ #endif #include "threadwrap.h" /* DLLCALL */ @@ -62,8 +63,9 @@ ulong _beginthread(void( *start_address )( void * ) that thread resources are freed on exit() */ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); -#ifdef BSD /* Default stack size in BSD is too small for JS stuff */ +/* #ifdef BSD */ +#if 0 if(stack_size==0) stack_size=1<<17; #endif -- GitLab