1 /* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
2
3 This software is provided AS-IS with no warranty, either express or
4 implied.
5
6 This software is distributed under license and may not be copied,
7 modified or distributed except as expressly authorized under the terms
8 of the license contained in the file LICENSE in this distribution.
9
10 For more information about licensing, please refer to
11 http://www.ghostscript.com/licensing/. For information on
12 commercial licensing, go to http://www.artifex.com/licensing/ or
13 contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14 San Rafael, CA 94903, U.S.A., +1(415)492-9861.
15 */
16
17 /* $Id: gxsync.c,v 1.4 2002/02/21 22:24:53 giles Exp $ */
18 /* Interface to platform-based synchronization primitives */
19
20 /* Initial version 2/1/98 by John Desrosiers (soho@crl.com) */
21
22 #include "memory_.h"
23 #include "gx.h"
24 #include "gserrors.h"
25 #include "gsmemory.h"
26 #include "gxsync.h"
27
28 /* This module abstracts the platform-specific synchronization primitives. */
29 /* Since these routines will see heavy use, performance is important. */
30
31
32 /* ----- Semaphore interface ----- */
33 /* These have the usual queued, counting semaphore semantics: at init time, */
34 /* the event count is set to 0 ('wait' will wait until 1st signal). */
35
36 /* Allocate & initialize a semaphore */
37 gx_semaphore_t * /* returns a new semaphore, 0 if error */
gx_semaphore_alloc(gs_memory_t * memory)38 gx_semaphore_alloc(
39 gs_memory_t * memory /* memory allocator to use */
40 )
41 {
42 gx_semaphore_t *sema;
43
44 /* sizeof decl'd sema struct, minus semaphore placeholder's size, + actual semaphore size */
45 unsigned semaSizeof
46 = sizeof(*sema) - sizeof(sema->native) + gp_semaphore_sizeof();
47
48 if (gp_semaphore_open(0) == 0) /* see if gp_semaphores are movable */
49 /* movable */
50 sema = (gx_semaphore_t *) gs_alloc_bytes(memory, semaSizeof,
51 "gx_semaphore (create)");
52 else
53 /* unmovable */
54 sema = (gx_semaphore_t *) gs_alloc_bytes_immovable(memory, semaSizeof,
55 "gx_semaphore (create)");
56 if (sema == 0)
57 return 0;
58
59 /* Make sema remember which allocator was used to allocate it */
60 sema->memory = memory;
61
62 if (gp_semaphore_open(&sema->native) < 0) {
63 gs_free_object(memory, sema, "gx_semaphore (alloc)");
64 return 0;
65 }
66 return sema;
67 }
68
69 /* Deinit & free a semaphore */
70 void
gx_semaphore_free(gx_semaphore_t * sema)71 gx_semaphore_free(
72 gx_semaphore_t * sema /* semaphore to delete */
73 )
74 {
75 if (sema) {
76 gp_semaphore_close(&sema->native);
77 gs_free_object(sema->memory, sema, "gx_semaphore (free)");
78 }
79 }
80
81 /* Macros defined in gxsync.h, but redefined here so compiler chex consistency */
82 #define gx_semaphore_wait(sema) gp_semaphore_wait(&(sema)->native)
83 #define gx_semaphore_signal(sema) gp_semaphore_signal(&(sema)->native)
84
85
86 /* ----- Monitor interface ----- */
87 /* These have the usual monitor semantics: at init time, */
88 /* the event count is set to 1 (1st 'enter' succeeds immediately). */
89
90 /* Allocate & Init a monitor */
91 gx_monitor_t * /* returns a new monitor, 0 if error */
gx_monitor_alloc(gs_memory_t * memory)92 gx_monitor_alloc(
93 gs_memory_t * memory /* memory allocator to use */
94 )
95 {
96 gx_monitor_t *mon;
97
98 /* sizeof decl'd mon struct, minus monitor placeholder's size, + actual monitor size */
99 unsigned monSizeof
100 = sizeof(*mon) - sizeof(mon->native) + gp_monitor_sizeof();
101
102 if (gp_monitor_open(0) == 0) /* see if gp_monitors are movable */
103 /* movable */
104 mon = (gx_monitor_t *) gs_alloc_bytes(memory, monSizeof,
105 "gx_monitor (create)");
106 else
107 /* unmovable */
108 mon = (gx_monitor_t *) gs_alloc_bytes_immovable(memory, monSizeof,
109 "gx_monitor (create)");
110 if (mon == 0)
111 return 0;
112
113 /* Make monitor remember which allocator was used to allocate it */
114 mon->memory = memory;
115
116 if (gp_monitor_open(&mon->native) < 0) {
117 gs_free_object(memory, mon, "gx_monitor (alloc)");
118 return 0;
119 }
120 return mon;
121 }
122
123 /* Dnit & free a monitor */
124 void
gx_monitor_free(gx_monitor_t * mon)125 gx_monitor_free(
126 gx_monitor_t * mon /* monitor to delete */
127 )
128 {
129 if (mon) {
130 gp_monitor_close(&mon->native);
131 gs_free_object(mon->memory, mon, "gx_monitor (free)");
132 }
133 }
134
135 /* Macros defined in gxsync.h, but redefined here so compiler chex consistency */
136 #define gx_monitor_enter(sema) gp_monitor_enter(&(sema)->native)
137 #define gx_monitor_leave(sema) gp_monitor_leave(&(sema)->native)
138