File: import.c

package info (click to toggle)
ecl 0.9i-2
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 22,424 kB
  • ctags: 28,771
  • sloc: ansic: 115,594; lisp: 63,241; asm: 45,930; sh: 15,564; cpp: 9,729; perl: 2,886; makefile: 2,751; yacc: 226; lex: 94; fortran: 24
file content (109 lines) | stat: -rw-r--r-- 2,801 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/*
    import.c -- Execute Lisp code from C-generated threads
*/
/*
    Copyright (c) 2005, Juan Jose Garcia Ripoll.

    ECL is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    See file '../Copyright' for full details.
*/

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

/*
 * GOAL:	To execute lisp code from threads which have not
 *		been generated by our lisp environment.
 *
 * ASSUMES:	ECL has been configured with threads (--enable-threads)
 *		and installed somewhere on the path.
 *
 * COMPILE:	Run "make" from the command line.
 *
 *
 * When this example is compiled and run, it generates a number of
 * threads, each one executing some interpreted code -- in this case
 * a bunch of PRINT statements.
 *
 * Importing other threads into lisp is possible if these threads have
 * been intercepted by the garbage collector. The way to do it is to
 * include the <ecl.h> on the source code that generates the threads,
 * as we do here. This takes care of replacing calls to phtread_create
 * or CreateThread (in unix and Windows respectively) with the
 * GC_pthread_create and GC_CreateThread functions.
 */

#include <ecl.h>


static void *
thread_entry_point(void *data)
{
	cl_object form;

	/*
	 * This is the entry point of the threads we have created.
	 * These threads have no valid lisp environment. The following
	 * routine initializes the lisp and makes it ready for working
	 * in this thread.
	 */

	ecl_import_current_thread(Cnil, Cnil);

	/*
	 * Here we execute some lisp code code.
	 */
	cl_eval(form);

	/*
	 * Finally, when we exit the thread we have to release the
	 * resources allocated by the lisp environment.
	 */
	ecl_release_current_thread();

	return NULL;
}


int main(int narg, char **argv)
{
	pthread_t child_thread;
	int i, code;

	/*
	 * First of all, we have to initialize the ECL environment.
	 * This should be done from the main thread.
	 */
	cl_boot(narg, argv);

	/*
	 * Here we spawn 10 threads using the OS functions. The
	 * current version is for Unix and uses pthread_create.
	 * Since we have included <gc.h>, pthread_create will be
	 * replaced with the appropiate routine from the garbage
	 * collector.
	 */
	cl_object sym_print = c_string_to_object("PRINT");
	for (i = 0; i < 10; i++) {
		cl_object form = cl_list(2, sym_print, MAKE_FIXNUM(i));
		code = pthread_create(&child_thread, NULL, thread_entry_point,
				      (void*)form);
		if (code) {
			printf("Unable to create thread\n");
			exit(1);
		}
	}

	/*
	 * Here we wait for the last thread to finish.
	 */
	pthread_join(child_thread, NULL);

	return 0;
}