All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Plumed.c
Go to the documentation of this file.
1 /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2  Copyright (c) 2013 The plumed team
3  (see the PEOPLE file at the root of the distribution for a list of names)
4 
5  See http://www.plumed-code.org for more information.
6 
7  This file is part of plumed, version 2.0.
8 
9  plumed is free software: you can redistribute it and/or modify
10  it under the terms of the GNU Lesser General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  (at your option) any later version.
13 
14  plumed is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU Lesser General Public License for more details.
18 
19  You should have received a copy of the GNU Lesser General Public License
20  along with plumed. If not, see <http://www.gnu.org/licenses/>.
21 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
22 #ifdef __PLUMED_HAS_DLOPEN
23 #include <dlfcn.h>
24 #endif
25 
26 #include "Plumed.h"
27 #include <stdio.h>
28 #include <assert.h>
29 #include <stdlib.h>
30 #include <limits.h>
31 
32 /* DECLARATION USED ONLY IN THIS FILE */
33 
34 #ifdef __cplusplus
35  extern "C" {
36 #endif
37 
38 /**
39  Holder for plumedmain function pointers.
40 */
41 typedef struct {
42  void*(*create)(void);
43  void(*cmd)(void*,const char*,const void*);
44  void(*finalize)(void*);
46 
47 /**
48  Register for plumedmain function pointers
49 */
51 
52 #ifdef __PLUMED_STATIC_KERNEL
53 /* Real interface */
54 void*plumedmain_create(void);
55 void plumedmain_cmd(void*,const char*,const void*);
56 void plumedmain_finalize(void*);
57 #else
58 /* dummy interface */
59 void*plumed_dummy_create(void);
60 void plumed_dummy_cmd(void*,const char*,const void*);
61 void plumed_dummy_finalize(void*);
62 #endif
63 
64 #ifdef __cplusplus
65  }
66 #endif
67 
68 /* END OF DECLARATION USED ONLY IN THIS FILE */
69 
70 /* These are the dummy routines which are used when plumed is not available */
71 
72 #ifdef __PLUMED_STATIC_KERNEL
73 
74 static int installed=1;
75 
76 #else
77 
78 static int installed=0;
79 
80 static int dummy;
81 
83  return (void*)&dummy;
84 }
85 
86 void plumed_dummy_cmd(void*p,const char*key,const void*val){
87  (void) p; /* avoid warning on unused parameter */
88  (void) key; /* avoid warning on unused parameter */
89  (void) val; /* avoid warning on unused parameter */
90  fprintf(stderr,"+++ ERROR: you are trying to use plumed, but it is not available +++\n");
91  fprintf(stderr,"+++ Check your PLUMED_KERNEL environment variable +++\n");
92  exit(1);
93 }
94 
95 void plumed_dummy_finalize(void*p){
96  (void) p; /* avoid warning on unused parameter */
97 }
98 
99 #endif
100 
102 #ifdef __PLUMED_STATIC_KERNEL
103 /*
104  When __PLUMED_STATIC_KERNEL is defined, the function holder is initialized
105  to statically bound plumedmain_create,plumedmain_cmd,plumedmain_finalize and
106  cannot be changed. This saves from mis-set values for PLUMED_KERNEL
107 */
109  (void) f; /* avoid warning on unused parameter */
110  return &g;
111 #else
112 /*
113  On the other hand, for runtime binding, we allow to reset the function holder on the
114  first call to plumed_kernel_register.
115  Notice that in principle plumed_kernel_register is entered *twice*: one for the first
116  plumed usage, and then from the PlumedMainInitializer object of the shared library.
117  This is why we set "first=0" only *after* loading the shared library.
118  Also notice that we should put some guard here for safe multithread calculations.
119 */
121  static int first=1;
122 #ifdef __PLUMED_HAS_DLOPEN
123  char* path;
124  void* p;
125  if(first && f==NULL){
126  path=getenv("PLUMED_KERNEL");
127  if(path && (*path)){
128  fprintf(stderr,"+++ Loading the PLUMED kernel runtime +++\n");
129  fprintf(stderr,"+++ PLUMED_KERNEL=\"%s\" +++\n",path);
130  p=dlopen(path,RTLD_NOW|RTLD_GLOBAL);
131  if(p){
132  fprintf(stderr,"+++ PLUMED kernel successfully loaded +++\n");
133  installed=1;
134  } else{
135  fprintf(stderr,"+++ PLUMED kernel not found ! +++\n");
136  fprintf(stderr,"+++ error message from dlopen(): %s\n",dlerror());
137  }
138  }
139  }
140 #endif
141  first=0;
142  if(f) g=*f;
143  return &g;
144 #endif
145 }
146 
147 /* C wrappers: */
148 
150  plumed p;
151  p.p=(*(plumed_kernel_register(NULL)->create))();
152  return p;
153 }
154 
155 void plumed_cmd(plumed p,const char*key,const void*val){
156  (*(plumed_kernel_register(NULL)->cmd))(p.p,key,val);
157 }
158 
160  (*(plumed_kernel_register(NULL)->finalize))(p.p);
161 }
162 
165  return installed;
166 }
167 
168 /* we declare a Plumed_g_main object here, in such a way that it is always available */
169 
170 static plumed gmain={NULL};
171 
173  return gmain;
174 }
175 
176 void plumed_gcreate(void){
177  assert(gmain.p==NULL);
178  gmain=plumed_create();
179 }
180 
181 void plumed_gcmd(const char*key,const void*val){
182  plumed_cmd(gmain,key,val);
183 }
184 
185 void plumed_gfinalize(void){
186  plumed_finalize(gmain);
187  gmain.p=NULL;
188 }
189 
191  if(gmain.p) return 1;
192  else return 0;
193 }
194 
195 void plumed_c2f(plumed p,char*c){
196  unsigned i;
197  unsigned char* cc;
198 /*
199  Convert the address stored in p.p into a proper FORTRAN string
200  made of only ASCII characters. For this to work, the two following
201  assertions should be satisfied:
202 */
203  assert(CHAR_BIT<=12);
204  assert(sizeof(p.p)<=16);
205 
206  assert(c);
207  cc=(unsigned char*)&p.p;
208  for(i=0;i<sizeof(p.p);i++){
209 /*
210  characters will range between '0' (ASCII 48) and 'o' (ASCII 111=48+63)
211 */
212  c[2*i]=cc[i]/64+48;
213  c[2*i+1]=cc[i]%64+48;
214  }
215 }
216 
217 plumed plumed_f2c(const char*c){
218  plumed p;
219  unsigned i;
220  unsigned char* cc;
221 
222  assert(CHAR_BIT<=12);
223  assert(sizeof(p.p)<=16);
224 
225  assert(c);
226  cc=(unsigned char*)&p.p;
227  for(i=0;i<sizeof(p.p);i++){
228 /*
229  perform the reversed transform
230 */
231  cc[i]=(c[2*i]-48)*64 + (c[2*i+1]-48);
232  }
233  return p;
234 }
235 
236 
237 #ifdef __cplusplus
238  extern "C" {
239 #endif
240 
241 /*
242  Fortran wrappers
243  These are just like the global C wrappers. They are
244  just defined here and not declared in the .h file since they
245  should not be used from c/c++ anyway.
246 */
247 
248 /*
249  First we assume no name mangling
250 */
251 
252 void plumed_f_installed(int*i){
253  *i=plumed_installed();
254 }
255 
257  *i=plumed_ginitialized();
258 }
259 
260 void plumed_f_gcreate(void){
261  plumed_gcreate();
262 }
263 
264 void plumed_f_gcmd(char*key,void*val){
265  plumed_gcmd(key,val);
266 }
267 
270 }
271 
272 void plumed_f_create(char*c){
273  plumed p;
274  p=plumed_create();
275  plumed_c2f(p,c);
276 }
277 
278 void plumed_f_cmd(char*c,char*key,void*val){
279  plumed p;
280  p=plumed_f2c(c);
281  plumed_cmd(p,key,val);
282 }
283 
284 void plumed_f_finalize(char*c){
285  plumed p;
286  p=plumed_f2c(c);
287  plumed_finalize(p);
288 }
289 
290 void plumed_f_global(char*c){
291  plumed_c2f(gmain,c);
292 }
293 
294 /*
295  Then we add wrappers for there functions to cover all
296  the possible fortran mangling schemes, which should be:
297  without underscore, with one underscore and with two underscores
298  lower or upper case
299 */
300 
301 #define IMPLEMENT(lower,upper,implem) \
302  void lower ##_ implem \
303  void lower ##__ implem \
304  void upper implem \
305  void upper ##_ implem \
306  void upper ##__ implem
307 
308 IMPLEMENT(plumed_f_gcreate, PLUMED_F_GCREATE, (void){plumed_f_gcreate();})
309 IMPLEMENT(plumed_f_gcmd, PLUMED_F_GCMD, (char* key,void* val){plumed_f_gcmd(key,val);})
310 IMPLEMENT(plumed_f_gfinalize, PLUMED_F_GFINALIZE, (void){plumed_f_gfinalize();})
311 IMPLEMENT(plumed_f_ginitialized,PLUMED_F_GINITIALIZED,(int*i){plumed_f_ginitialized(i);})
312 IMPLEMENT(plumed_f_create, PLUMED_F_CREATE, (char*c){plumed_f_create(c);})
313 IMPLEMENT(plumed_f_cmd, PLUMED_F_CMD, (char*c,char* key,void* val){plumed_f_cmd(c,key,val);})
314 IMPLEMENT(plumed_f_finalize, PLUMED_F_FINALIZE, (char*c){plumed_f_finalize(c);})
315 IMPLEMENT(plumed_f_installed, PLUMED_F_INSTALLED, (int*i){plumed_f_installed(i);})
316 IMPLEMENT(plumed_f_global, PLUMED_F_GLOBAL, (char*c){plumed_f_global(c);})
317 
318 #ifdef __cplusplus
319 }
320 #endif
321 
322 
323 
324 
plumed plumed_global(void)
Retrieves an handler to the global structure.
Definition: Plumed.c:172
plumed_plumedmain_function_holder * plumed_kernel_register(const plumed_plumedmain_function_holder *)
Register for plumedmain function pointers.
Definition: Plumed.c:101
int plumed_ginitialized(void)
Check if the global interface has been initialized.
Definition: Plumed.c:190
plumed plumed_f2c(const char *c)
Converts a FORTRAN handler to a C handler.
Definition: Plumed.c:217
void plumed_f_finalize(char *c)
Definition: Plumed.c:284
int plumed_installed(void)
Check if plumed is installed (for runtime binding)
Definition: Plumed.c:163
void plumed_f_gcreate(void)
Definition: Plumed.c:260
static int installed
Definition: Plumed.c:78
void plumed_f_cmd(char *c, char *key, void *val)
Definition: Plumed.c:278
void plumed_f_create(char *c)
Definition: Plumed.c:272
void plumed_f_ginitialized(int *i)
Definition: Plumed.c:256
#define IMPLEMENT(lower, upper, implem)
Definition: Plumed.c:301
Container for plumedmain function pointers (create, cmd and finalize).
void * plumed_dummy_create(void)
Definition: Plumed.c:82
void plumed_f_gfinalize(void)
Definition: Plumed.c:268
void plumedmain_finalize(void *plumed)
void * p
Void pointer holding the real PlumedMain structure.
Definition: Plumed.h:206
void plumedmain_cmd(void *plumed, const char *key, const void *val)
void plumed_cmd(plumed p, const char *key, const void *val)
Tells p to execute a command.
Definition: Plumed.c:155
void plumed_f_installed(int *i)
Definition: Plumed.c:252
void plumed_dummy_cmd(void *, const char *, const void *)
Definition: Plumed.c:86
static int dummy
Definition: Plumed.c:80
void plumed_c2f(plumed p, char *c)
Converts a C handler to a FORTRAN handler.
Definition: Plumed.c:195
void plumed_dummy_finalize(void *)
Definition: Plumed.c:95
static plumed gmain
Definition: Plumed.c:170
Main plumed object.
Definition: Plumed.h:201
plumed plumed_create(void)
Constructor.
Definition: Plumed.c:149
void * plumedmain_create()
void plumed_f_gcmd(char *key, void *val)
Definition: Plumed.c:264
void plumed_gcmd(const char *key, const void *val)
Tells to the global interface to execute a command.
Definition: Plumed.c:181
void(* cmd)(void *, const char *, const void *)
void plumed_gfinalize(void)
Destructor for the global interface.
Definition: Plumed.c:185
void plumed_finalize(plumed p)
Destructor.
Definition: Plumed.c:159
void plumed_gcreate(void)
Constructor for the global interface.
Definition: Plumed.c:176
void plumed_f_global(char *c)
Definition: Plumed.c:290