Line data Source code
1 : /* gen-posix-lock-obj.c - Build tool to construct the lock object.
2 : Copyright (C) 2014 g10 Code GmbH
3 :
4 : This file is part of libgpg-error.
5 :
6 : libgpg-error is free software; you can redistribute it and/or
7 : modify it under the terms of the GNU Lesser General Public License
8 : as published by the Free Software Foundation; either version 2.1 of
9 : the License, or (at your option) any later version.
10 :
11 : libgpg-error is distributed in the hope that it will be useful, but
12 : WITHOUT ANY WARRANTY; without even the implied warranty of
13 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : Lesser General Public License for more details.
15 :
16 : You should have received a copy of the GNU Lesser General Public
17 : License along with this program; if not, see <https://www.gnu.org/licenses/>.
18 : */
19 :
20 : #if HAVE_CONFIG_H
21 : #include <config.h>
22 : #endif
23 :
24 : #ifdef HAVE_W32_SYSTEM
25 : # error This module may not be build for Windows.
26 : #endif
27 :
28 : #include <stdlib.h>
29 : #include <string.h>
30 : #include <stdio.h>
31 : #include <errno.h>
32 : #ifdef USE_POSIX_THREADS
33 : # include <pthread.h>
34 : #endif
35 :
36 : #include "posix-lock-obj.h"
37 :
38 : #define PGM "gen-posix-lock-obj"
39 :
40 : /* Check that configure did its job. */
41 : #ifdef USE_POSIX_THREADS
42 : #if SIZEOF_PTHREAD_MUTEX_T < 4
43 : # error sizeof pthread_mutex_t is not known.
44 : #endif
45 : #endif
46 :
47 : /* Special requirements for certain platforms. */
48 : # define USE_LONG_DOUBLE_FOR_ALIGNMENT 0
49 : #if defined(__sun) && !defined (__LP64__) && !defined(_LP64)
50 : /* Solaris on 32-bit architecture. */
51 : # define USE_DOUBLE_FOR_ALIGNMENT 1
52 : #else
53 : # define USE_DOUBLE_FOR_ALIGNMENT 0
54 : #endif
55 : #if defined(__hppa__)
56 : # define USE_16BYTE_ALIGNMENT 1
57 : #else
58 : # define USE_16BYTE_ALIGNMENT 0
59 : #endif
60 :
61 : #if USE_16BYTE_ALIGNMENT && !HAVE_GCC_ATTRIBUTE_ALIGNED
62 : # error compiler is not able to enforce a 16 byte alignment
63 : #endif
64 :
65 : #ifdef USE_POSIX_THREADS
66 : static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
67 : #endif
68 :
69 : int
70 1 : main (void)
71 : {
72 : #ifdef USE_POSIX_THREADS
73 : unsigned char *p;
74 : int i;
75 : #endif
76 : struct {
77 : long vers;
78 : #ifdef USE_POSIX_THREADS
79 : pthread_mutex_t mtx;
80 : #endif
81 : } dummyobj;
82 :
83 :
84 : #ifdef USE_POSIX_THREADS
85 : if (sizeof mtx != SIZEOF_PTHREAD_MUTEX_T)
86 : {
87 : fprintf (stderr, PGM ": pthread_mutex_t mismatch\n");
88 : exit (1);
89 : }
90 : #endif /*USE_POSIX_THREADS*/
91 :
92 : if (sizeof (dummyobj) != sizeof (_gpgrt_lock_t))
93 : {
94 : fprintf (stderr, PGM ": internal and external lock object mismatch\n");
95 : exit (1);
96 : }
97 :
98 1 : printf ("## lock-obj-pub.%s.h%s\n"
99 : "## File created by " PGM " - DO NOT EDIT\n"
100 : "## To be included by mkheader into gpg-error.h\n"
101 : "\n",
102 : HOST_TRIPLET_STRING,
103 : #ifdef USE_POSIX_THREADS
104 : ""
105 : #else
106 : " - NO LOCK SUPPORT"
107 : #endif
108 : );
109 :
110 : #ifdef USE_POSIX_THREADS
111 :
112 : /* To force a probably suitable alignment of the structure we use a
113 : union and include a long and a pointer to a long. */
114 1 : printf ("typedef struct\n"
115 : "{\n"
116 : " long _vers;\n"
117 : " union {\n"
118 : " volatile char _priv[%d];\n"
119 : "%s"
120 : " long _x_align;\n"
121 : " long *_xp_align;\n"
122 : " } u;\n"
123 : "} gpgrt_lock_t;\n"
124 : "\n"
125 : "#define GPGRT_LOCK_INITIALIZER {%d,{{",
126 : SIZEOF_PTHREAD_MUTEX_T,
127 : # if USE_16BYTE_ALIGNMENT
128 : " int _x16_align __attribute__ ((aligned (16)));\n",
129 : # elif USE_DOUBLE_FOR_ALIGNMENT
130 : " double _xd_align;\n",
131 : # elif USE_LONG_DOUBLE_FOR_ALIGNMENT
132 : " long double _xld_align;\n",
133 : # else
134 : "",
135 : # endif
136 : LOCK_ABI_VERSION);
137 : p = (unsigned char *)&mtx;
138 41 : for (i=0; i < sizeof mtx; i++)
139 : {
140 40 : if (i && !(i % 8))
141 4 : printf (" \\\n%*s", 36, "");
142 40 : printf ("%u", p[i]);
143 40 : if (i < sizeof mtx - 1)
144 : putchar (',');
145 : }
146 1 : fputs ("}}}\n", stdout);
147 :
148 : #else /*!USE_POSIX_THREADS*/
149 :
150 : printf ("/* Dummy object - no locking available. */\n"
151 : "typedef struct\n"
152 : "{\n"
153 : " long _vers;\n"
154 : "} gpgrt_lock_t;\n"
155 : "\n"
156 : "#define GPGRT_LOCK_INITIALIZER {%d}\n",
157 : LOCK_ABI_VERSION);
158 :
159 : #endif /*!USE_POSIX_THREADS*/
160 :
161 1 : fputs ("##\n"
162 : "## Loc" "al Variables:\n"
163 : "## mode: c\n"
164 : "## buffer-read-only: t\n"
165 : "## End:\n"
166 : "##\n", stdout);
167 :
168 1 : if (ferror (stdout))
169 : {
170 0 : fprintf (stderr, PGM ": error writing to stdout: %s\n", strerror (errno));
171 0 : return 1;
172 : }
173 :
174 : return 0;
175 : }
|