Annotation of OpenXM/src/ox_gsl/ox_gsl.c, Revision 1.10
1.10 ! ohara 1: /* $OpenXM: OpenXM/src/ox_gsl/ox_gsl.c,v 1.9 2018/04/18 02:20:51 takayama Exp $
1.1 takayama 2: */
3:
4: #include <stdio.h>
5: #include <stdlib.h>
1.2 takayama 6: #include <setjmp.h>
7: #include <string.h>
1.3 takayama 8: #include <unistd.h>
1.10 ! ohara 9: #include <signal.h>
1.3 takayama 10: #include <math.h>
11: #include "ox_gsl.h"
12: #include "call_gsl.h" // need only when you bind call_gsl functions.
1.1 takayama 13:
14: OXFILE *fd_rw;
15:
16: #define INIT_S_SIZE 2048
17: #define EXT_S_SIZE 2048
18:
19: static int stack_size = 0;
20: static int stack_pointer = 0;
21: static cmo **stack = NULL;
22:
23: int Debug=1;
24:
1.2 takayama 25: void show_stack_top() {
1.1 takayama 26: cmo *data;
27: if (stack_pointer > 0) {
28: data=stack[stack_pointer-1];
1.2 takayama 29: print_cmo(data); printf("\n");
1.1 takayama 30: }else {
31: printf("The stack is empty.\n");
32: }
33: }
34:
1.3 takayama 35: void *gc_realloc(void *p,size_t osize,size_t nsize)
36: { return (void *)GC_realloc(p,nsize);}
37:
38: void gc_free(void *p,size_t size)
39: { GC_free(p);}
40:
1.1 takayama 41: void init_gc()
1.3 takayama 42: { GC_INIT();
43: mp_set_memory_functions(GC_malloc,gc_realloc,gc_free);
1.5 takayama 44: init_dic(); // initialize ox_eval.c
1.1 takayama 45: }
46:
1.2 takayama 47: void initialize_stack()
1.1 takayama 48: {
49: stack_pointer = 0;
50: stack_size = INIT_S_SIZE;
1.3 takayama 51: stack = GC_malloc(stack_size*sizeof(cmo*));
1.1 takayama 52: }
53:
1.2 takayama 54: static void extend_stack()
1.1 takayama 55: {
56: int size2 = stack_size + EXT_S_SIZE;
57: cmo **stack2 = malloc(size2*sizeof(cmo*));
58: memcpy(stack2, stack, stack_size*sizeof(cmo *));
59: free(stack);
60: stack = stack2;
61: stack_size = size2;
62: }
63:
1.2 takayama 64: void push(cmo* m)
1.1 takayama 65: {
66: stack[stack_pointer] = m;
67: stack_pointer++;
68: if (stack_pointer >= stack_size) {
69: extend_stack();
70: }
71: }
72:
73: cmo* pop()
74: {
75: if (stack_pointer > 0) {
76: stack_pointer--;
77: return stack[stack_pointer];
78: }
79: return new_cmo_null();
80: }
81:
82: void pops(int n)
83: {
84: stack_pointer -= n;
85: if (stack_pointer < 0) {
86: stack_pointer = 0;
87: }
88: }
89:
90: #define OX_GSL_VERSION 2018032901
91: #define ID_STRING "2018/03/29 13:56:00"
92:
93: int sm_mathcap()
94: {
1.2 takayama 95: int available_cmo[]={
96: CMO_NULL,
97: CMO_INT32,
98: // CMO_DATUM,
99: CMO_STRING,
100: CMO_MATHCAP,
101: CMO_LIST,
102: // CMO_MONOMIAL32,
103: CMO_ZZ,
104: // CMO_QQ,
105: CMO_BIGFLOAT32,
106: CMO_COMPLEX,
107: CMO_IEEE_DOUBLE_FLOAT,
108: CMO_ZERO,
109: // CMO_DMS_GENERIC,
110: // CMO_RING_BY_NAME,
111: // CMO_INDETERMINATE,
112: // CMO_DISTRIBUTED_POLYNOMIAL,
113: // CMO_RECURSIVE_POLYNOMIAL,
114: // CMO_POLYNOMIAL_IN_ONE_VARIABLE,
1.5 takayama 115: CMO_TREE,
1.2 takayama 116: CMO_ERROR2,
117: 0};
118: int available_sm_command[]={
119: SM_popCMO,
120: SM_popString,
121: SM_mathcap,
122: SM_pops,
123: // SM_executeStringByLocalParser,
124: SM_executeFunction,
125: SM_setMathCap,
126: SM_shutdown,
127: SM_control_kill,
128: SM_control_reset_connection,
129: SM_control_spawn_server,
130: SM_control_terminate_server,
131: 0};
132: mathcap_init(OX_GSL_VERSION, ID_STRING, "ox_gsl", available_cmo,available_sm_command);
133: push((cmo *)oxf_cmo_mathcap(fd_rw));
1.1 takayama 134: return 0;
135: }
136:
137: int sm_popCMO()
138: {
139: cmo* m = pop();
140:
141: if (m != NULL) {
142: send_ox_cmo(fd_rw, m);
143: return 0;
144: }
145: return SM_popCMO;
146: }
147:
1.3 takayama 148: cmo *make_error2(const char *reason,const char *fname,int line,int code)
1.1 takayama 149: {
1.3 takayama 150: // gsl_error_handler_t void handler(const char *reason,const char *file,int line, int gsl_errno)
151: cmo *ms;
152: cmo *err;
153: cmo *m;
154: cmo **argv;
155: int n;
156: char *s;
157: n = 5;
158: argv = (cmo **) GC_malloc(sizeof(cmo *)*n);
159: ms = (cmo *)new_cmo_string("Error"); argv[0] = ms;
1.4 takayama 160: if (reason != NULL) {s = (char *)GC_malloc(strlen(reason)+1); strcpy(s,reason);
161: }else strcpy(s,"");
1.3 takayama 162: ms = (cmo *) new_cmo_string(s); argv[1] = ms;
1.4 takayama 163: if (fname != NULL) {s = (char *)GC_malloc(strlen(fname)+1); strcpy(s,fname);
164: }else strcpy(s,"");
1.3 takayama 165: ms = (cmo *) new_cmo_string(s); argv[2] = ms;
166: err = (cmo *)new_cmo_int32(line); argv[3] = err;
167: err = (cmo *)new_cmo_int32(code); argv[4] = err;
168:
169: m = (cmo *)new_cmo_list_array((void *)argv,n);
170: return (m);
1.1 takayama 171: }
172:
173: int get_i()
174: {
175: cmo *c = pop();
176: if (c->tag == CMO_INT32) {
177: return ((cmo_int32 *)c)->i;
178: }else if (c->tag == CMO_ZZ) {
179: return mpz_get_si(((cmo_zz *)c)->mpz);
1.2 takayama 180: }else if (c->tag == CMO_NULL) {
181: return(0);
182: }else if (c->tag == CMO_ZERO) {
183: return(0);
1.1 takayama 184: }
1.4 takayama 185: myhandler("get_i: not an integer",NULL,0,-1);
1.1 takayama 186: return 0;
187: }
188:
1.2 takayama 189: void get_xy(int *x, int *y)
1.1 takayama 190: {
191: pop();
192: *x = get_i();
193: *y = get_i();
194: }
195:
1.2 takayama 196: void my_add_int32()
1.1 takayama 197: {
198: int x, y;
199: get_xy(&x, &y);
1.2 takayama 200: push((cmo *)new_cmo_int32(x+y));
1.1 takayama 201: }
202:
1.2 takayama 203: double get_double()
204: {
1.3 takayama 205: #define mympz(c) (((cmo_zz *)c)->mpz)
1.2 takayama 206: cmo *c = pop();
207: if (c->tag == CMO_INT32) {
208: return( (double) (((cmo_int32 *)c)->i) );
209: }else if (c->tag == CMO_IEEE_DOUBLE_FLOAT) {
1.3 takayama 210: return (((cmo_double *)c)->d); // see ox_toolkit.h
1.2 takayama 211: }else if (c->tag == CMO_ZZ) {
1.3 takayama 212: if ((mpz_cmp_si(mympz(c),(long int) 0x7fffffff)>0) ||
213: (mpz_cmp_si(mympz(c),(long int) -0x7fffffff)<0)) {
1.4 takayama 214: myhandler("get_double: out of int32",NULL,0,-1);
1.3 takayama 215: return(NAN);
216: }
217: return( (double) mpz_get_si(((cmo_zz *)c)->mpz));
1.2 takayama 218: }else if (c->tag == CMO_NULL) {
219: return(0);
220: }else if (c->tag == CMO_ZERO) {
221: return(0);
222: }
1.4 takayama 223: myhandler("get_double: not a double",NULL,0,-1);
1.3 takayama 224: return(NAN);
1.2 takayama 225: }
226:
227: void my_add_double() {
228: double x,y;
229: pop();
230: y = get_double();
231: x = get_double();
232: push((cmo *)new_cmo_double(x+y));
233: }
234:
235: double *get_double_list(int *length) {
236: cmo *c;
237: cmo *entry;
238: cell *cellp;
239: double *d;
240: int n,i;
241: c = pop();
242: if (c->tag != CMO_LIST) {
1.3 takayama 243: // make_error2("get_double_list",NULL,0,-1);
1.2 takayama 244: *length=-1; return(0);
245: }
246: n = *length = list_length((cmo_list *)c);
247: d = (double *) GC_malloc(sizeof(double)*(*length+1));
248: cellp = list_first((cmo_list *)c);
249: entry = cellp->cmo;
250: for (i=0; i<n; i++) {
251: if (Debug) {
252: printf("entry[%d]=",i); print_cmo(entry); printf("\n");
253: }
254: if (entry->tag == CMO_INT32) {
255: d[i]=( (double) (((cmo_int32 *)entry)->i) );
256: }else if (entry->tag == CMO_IEEE_DOUBLE_FLOAT) {
257: d[i]=((cmo_double *)entry)->d;
258: }else if (entry->tag == CMO_ZZ) {
259: d[i]=( (double) mpz_get_si(((cmo_zz *)entry)->mpz));
260: }else if (entry->tag == CMO_NULL) {
261: d[i]= 0;
262: }else {
263: fprintf(stderr,"entries of the list should be int32 or zz or double\n");
264: *length = -1;
1.3 takayama 265: myhandler("get_double_list",NULL,0,-1);
1.2 takayama 266: return(NULL);
267: }
268: cellp = list_next(cellp);
269: entry = cellp->cmo;
270: }
271: return(d);
272: }
273: void show_double_list() {
274: int n;
275: double *d;
276: int i;
277: pop(); // pop argument number;
278: d = get_double_list(&n);
1.3 takayama 279: if (n < 0) fprintf(stderr,"Error in the double list\n");
1.2 takayama 280: printf("show_double_list: length=%d\n",n);
281: for (i=0; i<n; i++) {
282: printf("%lg, ",d[i]);
283: }
284: printf("\n");
285: }
286:
287: char *get_string() {
288: cmo *c;
289: c = pop();
290: if (c->tag == CMO_STRING) {
291: return (((cmo_string *)c)->s);
292: }
1.3 takayama 293: // make_error2(-1);
1.2 takayama 294: return(NULL);
295: }
1.1 takayama 296:
1.7 takayama 297: void test_ox_eval() {
1.5 takayama 298: cmo *c;
299: double d=0;
300: pop();
1.7 takayama 301: c=pop();
1.5 takayama 302: if (Debug) {
1.7 takayama 303: ox_printf("cmo *c="); print_cmo(c); ox_printf("\n");
1.5 takayama 304: }
1.6 ohara 305: init_dic();
1.5 takayama 306: register_entry("x",1.25);
1.7 takayama 307: if (eval_cmo(c,&d) == 0) myhandler("eval_cmo failed",NULL,0,-1);
1.5 takayama 308: push((cmo *)new_cmo_double(d));
309: }
310:
1.1 takayama 311: int sm_executeFunction()
312: {
313: cmo_string *func = (cmo_string *)pop();
314: if (func->tag != CMO_STRING) {
1.3 takayama 315: push(make_error2("sm_executeFunction, not CMO_STRING",NULL,0,-1));
1.1 takayama 316: return -1;
317: }
1.9 takayama 318: init_dic();
1.2 takayama 319: // Test functions
1.1 takayama 320: if (strcmp(func->s, "add_int32") == 0) {
321: my_add_int32();
1.2 takayama 322: }else if (strcmp(func->s,"add_double")==0) {
323: my_add_double();
324: }else if (strcmp(func->s,"show_double_list")==0) {
325: show_double_list();
1.3 takayama 326: }else if (strcmp(func->s,"restart")==0) {
327: pop(); restart();
1.5 takayama 328: }else if (strcmp(func->s,"test_ox_eval")==0) {
329: test_ox_eval();
1.2 takayama 330: // The following functions are defined in call_gsl.c
331: }else if (strcmp(func->s,"gsl_sf_lngamma_complex_e")==0) {
332: call_gsl_sf_lngamma_complex_e();
1.8 takayama 333: }else if (strcmp(func->s,"gsl_integration_qags")==0) {
334: call_gsl_integration_qags();
1.1 takayama 335: }else {
1.3 takayama 336: push(make_error2("sm_executeFunction, unknown function",NULL,0,-1));
1.1 takayama 337: return -1;
1.2 takayama 338: }
339: return(0);
1.1 takayama 340: }
341:
342:
343: int receive_and_execute_sm_command()
344: {
345: int code = receive_int32(fd_rw);
346: switch(code) {
347: case SM_popCMO:
348: sm_popCMO();
349: break;
350: case SM_executeFunction:
351: sm_executeFunction();
352: break;
353: case SM_mathcap:
354: sm_mathcap();
355: break;
356: case SM_setMathCap:
357: pop();
358: break;
359: default:
360: ;
361: }
1.2 takayama 362: return(0);
1.1 takayama 363: }
364:
365: int receive()
366: {
367: int tag;
368:
369: tag = receive_ox_tag(fd_rw);
370: switch(tag) {
371: case OX_DATA:
372: push(receive_cmo(fd_rw));
373: if (Debug) show_stack_top();
374: break;
375: case OX_COMMAND:
376: if (Debug) show_stack_top();
377: receive_and_execute_sm_command();
378: break;
379: default:
380: ;
381: }
382: return 0;
383: }
384:
1.2 takayama 385: jmp_buf Ox_env;
1.3 takayama 386: int Ox_intr_usr1=0;
1.2 takayama 387: void usr1_handler(int sig)
388: {
1.3 takayama 389: Ox_intr_usr1=1;
390: longjmp(Ox_env,1);
391: }
392: void restart() {
393: Ox_intr_usr1=0;
1.2 takayama 394: longjmp(Ox_env,1);
395: }
396:
1.3 takayama 397: void myhandler(const char *reason,const char *file,int line, int gsl_errno) {
398: cmo *m;
399: FILE *fp;
400: char logname[1024];
401: sprintf(logname,"/tmp/ox_gsl-%d.txt",(int) getpid());
402: fp = fopen(logname,"w");
403: fprintf(fp,"%d\n",gsl_errno);
404: fprintf(fp,"%d\n",line);
405: if (file != NULL) fprintf(fp,"%s\n",file); else fprintf(fp,"file?\n");
406: if (reason != NULL) fprintf(fp,"%s\n",reason); else fprintf(fp,"reason?\n");
1.4 takayama 407: fflush(NULL); fclose(fp);
1.3 takayama 408: // m = make_error2(reason,file,line,gsl_errno);
409: // send_ox_cmo(fd_rw, m); ox_flush(fd_rw);
410: // send error packet even it is not asked. Todo, OK? --> no
411: restart();
412: }
413: void push_error_from_file() {
414: FILE *fp;
415: #define BUF_SIZE 1024
416: char logname[BUF_SIZE];
417: char cmd[BUF_SIZE];
418: char file[BUF_SIZE];
419: char reason[BUF_SIZE];
420: int gsl_errno, line;
421: cmo *m;
422: fprintf(stderr,"push_error_from_file()\n");
423: sprintf(logname,"/tmp/ox_gsl-%d.txt",(int) getpid());
1.4 takayama 424: fp = fopen(logname,"r");
425: if (fp == NULL) {
426: fprintf(stderr,"open %s is failed\n",logname); return;
427: }
1.3 takayama 428: fgets(cmd,BUF_SIZE-2,fp); sscanf(cmd,"%d",&gsl_errno);
429: fgets(cmd,BUF_SIZE-2,fp); sscanf(cmd,"%d",&line);
1.4 takayama 430: #define remove_newline(s) {char *tmp_pos; if ((tmp_pos=strchr(s,'\n')) != NULL) *tmp_pos = '\0';}
431: fgets(file,BUF_SIZE-2,fp); remove_newline(file);
432: fgets(reason,BUF_SIZE-2,fp); remove_newline(reason);
1.3 takayama 433: fclose(fp);
434: m = make_error2(reason,file,line,gsl_errno);
435: push(m);
436: sprintf(cmd,"rm -f %s",logname);
437: system(cmd);
438: }
1.1 takayama 439: int main()
440: {
1.2 takayama 441: if ( setjmp(Ox_env) ) {
1.3 takayama 442: fprintf(stderr,"resetting libgsl ...");
1.2 takayama 443: initialize_stack();
1.3 takayama 444: if (Ox_intr_usr1) {
445: fprintf(stderr,"and sending OX_SYNC_BALL...");
446: send_ox_tag(fd_rw,OX_SYNC_BALL);
447: }
1.2 takayama 448: fprintf(stderr,"done\n");
1.3 takayama 449: Ox_intr_usr1=0;
450: push_error_from_file();
1.2 takayama 451: }else{
1.1 takayama 452: ox_stderr_init(stderr);
453: initialize_stack();
454: init_gc();
455: fd_rw = oxf_open(3);
456: oxf_determine_byteorder_server(fd_rw);
1.2 takayama 457: }
1.10 ! ohara 458: #if defined(__CYGWIN__)
! 459: void *mysignal(int sig,void (*handler)(int m));
! 460: mysignal(SIGUSR1,usr1_handler);
! 461: #else
1.2 takayama 462: signal(SIGUSR1,usr1_handler);
1.10 ! ohara 463: #endif
1.2 takayama 464:
465: while(1) {
466: receive();
467: }
468: return(0);
1.1 takayama 469: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>