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