/* Copyright (C) 1998 artofcode LLC. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA, 02111-1307. */ /*$Id: gxsync.c,v 1.2.6.1.2.1 2003/01/17 00:49:04 giles Exp $ */ /* Interface to platform-based synchronization primitives */ /* Initial version 2/1/98 by John Desrosiers (soho@crl.com) */ #include "memory_.h" #include "gx.h" #include "gserrors.h" #include "gsmemory.h" #include "gxsync.h" /* This module abstracts the platform-specific synchronization primitives. */ /* Since these routines will see heavy use, performance is important. */ /* ----- Semaphore interface ----- */ /* These have the usual queued, counting semaphore semantics: at init time, */ /* the event count is set to 0 ('wait' will wait until 1st signal). */ /* Allocate & initialize a semaphore */ gx_semaphore_t * /* returns a new semaphore, 0 if error */ gx_semaphore_alloc( gs_memory_t * memory /* memory allocator to use */ ) { gx_semaphore_t *sema; /* sizeof decl'd sema struct, minus semaphore placeholder's size, + actual semaphore size */ unsigned semaSizeof = sizeof(*sema) - sizeof(sema->native) + gp_semaphore_sizeof(); if (gp_semaphore_open(0) == 0) /* see if gp_semaphores are movable */ /* movable */ sema = (gx_semaphore_t *) gs_alloc_bytes(memory, semaSizeof, "gx_semaphore (create)"); else /* unmovable */ sema = (gx_semaphore_t *) gs_alloc_bytes_immovable(memory, semaSizeof, "gx_semaphore (create)"); if (sema == 0) return 0; /* Make sema remember which allocator was used to allocate it */ sema->memory = memory; if (gp_semaphore_open(&sema->native) < 0) { gs_free_object(memory, sema, "gx_semaphore (alloc)"); return 0; } return sema; } /* Deinit & free a semaphore */ void gx_semaphore_free( gx_semaphore_t * sema /* semaphore to delete */ ) { if (sema) { gp_semaphore_close(&sema->native); gs_free_object(sema->memory, sema, "gx_semaphore (free)"); } } /* Macros defined in gxsync.h, but redefined here so compiler chex consistency */ #define gx_semaphore_wait(sema) gp_semaphore_wait(&(sema)->native) #define gx_semaphore_signal(sema) gp_semaphore_signal(&(sema)->native) /* ----- Monitor interface ----- */ /* These have the usual monitor semantics: at init time, */ /* the event count is set to 1 (1st 'enter' succeeds immediately). */ /* Allocate & Init a monitor */ gx_monitor_t * /* returns a new monitor, 0 if error */ gx_monitor_alloc( gs_memory_t * memory /* memory allocator to use */ ) { gx_monitor_t *mon; /* sizeof decl'd mon struct, minus monitor placeholder's size, + actual monitor size */ unsigned monSizeof = sizeof(*mon) - sizeof(mon->native) + gp_monitor_sizeof(); if (gp_monitor_open(0) == 0) /* see if gp_monitors are movable */ /* movable */ mon = (gx_monitor_t *) gs_alloc_bytes(memory, monSizeof, "gx_monitor (create)"); else /* unmovable */ mon = (gx_monitor_t *) gs_alloc_bytes_immovable(memory, monSizeof, "gx_monitor (create)"); if (mon == 0) return 0; /* Make monitor remember which allocator was used to allocate it */ mon->memory = memory; if (gp_monitor_open(&mon->native) < 0) { gs_free_object(memory, mon, "gx_monitor (alloc)"); return 0; } return mon; } /* Dnit & free a monitor */ void gx_monitor_free( gx_monitor_t * mon /* monitor to delete */ ) { if (mon) { gp_monitor_close(&mon->native); gs_free_object(mon->memory, mon, "gx_monitor (free)"); } } /* Macros defined in gxsync.h, but redefined here so compiler chex consistency */ #define gx_monitor_enter(sema) gp_monitor_enter(&(sema)->native) #define gx_monitor_leave(sema) gp_monitor_leave(&(sema)->native)