1 /****************************************
2 * Computer Algebra System SINGULAR *
3 ****************************************/
4 /***************************************************************
5 * File: p_Procs_Dynamic.cc
6 * Purpose: source for dynamically loaded version of p_Procs
7 * Author: obachman (Olaf Bachmann)
8 * Created: 12/00
9 *******************************************************************/
10 #include "misc/auxiliary.h"
11
12 #include "factory/factory.h"
13
14 #include "reporter/reporter.h"
15
16 #include "polys/monomials/ring.h"
17 #include "polys/monomials/p_polys.h"
18
19 #include "polys/kbuckets.h"
20
21 #include "polys/templates/p_Numbers.h"
22
23 #include "polys/templates/p_Procs.h"
24 #include "polys/templates/p_MemCmp.h"
25 #include "polys/templates/p_MemAdd.h"
26 #include "polys/templates/p_MemCopy.h"
27
28
29 #ifdef HAVE_DL
30 const BOOLEAN p_procs_dynamic = TRUE;
31
32 #define WARN_MSG "Singular will work properly, but much slower."
33
34 // need external linkage, so that dynl_sym works
35 #undef LINKAGE
36 #define LINKAGE extern "C"
37 #define p_Procs_Kernel
38
39 #include "templates/p_Procs.inc"
40
41 #include "templates/p_Procs_Dynamic.h"
42 // include general p_Proc stuff
43 #include "templates/p_Procs_Impl.h"
44
45 #include "mod_raw.h"
46
47 // define to bound for length of p_Proc name
48 #define MAX_PROCNAME_LEN 200
49
50 void* p_procs_handle_FieldIndep = NULL;
51 void* p_procs_handle_FieldZp = NULL;
52 void* p_procs_handle_FieldQ = NULL;
53 void* p_procs_handle_FieldGeneral = NULL;
54
p_ProcInitHandle(void ** handle,const char * module)55 static void* p_ProcInitHandle(void** handle, const char* module)
56 {
57 if (*handle == NULL)
58 {
59 char name[25];
60 sprintf(name, "p_Procs_%s", module);
61 *handle = dynl_open_binary_warn(name, WARN_MSG);
62 }
63 return *handle;
64 }
65
p_ProcGetHandle(p_Proc proc,p_Field field)66 static inline void* p_ProcGetHandle(p_Proc proc, p_Field field)
67 {
68 const char* module = p_ProcField_2_Module(proc, field);
69
70 if (strcmp(module, "FieldIndep") == 0)
71 return p_ProcInitHandle(&p_procs_handle_FieldIndep, module);
72 else if (strcmp(module, "FieldZp") == 0)
73 return p_ProcInitHandle(&p_procs_handle_FieldZp, module);
74 else if (strcmp(module, "FieldQ") == 0)
75 return p_ProcInitHandle(&p_procs_handle_FieldQ, module);
76 else if (strcmp(module, "FieldGeneral") == 0)
77 return p_ProcInitHandle(&p_procs_handle_FieldGeneral, module);
78 else
79 {
80 assume(0);
81 return NULL;
82 }
83 }
84
85
GetGeneralProc(p_Proc proc)86 static void* GetGeneralProc(p_Proc proc)
87 {
88 switch(proc)
89 {
90 case p_Copy_Proc:
91 return cast_A_to_vptr(p_Copy__FieldGeneral_LengthGeneral_OrdGeneral);
92 case p_Delete_Proc:
93 return cast_A_to_vptr(p_Delete__FieldGeneral_LengthGeneral_OrdGeneral);
94 case p_ShallowCopyDelete_Proc:
95 return cast_A_to_vptr(p_ShallowCopyDelete__FieldGeneral_LengthGeneral_OrdGeneral);
96 case p_Add_q_Proc:
97 return cast_A_to_vptr(p_Add_q__FieldGeneral_LengthGeneral_OrdGeneral);
98 case p_Neg_Proc:
99 return cast_A_to_vptr(p_Neg__FieldGeneral_LengthGeneral_OrdGeneral);
100 case p_Merge_q_Proc:
101 return cast_A_to_vptr(p_Merge_q__FieldGeneral_LengthGeneral_OrdGeneral);
102 case p_kBucketSetLm_Proc:
103 return cast_A_to_vptr(p_kBucketSetLm__FieldGeneral_LengthGeneral_OrdGeneral);
104 #ifdef HAVE_RINGS
105 case p_Mult_nn_Proc:
106 return cast_A_to_vptr(p_Mult_nn__RingGeneral_LengthGeneral_OrdGeneral);
107 case pp_Mult_nn_Proc:
108 return cast_A_to_vptr(pp_Mult_nn__RingGeneral_LengthGeneral_OrdGeneral);
109 case pp_Mult_mm_Proc:
110 return cast_A_to_vptr(pp_Mult_mm__RingGeneral_LengthGeneral_OrdGeneral);
111 case pp_Mult_mm_Noether_Proc:
112 return cast_A_to_vptr(pp_Mult_mm_Noether__RingGeneral_LengthGeneral_OrdGeneral);
113 case p_Mult_mm_Proc:
114 return cast_A_to_vptr(p_Mult_mm__RingGeneral_LengthGeneral_OrdGeneral);
115 case p_Minus_mm_Mult_qq_Proc:
116 return cast_A_to_vptr(p_Minus_mm_Mult_qq__RingGeneral_LengthGeneral_OrdGeneral);
117 case pp_Mult_Coeff_mm_DivSelect_Proc:
118 return cast_A_to_vptr(pp_Mult_Coeff_mm_DivSelect__RingGeneral_LengthGeneral_OrdGeneral);
119 case pp_Mult_Coeff_mm_DivSelectMult_Proc:
120 return cast_A_to_vptr(pp_Mult_Coeff_mm_DivSelectMult__RingGeneral_LengthGeneral_OrdGeneral);
121 #else
122 case p_Mult_nn_Proc:
123 return cast_A_to_vptr(p_Mult_nn__FieldGeneral_LengthGeneral_OrdGeneral);
124 case pp_Mult_nn_Proc:
125 return cast_A_to_vptr(pp_Mult_nn__FieldGeneral_LengthGeneral_OrdGeneral);
126 case pp_Mult_mm_Proc:
127 return cast_A_to_vptr(pp_Mult_mm__FieldGeneral_LengthGeneral_OrdGeneral);
128 case pp_Mult_mm_Noether_Proc:
129 return cast_A_to_vptr(pp_Mult_mm_Noether__FieldGeneral_LengthGeneral_OrdGeneral);
130 case p_Mult_mm_Proc:
131 return cast_A_to_vptr(p_Mult_mm__FieldGeneral_LengthGeneral_OrdGeneral);
132 case p_Minus_mm_Mult_qq_Proc:
133 return cast_A_to_vptr(p_Minus_mm_Mult_qq__FieldGeneral_LengthGeneral_OrdGeneral);
134 case pp_Mult_Coeff_mm_DivSelect_Proc:
135 return cast_A_to_vptr(pp_Mult_Coeff_mm_DivSelect__FieldGeneral_LengthGeneral_OrdGeneral);
136 case pp_Mult_Coeff_mm_DivSelectMult_Proc:
137 return cast_A_to_vptr(pp_Mult_Coeff_mm_DivSelectMult__FieldGeneral_LengthGeneral_OrdGeneral);
138 #endif
139 case p_Unknown_Proc:
140 break;
141 }
142 dReportBug("p_Unknown_Proc");
143 return NULL;
144 }
145
146 #ifdef RDEBUG
GetGeneralProcName(p_Proc proc)147 static const char* GetGeneralProcName(p_Proc proc)
148 {
149 switch(proc)
150 {
151 case p_Copy_Proc:
152 return "p_Copy__FieldGeneral_LengthGeneral_OrdGeneral";
153 case p_Delete_Proc:
154 return "p_Delete__FieldGeneral_LengthGeneral_OrdGeneral";
155 case p_ShallowCopyDelete_Proc:
156 return "p_ShallowCopyDelete__FieldGeneral_LengthGeneral_OrdGeneral";
157 case p_Add_q_Proc:
158 return "p_Add_q__FieldGeneral_LengthGeneral_OrdGeneral";
159 case p_Neg_Proc:
160 return "p_Neg__FieldGeneral_LengthGeneral_OrdGeneral";
161 case p_Merge_q_Proc:
162 return "p_Merge_q__FieldGeneral_LengthGeneral_OrdGeneral";
163 case p_kBucketSetLm_Proc:
164 return "p_kBucketSetLm__FieldGeneral_LengthGeneral_OrdGeneral";
165 case p_Unknown_Proc:
166 break;
167 #ifdef HAVE_RINGS
168 case p_Mult_nn_Proc:
169 return "p_Mult_nn__RingGeneral_LengthGeneral_OrdGeneral";
170 case pp_Mult_nn_Proc:
171 return "pp_Mult_nn__RingGeneral_LengthGeneral_OrdGeneral";
172 case pp_Mult_mm_Proc:
173 return "pp_Mult_mm__RingGeneral_LengthGeneral_OrdGeneral";
174 case pp_Mult_mm_Noether_Proc:
175 return "pp_Mult_mm_Noether__RingGeneral_LengthGeneral_OrdGeneral";
176 case p_Mult_mm_Proc:
177 return "p_Mult_mm__RingGeneral_LengthGeneral_OrdGeneral";
178 case p_Minus_mm_Mult_qq_Proc:
179 return "p_Minus_mm_Mult_qq__RingGeneral_LengthGeneral_OrdGeneral";
180 case pp_Mult_Coeff_mm_DivSelect_Proc:
181 return "pp_Mult_Coeff_mm_DivSelect__RingGeneral_LengthGeneral_OrdGeneral";
182 case pp_Mult_Coeff_mm_DivSelectMult_Proc:
183 return "pp_Mult_Coeff_mm_DivSelectMult__RingGeneral_LengthGeneral_OrdGeneral";
184 #else
185 case p_Mult_nn_Proc:
186 return "p_Mult_nn__FieldGeneral_LengthGeneral_OrdGeneral";
187 case pp_Mult_nn_Proc:
188 return "pp_Mult_nn__FieldGeneral_LengthGeneral_OrdGeneral";
189 case pp_Mult_mm_Proc:
190 return "pp_Mult_mm__FieldGeneral_LengthGeneral_OrdGeneral";
191 case pp_Mult_mm_Noether_Proc:
192 return "pp_Mult_mm_Noether__FieldGeneral_LengthGeneral_OrdGeneral";
193 case p_Mult_mm_Proc:
194 return "p_Mult_mm__FieldGeneral_LengthGeneral_OrdGeneral";
195 case p_Minus_mm_Mult_qq_Proc:
196 return "p_Minus_mm_Mult_qq__FieldGeneral_LengthGeneral_OrdGeneral";
197 case pp_Mult_Coeff_mm_DivSelect_Proc:
198 return "pp_Mult_Coeff_mm_DivSelect__FieldGeneral_LengthGeneral_OrdGeneral";
199 case pp_Mult_Coeff_mm_DivSelectMult_Proc:
200 return "pp_Mult_Coeff_mm_DivSelectMult__FieldGeneral_LengthGeneral_OrdGeneral";
201 #endif
202 }
203 return "p_Unknown_Proc";
204 }
205 #endif
206
207
GetDynamicProc(const char * proc_s,p_Proc proc,p_Field field,p_Length length,p_Ord ord,int get_name=0)208 static void* GetDynamicProc(const char* proc_s, p_Proc proc,
209 p_Field field, p_Length length, p_Ord ord
210 #ifdef RDEBUG
211 , int get_name = 0
212 #endif
213 )
214 {
215 void* proc_ptr = NULL;
216 char proc_name[MAX_PROCNAME_LEN];
217 sprintf(proc_name, "%s__%s_%s_%s", proc_s,
218 p_FieldEnum_2_String(field),
219 p_LengthEnum_2_String(length),
220 p_OrdEnum_2_String(ord));
221 // printf("set %s\n",proc_name);
222 // first, try to get the proc from the kernel
223 proc_ptr = dynl_sym(DYNL_KERNEL_HANDLE, proc_name);
224 if (proc_ptr == NULL)
225 {
226 proc_ptr = dynl_sym_warn(p_ProcGetHandle(proc, field), proc_name, WARN_MSG);
227 // last but not least use general proc
228 if (proc_ptr == NULL)
229 {
230 proc_ptr = GetGeneralProc(proc);
231 #ifdef RDEBUG
232 sprintf(proc_name,"%s", GetGeneralProcName(proc));
233 #endif
234 }
235 }
236 #ifdef RDEBUG
237 if (get_name)
238 {
239 char* name = omStrDup(proc_name);
240 #if (!defined(SING_NDEBUG)) && (!defined(OM_NDEBUG))
241 omMarkAsStaticAddr(name);
242 #endif
243 return (void*) name;
244 }
245 #endif
246 return proc_ptr;
247 }
248
249
250 #define DoReallySetProc(what, field, length, ord) \
251 _p_procs->what = cast_vptr_to_A<what##_Proc_Ptr>( \
252 GetDynamicProc(#what, what##_Proc, field, length, ord))
253
254 #ifdef RDEBUG
255 #define DoSetProc(what, field, length, ord) \
256 do \
257 { \
258 if (set_names) \
259 _p_procs->what = cast_vptr_to_A<what##_Proc_Ptr>( \
260 GetDynamicProc(#what, what##_Proc, field, length, ord, 1)); \
261 else \
262 DoReallySetProc(what, field, length, ord); \
263 } \
264 while(0)
265 #else
266 #define DoSetProc DoReallySetProc
267 #endif
268
269 #include "templates/p_Procs_Set.h"
270
271 #endif
272
273