⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdl_syssem.c

📁 Simple DirectMedia Layer - Simple DirectMedia Layer 是一个跨平台的多媒体库设计用来提供快速图形framebuffer和音频驱动。应用MPEG为软件
💻 C
字号:
/*    SDL - Simple DirectMedia Layer    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Sam Lantinga    This library is free software; you can redistribute it and/or    modify it under the terms of the GNU Library General Public    License as published by the Free Software Foundation; either    version 2 of the License, or (at your option) any later version.    This library is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    Library General Public License for more details.    You should have received a copy of the GNU Library General Public    License along with this library; if not, write to the Free    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA    Sam Lantinga    slouken@devolution.com*/#ifdef SAVE_RCSIDstatic char rcsid = "@(#) $Id: SDL_syssem.c,v 1.3 2002/03/06 11:23:02 slouken Exp $";#endif#include <stdlib.h>#include "SDL_error.h"#include "SDL_thread.h"#include "SDL_timer.h"#ifdef SDL_USE_PTHREADS#include <stdio.h>#include <stdlib.h>#include <unistd.h>			/* For getpid() */#include <pthread.h>/* * This is semaphore.h inlined here so that BSD/OS POSIX semaphore are * completely selfcontained without requiring any additional include files * or libraries not present in the stock system*//* 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#include <sys/cdefs.h>__BEGIN_DECLSint	 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/* END of inlined semaphore.h *//* Wrapper around POSIX 1003.1b semaphores */struct SDL_semaphore {	sem_t *sem;	sem_t sem_data;};/* Create a semaphore, initialized with value */SDL_sem *SDL_CreateSemaphore(Uint32 initial_value){	SDL_sem *sem = (SDL_sem *) malloc(sizeof(SDL_sem));	if ( sem ) {		if ( sem_init(&sem->sem_data, 0, initial_value) < 0 ) {			SDL_SetError("sem_init() failed");			free(sem);			sem = NULL;		} else {			sem->sem = &sem->sem_data;		}	} else {		SDL_OutOfMemory();	}	return sem;}void SDL_DestroySemaphore(SDL_sem *sem){	if ( sem ) {		sem_destroy(sem->sem);		free(sem);	}}int SDL_SemTryWait(SDL_sem *sem){	int retval;	if ( ! sem ) {		SDL_SetError("Passed a NULL semaphore");		return -1;	}	retval = SDL_MUTEX_TIMEDOUT;	if ( sem_trywait(sem->sem) == 0 )		retval = 0;	return retval;}int SDL_SemWait(SDL_sem *sem){	int retval;	if ( ! sem ) {		SDL_SetError("Passed a NULL semaphore");		return -1;	}	retval = sem_wait(sem->sem);	if ( retval < 0 ) {		SDL_SetError("sem_wait() failed");	}	return retval;}int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout){	int retval;	if ( ! sem ) {		SDL_SetError("Passed a NULL semaphore");		return -1;	}	/* Try the easy cases first */	if ( timeout == 0 ) {		return SDL_SemTryWait(sem);	}	if ( timeout == SDL_MUTEX_MAXWAIT ) {		return SDL_SemWait(sem);	}	/* Ack!  We have to busy wait... */	timeout += SDL_GetTicks();	do {		retval = SDL_SemTryWait(sem);		if ( retval == 0 ) {			break;		}		SDL_Delay(1);	} while ( SDL_GetTicks() < timeout );	return retval;}Uint32 SDL_SemValue(SDL_sem *sem){	int ret = 0;	if ( sem ) {		sem_getvalue(sem->sem, &ret);		if ( ret < 0 ) {			ret = 0;		}	}	return (Uint32)ret;}int SDL_SemPost(SDL_sem *sem){	int retval;	if ( ! sem ) {		SDL_SetError("Passed a NULL semaphore");		return -1;	}	retval = sem_post(sem->sem);	if ( retval < 0 ) {		SDL_SetError("sem_post() failed");	}	return retval;}/*  * BEGIN inlined uthread_sem.c.  This is done here so that no extra libraries * or include files not present in BSD/OS are required*//* * 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 <pthread.h>/* Begin thread_private.h kluge *//* * These come out of (or should go into) thread_private.h - rather than have  * to copy (or symlink) the files from the source tree these definitions are  * inlined here.  Obviously these go away when this module is part of libc.*/struct sem {#define SEM_MAGIC       ((u_int32_t) 0x09fa4012)        u_int32_t       magic;        pthread_mutex_t lock;        pthread_cond_t  gtzero;        u_int32_t       count;        u_int32_t       nwaiters;};extern pthread_once_t _thread_init_once;extern int _threads_initialized;extern void  _thread_init __P((void));#define THREAD_INIT() \	(void) pthread_once(&_thread_init_once, _thread_init)#define THREAD_SAFE() \	(_threads_initialized != 0)#define _SEM_CHECK_VALIDITY(sem)		\	if ((*(sem))->magic != SEM_MAGIC) {	\		errno = EINVAL;			\		retval = -1;			\		goto RETURN;			\	}/* End thread_private.h kluge */intsem_init(sem_t *sem, int pshared, unsigned int value){	int	retval;	if (!THREAD_SAFE())		THREAD_INIT();	/*	 * 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;	}	*sem = (sem_t)malloc(sizeof(struct sem));	if (*sem == NULL) {		errno = ENOSPC;		retval = -1;		goto RETURN;	}	/*	 * 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;}intsem_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;	}	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;}sem_t *sem_open(const char *name, int oflag, ...){	errno = ENOSYS;	return SEM_FAILED;}intsem_close(sem_t *sem){	errno = ENOSYS;	return -1;}intsem_unlink(const char *name){	errno = ENOSYS;	return -1;}intsem_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--;	}	(*sem)->count--;	pthread_mutex_unlock(&(*sem)->lock);	retval = 0;  RETURN:	pthread_testcancel();	return retval;}intsem_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;	}		pthread_mutex_unlock(&(*sem)->lock);  RETURN:	return retval;}intsem_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;}intsem_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;}/* END of inlined uthread_sem.c */#endif /* SDL_USE_PTHREADS */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -