pike.git/
src/
threads.c
Branch:
Tag:
Non-build tags
All tags
No tags
1998-08-24
1998-08-24 20:58:41 by Marcus Comstedt <marcus@mc.pp.se>
d86cd760aeb0653c2c82976d7881249179096946 (
101
lines) (+
96
/-
5
)
[
Show
|
Annotate
]
Branch:
7.9
Thread local variables implemented.
Rev: src/threads.c:1.82
Rev: src/threads.h:1.50
1:
#include "global.h"
-
RCSID("$Id: threads.c,v 1.
81
1998/08/
17
04
:
37
:
51
per
Exp $");
+
RCSID("$Id: threads.c,v 1.
82
1998/08/
24
20
:
58
:
38
marcus
Exp $");
int num_threads = 1; int threads_disabled = 0;
7:
#ifdef _REENTRANT #include "threads.h" #include "array.h"
+
#include "mapping.h"
#include "object.h" #include "pike_macros.h" #include "callback.h"
146:
MUTEX_T interpreter_lock, thread_table_lock, interleave_lock; struct program *mutex_key = 0; struct program *thread_id_prog = 0;
+
struct program *thread_local_prog = 0;
#ifdef POSIX_THREADS pthread_attr_t pattr; pthread_attr_t small_pattr;
157:
struct array *args; };
+
struct thread_local
+
{
+
INT32 id;
+
};
+
static volatile IMUTEX_T *interleave_list = NULL; void low_init_threads_disable(void)
488:
pop_stack(); }
+
if(((struct thread_state *)(thread_id->storage))->thread_local != NULL) {
+
free_mapping(((struct thread_state *)(thread_id->storage))->thread_local);
+
((struct thread_state *)(thread_id->storage))->thread_local = NULL;
+
}
+
((struct thread_state *)(thread_id->storage))->status=THREAD_EXITED; co_signal(& ((struct thread_state *)(thread_id->storage))->status_change);
838:
MEMSET(o->storage, 0, sizeof(struct thread_state)); THIS_THREAD->status=THREAD_NOT_STARTED; co_init(& THIS_THREAD->status_change);
+
THIS_THREAD->thread_local=NULL;
} void exit_thread_obj(struct object *o) {
-
+
if(THIS_THREAD->thread_local != NULL) {
+
free_mapping(THIS_THREAD->thread_local);
+
THIS_THREAD->thread_local = NULL;
+
}
co_destroy(& THIS_THREAD->status_change); th_destroy(& THIS_THREAD->id); }
-
#ifdef DEBUG
+
static void thread_was_marked(struct object *o) { struct thread_state *tmp=(struct thread_state *)(o->storage);
-
+
if(tmp->thread_local != NULL)
+
gc_mark_mapping_as_referenced(tmp->thread_local);
+
#ifdef DEBUG
if(tmp->swapped) { debug_gc_xmark_svalues(tmp->evaluator_stack,tmp->sp-tmp->evaluator_stack-1,"idle thread stack"); }
-
}
+
#endif
-
+
}
-
+
static void thread_was_checked(struct object *o)
+
{
+
struct thread_state *tmp=(struct thread_state *)(o->storage);
+
if(tmp->thread_local != NULL)
+
gc_check(tmp->thread_local);
+
}
+
+
void f_thread_local(INT32 args)
+
{
+
static INT32 thread_local_id = 0;
+
+
struct object *loc = clone_object(thread_local_prog,0);
+
((struct thread_local *)loc->storage)->id = thread_local_id++;
+
pop_n_elems(args);
+
push_object(loc);
+
}
+
+
void f_thread_local_get(INT32 args)
+
{
+
struct svalue key;
+
struct mapping *m;
+
key.u.integer = ((struct thread_local *)fp->current_storage)->id;
+
key.type = T_INT;
+
key.subtype = NUMBER_NUMBER;
+
pop_n_elems(args);
+
if(thread_id != NULL &&
+
(m = ((struct thread_state *)thread_id->storage)->thread_local) != NULL)
+
mapping_index_no_free(sp++, m, &key);
+
else {
+
push_int(0);
+
sp[-1].subtype=NUMBER_UNDEFINED;
+
}
+
}
+
+
void f_thread_local_set(INT32 args)
+
{
+
struct svalue key;
+
struct mapping *m;
+
key.u.integer = ((struct thread_local *)fp->current_storage)->id;
+
key.type = T_INT;
+
key.subtype = NUMBER_NUMBER;
+
if(args>1)
+
pop_n_elems(args-1);
+
else if(args<1)
+
error("Too few arguments to thread_local->set()\n");
+
+
if(thread_id == NULL)
+
error("Trying to set thread_local without thread!\n");
+
+
if((m = ((struct thread_state *)thread_id->storage)->thread_local) == NULL)
+
m = ((struct thread_state *)thread_id->storage)->thread_local =
+
allocate_mapping(4);
+
+
mapping_insert(m, &key, &sp[-1]);
+
}
+
void low_th_init(void) { #ifdef SGI_SPROC_THREADS
912:
add_efun("all_threads",f_all_threads,"function(:array(object))", OPT_EXTERNAL_DEPEND);
+
add_efun("thread_local",f_thread_local,"function(:object)",OPT_SIDE_EFFECT);
+
start_new_program(); add_storage(sizeof(struct mutex_storage)); add_function("lock",f_mutex_lock,"function(int|void:object)",0);
957:
} start_new_program();
+
add_storage(sizeof(struct thread_local));
+
add_function("get",f_thread_local_get,"function(:mixed)",0);
+
add_function("set",f_thread_local_set,"function(mixed:mixed)",0);
+
thread_local_prog=end_program();
+
if(!thread_local_prog)
+
fatal("Failed to initialize thread_local program!\n");
+
+
start_new_program();
add_storage(sizeof(struct thread_state)); thread_id_result_variable=simple_add_variable("result","mixed",0); add_function("backtrace",f_thread_backtrace,"function(:array)",0); add_function("wait",f_thread_id_result,"function(:mixed)",0); add_function("status",f_thread_id_status,"function(:int)",0);
-
#ifdef DEBUG
+
set_gc_mark_callback(thread_was_marked);
-
#endif
+
set_gc_check_callback(thread_was_checked);
set_init_callback(init_thread_obj); set_exit_callback(exit_thread_obj); thread_id_prog=end_program();
986:
mutex_key=0; }
+
if(thread_local_prog)
+
{
+
free_program(thread_local_prog);
+
thread_local_prog=0;
+
}
+
if(thread_id_prog) { free_program(thread_id_prog);