e576bb | 2002-10-11 | Martin Nilsson | | |
9699fc | 2003-02-10 | Martin Stjernholm | | || $Id: threads.c,v 1.201 2003/02/10 17:10:40 mast Exp $
|
e576bb | 2002-10-11 | Martin Nilsson | | */
|
1b10db | 2002-10-08 | Martin Nilsson | |
|
83b184 | 2003-02-08 | Martin Stjernholm | | #ifndef CONFIGURE_TEST
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | #include "global.h"
|
9699fc | 2003-02-10 | Martin Stjernholm | | RCSID("$Id: threads.c,v 1.201 2003/02/10 17:10:40 mast Exp $");
|
a29e02 | 1996-10-15 | Fredrik Hübinette (Hubbe) | |
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT int num_threads = 1;
PMOD_EXPORT int threads_disabled = 0;
|
83b184 | 2003-02-08 | Martin Stjernholm | | #endif /* !CONFIGURE_TEST */
|
a29e02 | 1996-10-15 | Fredrik Hübinette (Hubbe) | |
#ifdef _REENTRANT
|
83b184 | 2003-02-08 | Martin Stjernholm | |
#ifndef CONFIGURE_TEST
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | #include "threads.h"
#include "array.h"
|
d86cd7 | 1998-08-24 | Marcus Comstedt | | #include "mapping.h"
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | #include "object.h"
|
bb55f8 | 1997-03-16 | Fredrik Hübinette (Hubbe) | | #include "pike_macros.h"
|
a29e02 | 1996-10-15 | Fredrik Hübinette (Hubbe) | | #include "callback.h"
|
9c6f7d | 1997-04-15 | Fredrik Hübinette (Hubbe) | | #include "builtin_functions.h"
#include "constants.h"
|
be478c | 1997-08-30 | Henrik Grubbström (Grubba) | | #include "program.h"
|
3f87be | 1999-12-14 | Martin Stjernholm | | #include "program_id.h"
|
c5b96b | 1997-11-11 | Henrik Grubbström (Grubba) | | #include "gc.h"
|
3c0c28 | 1998-01-26 | Fredrik Hübinette (Hubbe) | | #include "main.h"
|
a49ee6 | 1999-04-02 | Fredrik Hübinette (Hubbe) | | #include "module_support.h"
|
52e4c6 | 1999-12-13 | Martin Stjernholm | | #include "pike_types.h"
|
9a0d42 | 2000-02-06 | Martin Stjernholm | | #include "operators.h"
|
7e8ea3 | 2000-08-13 | Henrik Grubbström (Grubba) | | #include "bignum.h"
|
700dac | 2002-02-05 | Martin Stjernholm | | #include "signal_handler.h"
|
d5c61f | 2002-12-07 | Henrik Grubbström (Grubba) | | #include "pike_rusage.h"
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | |
|
cd11fa | 1999-05-13 | Henrik Grubbström (Grubba) | | #include <errno.h>
|
335a55 | 2001-11-02 | Martin Stjernholm | | PMOD_EXPORT int live_threads = 0, disallow_live_threads = 0;
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT COND_T live_threads_change;
PMOD_EXPORT COND_T threads_disabled_change;
|
78797d | 2001-05-31 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT size_t thread_stack_size=256 * 1204;
|
ef1e93 | 1998-03-26 | Henrik Grubbström (Grubba) | |
|
83b184 | 2003-02-08 | Martin Stjernholm | | #else
#include "pike_threadlib.h"
#endif /* !CONFIGURE_TEST */
|
1f88bf | 2001-09-24 | Henrik Grubbström (Grubba) | |
int __thread_sys_behavior = 1;
|
83b184 | 2003-02-08 | Martin Stjernholm | | #ifndef CONFIGURE_TEST
|
3c5576 | 2001-09-20 | Fredrik Hübinette (Hubbe) | | #if !defined(HAVE_PTHREAD_ATFORK) && !defined(th_atfork)
|
71ac9e | 1999-08-29 | Fredrik Hübinette (Hubbe) | | #include "callback.h"
|
58580c | 2001-11-12 | Martin Stjernholm | | #define PIKE_USE_OWN_ATFORK
|
71ac9e | 1999-08-29 | Fredrik Hübinette (Hubbe) | |
|
3c5576 | 2001-09-20 | Fredrik Hübinette (Hubbe) | |
|
71ac9e | 1999-08-29 | Fredrik Hübinette (Hubbe) | | static struct callback_list atfork_prepare_callback;
static struct callback_list atfork_parent_callback;
static struct callback_list atfork_child_callback;
int th_atfork(void (*prepare)(void),void (*parent)(void),void (*child)(void))
{
if(prepare)
add_to_callback(&atfork_prepare_callback, (callback_func) prepare, 0, 0);
if(parent)
add_to_callback(&atfork_parent_callback, (callback_func) parent, 0, 0);
if(child)
add_to_callback(&atfork_child_callback, (callback_func) child, 0, 0);
return 0;
}
void th_atfork_prepare(void)
{
call_callback(& atfork_prepare_callback, 0);
}
void th_atfork_parent(void)
{
call_callback(& atfork_parent_callback, 0);
}
void th_atfork_child(void)
{
call_callback(& atfork_child_callback, 0);
}
#endif
|
83b184 | 2003-02-08 | Martin Stjernholm | | #endif /* !CONFIGURE_TEST */
|
dc7cc9 | 1998-01-14 | Fredrik Hübinette (Hubbe) | | #ifdef __NT__
|
7965d7 | 2001-01-24 | Fredrik Hübinette (Hubbe) | | int low_nt_create_thread(unsigned Pike_stack_size,
|
cd67ac | 1999-05-11 | Fredrik Hübinette (Hubbe) | | unsigned (TH_STDCALL *fun)(void *),
void *arg,
unsigned *id)
{
|
7965d7 | 2001-01-24 | Fredrik Hübinette (Hubbe) | | HANDLE h = (HANDLE)_beginthreadex(NULL, Pike_stack_size, fun, arg, 0, id);
|
cd67ac | 1999-05-11 | Fredrik Hübinette (Hubbe) | | if(h)
{
CloseHandle(h);
return 0;
}
else
{
return 1;
}
}
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
56f4f4 | 2001-09-18 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT HANDLE CheckValidHandle(HANDLE h);
|
dc7cc9 | 1998-01-14 | Fredrik Hübinette (Hubbe) | | #endif
#endif
|
e42eaf | 1998-01-02 | Fredrik Hübinette (Hubbe) | | #ifdef SIMULATE_COND_WITH_EVENT
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT int co_wait(COND_T *c, MUTEX_T *m)
|
e42eaf | 1998-01-02 | Fredrik Hübinette (Hubbe) | | {
struct cond_t_queue me;
event_init(&me.event);
|
dc7cc9 | 1998-01-14 | Fredrik Hübinette (Hubbe) | | me.next=0;
|
e42eaf | 1998-01-02 | Fredrik Hübinette (Hubbe) | | mt_lock(& c->lock);
|
dc7cc9 | 1998-01-14 | Fredrik Hübinette (Hubbe) | | if(c->tail)
{
c->tail->next=&me;
c->tail=&me;
}else{
c->head=c->tail=&me;
}
|
e42eaf | 1998-01-02 | Fredrik Hübinette (Hubbe) | |
mt_unlock(& c->lock);
mt_unlock(m);
event_wait(&me.event);
mt_lock(m);
event_destroy(& me.event);
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
dc7cc9 | 1998-01-14 | Fredrik Hübinette (Hubbe) | | if(me.next)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Wait on event return prematurely!!\n");
|
dc7cc9 | 1998-01-14 | Fredrik Hübinette (Hubbe) | | #endif
|
e42eaf | 1998-01-02 | Fredrik Hübinette (Hubbe) | | return 0;
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT int co_signal(COND_T *c)
|
e42eaf | 1998-01-02 | Fredrik Hübinette (Hubbe) | | {
struct cond_t_queue *t;
mt_lock(& c->lock);
|
dc7cc9 | 1998-01-14 | Fredrik Hübinette (Hubbe) | | if((t=c->head))
|
e42eaf | 1998-01-02 | Fredrik Hübinette (Hubbe) | | {
c->head=t->next;
t->next=0;
if(!c->head) c->tail=0;
}
mt_unlock(& c->lock);
if(t)
event_signal(& t->event);
return 0;
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT int co_broadcast(COND_T *c)
|
e42eaf | 1998-01-02 | Fredrik Hübinette (Hubbe) | | {
struct cond_t_queue *t,*n;
mt_lock(& c->lock);
n=c->head;
c->head=c->tail=0;
mt_unlock(& c->lock);
while((t=n))
{
n=t->next;
|
dc7cc9 | 1998-01-14 | Fredrik Hübinette (Hubbe) | | t->next=0;
|
e42eaf | 1998-01-02 | Fredrik Hübinette (Hubbe) | | event_signal(& t->event);
}
return 0;
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT int co_destroy(COND_T *c)
|
e42eaf | 1998-01-02 | Fredrik Hübinette (Hubbe) | | {
struct cond_t_queue *t;
mt_lock(& c->lock);
|
b1f4eb | 1998-01-13 | Fredrik Hübinette (Hubbe) | | t=c->head;
mt_unlock(& c->lock);
if(t) return -1;
mt_destroy(& c->lock);
|
e42eaf | 1998-01-02 | Fredrik Hübinette (Hubbe) | | return 0;
}
#endif
|
83b184 | 2003-02-08 | Martin Stjernholm | | #ifdef POSIX_THREADS
pthread_attr_t pattr;
pthread_attr_t small_pattr;
#endif
static void really_low_th_init(void)
{
#ifdef SGI_SPROC_THREADS
#error /* Need to specify a filename */
us_cookie = usinit("");
#endif /* SGI_SPROC_THREADS */
#ifdef POSIX_THREADS
#ifdef HAVE_PTHREAD_INIT
pthread_init();
#endif /* HAVE_PTHREAD_INIT */
#endif /* POSIX_THREADS */
#ifdef POSIX_THREADS
pthread_attr_init(&pattr);
#ifndef CONFIGURE_TEST
#ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE
pthread_attr_setstacksize(&pattr, thread_stack_size);
#endif
#endif
pthread_attr_setdetachstate(&pattr, PTHREAD_CREATE_DETACHED);
pthread_attr_init(&small_pattr);
#ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE
pthread_attr_setstacksize(&small_pattr, 4096*sizeof(char *));
#endif
pthread_attr_setdetachstate(&small_pattr, PTHREAD_CREATE_DETACHED);
#endif
}
#ifndef CONFIGURE_TEST
|
e42eaf | 1998-01-02 | Fredrik Hübinette (Hubbe) | |
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | #define THIS_THREAD ((struct thread_state *)CURRENT_STORAGE)
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | |
|
a29e02 | 1996-10-15 | Fredrik Hübinette (Hubbe) | | static struct callback *threads_evaluator_callback=0;
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | int thread_id_result_variable;
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | |
|
b32ef1 | 2000-04-19 | Martin Stjernholm | | int th_running = 0;
|
c91f89 | 2000-04-19 | Martin Stjernholm | | #ifdef PIKE_DEBUG
int debug_interpreter_is_locked = 0;
THREAD_T debug_locking_thread;
|
95c815 | 2001-11-01 | Martin Stjernholm | | THREAD_T threads_disabled_thread = 0;
|
c91f89 | 2000-04-19 | Martin Stjernholm | | #endif
|
c5f4e2 | 2002-09-14 | Martin Stjernholm | | #ifdef INTERNAL_PROFILING
PMOD_EXPORT unsigned long thread_yields = 0;
#endif
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT MUTEX_T interpreter_lock;
MUTEX_T thread_table_lock, interleave_lock;
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | struct program *mutex_key = 0;
|
fa8c69 | 2000-11-30 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT struct program *thread_id_prog = 0;
|
d86cd7 | 1998-08-24 | Marcus Comstedt | | struct program *thread_local_prog = 0;
|
89fc4c | 2000-08-10 | Henrik Grubbström (Grubba) | | PMOD_EXPORT ptrdiff_t thread_storage_offset;
|
7ee4aa | 2002-09-14 | Martin Stjernholm | | #ifdef USE_CLOCK_FOR_SLICES
PMOD_EXPORT clock_t thread_start_clock = 0;
#endif
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | |
|
6d1a5e | 1996-10-07 | Fredrik Hübinette (Hubbe) | | struct thread_starter
{
struct object *id;
struct array *args;
|
222d92 | 2000-05-20 | Henrik Grubbström (Grubba) | | #ifdef HAVE_BROKEN_LINUX_THREAD_EUID
|
c17fed | 2000-05-20 | Henrik Grubbström (Grubba) | | int euid, egid;
|
222d92 | 2000-05-20 | Henrik Grubbström (Grubba) | | #endif /* HAVE_BROKEN_LINUX_THREAD_EUID */
|
6d1a5e | 1996-10-07 | Fredrik Hübinette (Hubbe) | | };
|
d86cd7 | 1998-08-24 | Marcus Comstedt | | struct thread_local
{
INT32 id;
};
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | static volatile IMUTEX_T *interleave_list = NULL;
|
335a55 | 2001-11-02 | Martin Stjernholm | |
|
f328f1 | 1998-07-17 | Henrik Grubbström (Grubba) | | void low_init_threads_disable(void)
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | {
if (!threads_disabled) {
|
f328f1 | 1998-07-17 | Henrik Grubbström (Grubba) | | THREADS_FPRINTF(0,
(stderr, "low_init_threads_disable(): Locking IM's...\n"));
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | |
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | if (Pike_interpreter.thread_id) {
|
2f748a | 1999-02-20 | Henrik Grubbström (Grubba) | |
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | IMUTEX_T *im;
THREADS_ALLOW();
mt_lock(&interleave_lock);
im = (IMUTEX_T *)interleave_list;
while(im) {
mt_lock(&(im->lock));
im = im->next;
}
THREADS_DISALLOW();
} else {
|
2f748a | 1999-02-20 | Henrik Grubbström (Grubba) | |
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | IMUTEX_T *im;
mt_lock(&interleave_lock);
im = (IMUTEX_T *)interleave_list;
while(im) {
mt_lock(&(im->lock));
im = im->next;
}
}
|
f328f1 | 1998-07-17 | Henrik Grubbström (Grubba) | | THREADS_FPRINTF(0, (stderr,
"low_init_threads_disable(): Disabling threads.\n"));
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | |
threads_disabled = 1;
|
95c815 | 2001-11-01 | Martin Stjernholm | | #ifdef PIKE_DEBUG
threads_disabled_thread = th_self();
#endif
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | } else {
threads_disabled++;
}
|
f328f1 | 1998-07-17 | Henrik Grubbström (Grubba) | | THREADS_FPRINTF(0,
(stderr, "low_init_threads_disable(): threads_disabled:%d\n",
threads_disabled));
}
|
16df70 | 1998-07-16 | Fredrik Hübinette (Hubbe) | |
|
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | | |
335a55 | 2001-11-02 | Martin Stjernholm | | *! This function first posts a notice to all threads that it is time
*! to stop. It then waits until all threads actually *have* stopped,
*! and then then returns a lock object. All other threads will be
*! blocked from running until that object has been freed/destroyed.
*!
*! It's mainly useful to do things that require a temporary uid/gid
*! change, since on many OS the effective user and group applies to
*! all threads.
|
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | | *!
*! @note
|
335a55 | 2001-11-02 | Martin Stjernholm | | *! You should make sure that the returned object is freed even if
*! some kind of error is thrown. That means in practice that it
*! should only have references (direct or indirect) from function
*! local variables. Also, it shouldn't be referenced from cyclic
*! memory structures, since those are only destructed by the periodic
*! gc. (This advice applies to mutex locks in general, for that
*! matter.)
|
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | | */
|
f328f1 | 1998-07-17 | Henrik Grubbström (Grubba) | | void init_threads_disable(struct object *o)
{
|
335a55 | 2001-11-02 | Martin Stjernholm | | disallow_live_threads = 1;
|
f328f1 | 1998-07-17 | Henrik Grubbström (Grubba) | |
if(live_threads) {
SWAP_OUT_CURRENT_THREAD();
while (live_threads) {
THREADS_FPRINTF(0,
(stderr,
"_disable_threads(): Waiting for %d threads to finish\n",
live_threads));
|
bc21dc | 2001-11-01 | Martin Stjernholm | | low_co_wait_interpreter(&live_threads_change);
|
16df70 | 1998-07-16 | Fredrik Hübinette (Hubbe) | | }
|
f328f1 | 1998-07-17 | Henrik Grubbström (Grubba) | | SWAP_IN_CURRENT_THREAD();
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | }
|
335a55 | 2001-11-02 | Martin Stjernholm | |
low_init_threads_disable();
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | }
|
de413f | 1998-03-26 | Per Hedbor | | void exit_threads_disable(struct object *o)
{
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | THREADS_FPRINTF(0, (stderr, "exit_threads_disable(): threads_disabled:%d\n",
threads_disabled));
|
40e949 | 1998-07-05 | Henrik Grubbström (Grubba) | | if(threads_disabled) {
if(!--threads_disabled) {
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | IMUTEX_T *im = (IMUTEX_T *)interleave_list;
while(im) {
THREADS_FPRINTF(0,
(stderr,
|
95c815 | 2001-11-01 | Martin Stjernholm | | "exit_threads_disable(): Unlocking IM 0x%p\n", im));
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | mt_unlock(&(im->lock));
im = im->next;
}
mt_unlock(&interleave_lock);
THREADS_FPRINTF(0, (stderr, "_exit_threads_disable(): Wake up!\n"));
|
335a55 | 2001-11-02 | Martin Stjernholm | | disallow_live_threads = 0;
|
2202fe | 1998-04-23 | Fredrik Hübinette (Hubbe) | | co_broadcast(&threads_disabled_change);
|
95c815 | 2001-11-01 | Martin Stjernholm | | #ifdef PIKE_DEBUG
threads_disabled_thread = 0;
#endif
|
40e949 | 1998-07-05 | Henrik Grubbström (Grubba) | | }
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
40e949 | 1998-07-05 | Henrik Grubbström (Grubba) | | } else {
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("exit_threads_disable() called too many times!\n");
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #endif /* PIKE_DEBUG */
|
40e949 | 1998-07-05 | Henrik Grubbström (Grubba) | | }
|
de413f | 1998-03-26 | Per Hedbor | | }
|
063fe3 | 1998-03-10 | Per Hedbor | |
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | void init_interleave_mutex(IMUTEX_T *im)
|
063fe3 | 1998-03-10 | Per Hedbor | | {
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | mt_init(&(im->lock));
|
6e1db5 | 1998-07-09 | Henrik Grubbström (Grubba) | |
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | THREADS_FPRINTF(0, (stderr,
"init_interleave_mutex(): init_threads_disable()\n"));
|
6e1db5 | 1998-07-09 | Henrik Grubbström (Grubba) | |
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | init_threads_disable(NULL);
|
6e1db5 | 1998-07-09 | Henrik Grubbström (Grubba) | |
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | THREADS_FPRINTF(0, (stderr,
|
95c815 | 2001-11-01 | Martin Stjernholm | | "init_interleave_mutex(): Locking IM 0x%p\n", im));
|
6e1db5 | 1998-07-09 | Henrik Grubbström (Grubba) | |
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | |
mt_lock(&(im->lock));
im->next = (IMUTEX_T *)interleave_list;
if (interleave_list) {
interleave_list->prev = im;
|
6e1db5 | 1998-07-09 | Henrik Grubbström (Grubba) | | }
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | interleave_list = im;
im->prev = NULL;
|
6e1db5 | 1998-07-09 | Henrik Grubbström (Grubba) | |
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | THREADS_FPRINTF(0, (stderr,
"init_interleave_mutex(): exit_threads_disable()\n"));
exit_threads_disable(NULL);
}
void exit_interleave_mutex(IMUTEX_T *im)
{
init_threads_disable(NULL);
if (im->prev) {
im->prev->next = im->next;
} else {
interleave_list = im->next;
}
if (im->next) {
im->next->prev = im->prev;
|
ef1e93 | 1998-03-26 | Henrik Grubbström (Grubba) | | }
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | |
mt_unlock(&(im->lock));
exit_threads_disable(NULL);
|
063fe3 | 1998-03-10 | Per Hedbor | | }
|
eac209 | 1998-02-27 | Marcus Comstedt | |
|
f2c01e | 2003-01-08 | Martin Stjernholm | | struct thread_state *thread_table_chains[THREAD_TABLE_SIZE];
int num_pike_threads=0;
|
eac209 | 1998-02-27 | Marcus Comstedt | |
|
22ca07 | 1998-04-08 | Fredrik Hübinette (Hubbe) | | void thread_table_init(void)
|
eac209 | 1998-02-27 | Marcus Comstedt | | {
INT32 x;
for(x=0; x<THREAD_TABLE_SIZE; x++)
thread_table_chains[x] = NULL;
}
unsigned INT32 thread_table_hash(THREAD_T *tid)
{
|
d21327 | 1998-02-28 | Fredrik Hübinette (Hubbe) | | return th_hash(*tid) % THREAD_TABLE_SIZE;
|
eac209 | 1998-02-27 | Marcus Comstedt | | }
|
26cd94 | 1999-05-07 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
38e1e8 | 2001-11-08 | Fredrik Hübinette (Hubbe) | | void dumpmem(char *desc, void *x, int size)
|
26cd94 | 1999-05-07 | Fredrik Hübinette (Hubbe) | | {
int e;
unsigned char *tmp=(unsigned char *)x;
fprintf(stderr,"%s: ",desc);
for(e=0;e<size;e++)
fprintf(stderr,"%02x",tmp[e]);
fprintf(stderr,"\n");
}
#endif
|
fa8c69 | 2000-11-30 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void thread_table_insert(struct object *o)
|
eac209 | 1998-02-27 | Marcus Comstedt | | {
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | struct thread_state *s = OBJ2THREAD(o);
|
eac209 | 1998-02-27 | Marcus Comstedt | | unsigned INT32 h = thread_table_hash(&s->id);
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
939b18 | 1998-07-17 | Fredrik Hübinette (Hubbe) | | if(h>=THREAD_TABLE_SIZE)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("thread_table_hash failed miserably!\n");
|
26cd94 | 1999-05-07 | Fredrik Hübinette (Hubbe) | | if(thread_state_for_id(s->id))
|
3be550 | 1999-06-08 | Fredrik Hübinette (Hubbe) | | {
if(thread_state_for_id(s->id) == s)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Registring thread twice!\n");
|
3be550 | 1999-06-08 | Fredrik Hübinette (Hubbe) | | else
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Forgot to unregister thread!\n");
|
3be550 | 1999-06-08 | Fredrik Hübinette (Hubbe) | | }
|
26cd94 | 1999-05-07 | Fredrik Hübinette (Hubbe) | |
|
939b18 | 1998-07-17 | Fredrik Hübinette (Hubbe) | | #endif
|
eac209 | 1998-02-27 | Marcus Comstedt | | mt_lock( & thread_table_lock );
|
56ac10 | 2000-03-29 | Fredrik Hübinette (Hubbe) | | num_pike_threads++;
|
eac209 | 1998-02-27 | Marcus Comstedt | | if((s->hashlink = thread_table_chains[h]) != NULL)
s->hashlink->backlink = &s->hashlink;
thread_table_chains[h] = s;
s->backlink = &thread_table_chains[h];
mt_unlock( & thread_table_lock );
}
|
fa8c69 | 2000-11-30 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void thread_table_delete(struct object *o)
|
eac209 | 1998-02-27 | Marcus Comstedt | | {
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | struct thread_state *s = OBJ2THREAD(o);
|
26cd94 | 1999-05-07 | Fredrik Hübinette (Hubbe) | |
|
eac209 | 1998-02-27 | Marcus Comstedt | | mt_lock( & thread_table_lock );
|
56ac10 | 2000-03-29 | Fredrik Hübinette (Hubbe) | | num_pike_threads--;
|
eac209 | 1998-02-27 | Marcus Comstedt | | if(s->hashlink != NULL)
s->hashlink->backlink = s->backlink;
*(s->backlink) = s->hashlink;
mt_unlock( & thread_table_lock );
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT struct thread_state *thread_state_for_id(THREAD_T tid)
|
eac209 | 1998-02-27 | Marcus Comstedt | | {
unsigned INT32 h = thread_table_hash(&tid);
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | struct thread_state *s = NULL;
|
26cd94 | 1999-05-07 | Fredrik Hübinette (Hubbe) | | #if 0
if(num_threads>1)
dumpmem("thread_state_for_id: ",&tid,sizeof(tid));
#endif
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
939b18 | 1998-07-17 | Fredrik Hübinette (Hubbe) | | if(h>=THREAD_TABLE_SIZE)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("thread_table_hash failed miserably!\n");
|
939b18 | 1998-07-17 | Fredrik Hübinette (Hubbe) | | #endif
|
eac209 | 1998-02-27 | Marcus Comstedt | | mt_lock( & thread_table_lock );
|
d21327 | 1998-02-28 | Fredrik Hübinette (Hubbe) | | if(thread_table_chains[h] == NULL)
{
|
eac209 | 1998-02-27 | Marcus Comstedt | |
|
d21327 | 1998-02-28 | Fredrik Hübinette (Hubbe) | | }
else if(th_equal((s=thread_table_chains[h])->id, tid))
{
|
eac209 | 1998-02-27 | Marcus Comstedt | |
|
d21327 | 1998-02-28 | Fredrik Hübinette (Hubbe) | | }
else
{
|
eac209 | 1998-02-27 | Marcus Comstedt | | while((s = s->hashlink) != NULL)
|
d21327 | 1998-02-28 | Fredrik Hübinette (Hubbe) | | if(th_equal(s->id, tid))
|
eac209 | 1998-02-27 | Marcus Comstedt | | break;
if(s != NULL) {
|
ec2bab | 2000-06-24 | Fredrik Hübinette (Hubbe) | | |
eac209 | 1998-02-27 | Marcus Comstedt | | we want to search for it again */
if(s->hashlink != NULL)
s->hashlink->backlink = s->backlink;
*(s->backlink) = s->hashlink;
if((s->hashlink = thread_table_chains[h]) != NULL)
s->hashlink->backlink = &s->hashlink;
thread_table_chains[h] = s;
s->backlink = &thread_table_chains[h];
}
}
mt_unlock( & thread_table_lock );
|
26cd94 | 1999-05-07 | Fredrik Hübinette (Hubbe) | | #if 0
if(num_threads>1 && s)
dumpmem("thread_state_for_id return value: ",&s->id,sizeof(tid));
#endif
|
eac209 | 1998-02-27 | Marcus Comstedt | | return s;
}
|
048d23 | 2001-02-27 | Martin Stjernholm | | struct thread_state *gdb_thread_state_for_id(THREAD_T tid)
{
unsigned INT32 h = thread_table_hash(&tid);
struct thread_state *s;
for (s = thread_table_chains[h]; s != NULL; s = s->hashlink)
if(th_equal(s->id, tid))
break;
return s;
}
INT32 gdb_next_thread_state(INT32 prev, struct thread_state **ts)
{
if (!*ts || !(*ts)->hashlink) {
if (!*ts) prev = -1;
while (++prev < THREAD_TABLE_SIZE)
if ((*ts = thread_table_chains[prev]))
return prev;
*ts = NULL;
return 0;
}
*ts = (*ts)->hashlink;
return prev;
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT struct object *thread_for_id(THREAD_T tid)
|
eac209 | 1998-02-27 | Marcus Comstedt | | {
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | struct thread_state *s = thread_state_for_id(tid);
|
26cd94 | 1999-05-07 | Fredrik Hübinette (Hubbe) | | return (s == NULL? NULL : THREADSTATE2OBJ(s));
|
eac209 | 1998-02-27 | Marcus Comstedt | |
}
|
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | |
|
95363a | 2000-04-11 | Fredrik Hübinette (Hubbe) | |
|
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | | |
c7b7dd | 2001-10-28 | Martin Nilsson | | *! @[Thread()]
|
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_all_threads(INT32 args)
|
eac209 | 1998-02-27 | Marcus Comstedt | | {
struct svalue *oldsp;
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | struct thread_state *s;
|
eac209 | 1998-02-27 | Marcus Comstedt | |
pop_n_elems(args);
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | oldsp = Pike_sp;
|
f2c01e | 2003-01-08 | Martin Stjernholm | | FOR_EACH_THREAD (s, {
|
26cd94 | 1999-05-07 | Fredrik Hübinette (Hubbe) | | struct object *o = THREADSTATE2OBJ(s);
|
88f320 | 2002-06-17 | Henrik Grubbström (Grubba) | | if (o) {
ref_push_object(o);
}
|
f2c01e | 2003-01-08 | Martin Stjernholm | | });
|
89fc4c | 2000-08-10 | Henrik Grubbström (Grubba) | | f_aggregate(DO_NOT_WARN(Pike_sp - oldsp));
|
eac209 | 1998-02-27 | Marcus Comstedt | | }
|
38e1e8 | 2001-11-08 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
void debug_list_all_threads(void)
{
INT32 x;
struct thread_state *s;
THREAD_T self = th_self();
fprintf(stderr,"--Listing all threads--\n");
dumpmem("Current thread: ",&self, sizeof(self));
fprintf(stderr,"Current thread obj: %p\n",Pike_interpreter.thread_id);
fprintf(stderr,"Current thread hash: %d\n",thread_table_hash(&self));
fprintf(stderr,"Current stack pointer: %p\n",&self);
for(x=0; x<THREAD_TABLE_SIZE; x++)
{
for(s=thread_table_chains[x]; s; s=s->hashlink) {
struct object *o = THREADSTATE2OBJ(s);
fprintf(stderr,"ThTab[%d]: %p (stackbase=%p)",x,o,s->state.stack_top);
dumpmem(" ",&s->id, sizeof(s->id));
}
}
fprintf(stderr,"-----------------------\n");
}
#endif
|
95363a | 2000-04-11 | Fredrik Hübinette (Hubbe) | |
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT int count_pike_threads(void)
|
56ac10 | 2000-03-29 | Fredrik Hübinette (Hubbe) | | {
return num_pike_threads;
}
|
eac209 | 1998-02-27 | Marcus Comstedt | |
|
9ef9a3 | 1996-11-16 | Fredrik Hübinette (Hubbe) | | static void check_threads(struct callback *cb, void *arg, void * arg2)
|
a29e02 | 1996-10-15 | Fredrik Hübinette (Hubbe) | | {
|
319fb1 | 2002-09-14 | Martin Stjernholm | | #ifndef HAVE_NO_YIELD
|
0a861b | 1997-09-17 | Fredrik Hübinette (Hubbe) | | static int div_;
|
a85ac5 | 2001-08-23 | Per Hedbor | | if(div_++ & 255)
return;
|
7ee4aa | 2002-09-14 | Martin Stjernholm | | #ifdef HAVE_GETHRTIME
{
static hrtime_t last_ = 0;
hrtime_t now = gethrtime();
if( now-last_ < 50000000 )
return;
last_ = now;
}
#elif defined (USE_CLOCK_FOR_SLICES)
if (clock() - thread_start_clock < (clock_t) (CLOCKS_PER_SEC / 20))
return;
|
a85ac5 | 2001-08-23 | Per Hedbor | | #endif
|
319fb1 | 2002-09-14 | Martin Stjernholm | | #endif
|
0a861b | 1997-09-17 | Fredrik Hübinette (Hubbe) | |
|
26cd94 | 1999-05-07 | Fredrik Hübinette (Hubbe) | | #ifdef DEBUG
|
38e1e8 | 2001-11-08 | Fredrik Hübinette (Hubbe) | | if(thread_for_id(th_self()) != Pike_interpreter.thread_id) {
debug_list_all_threads();
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("thread_for_id() (or Pike_interpreter.thread_id) failed! %p != %p\n",thread_for_id(th_self()),Pike_interpreter.thread_id) ;
|
38e1e8 | 2001-11-08 | Fredrik Hübinette (Hubbe) | | }
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | |
if(Pike_interpreter.backlink != OBJ2THREAD(Pike_interpreter.thread_id))
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Hashlink is wrong!\n");
|
26cd94 | 1999-05-07 | Fredrik Hübinette (Hubbe) | | #endif
|
de413f | 1998-03-26 | Per Hedbor | | THREADS_ALLOW();
|
335a55 | 2001-11-02 | Martin Stjernholm | | th_yield();
|
de413f | 1998-03-26 | Per Hedbor | | THREADS_DISALLOW();
|
26cd94 | 1999-05-07 | Fredrik Hübinette (Hubbe) | |
|
7ee4aa | 2002-09-14 | Martin Stjernholm | | #ifdef USE_CLOCK_FOR_SLICES
thread_start_clock = clock();
#endif
|
38e1e8 | 2001-11-08 | Fredrik Hübinette (Hubbe) | | DO_IF_DEBUG(
if(thread_for_id(th_self()) != Pike_interpreter.thread_id) {
debug_list_all_threads();
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("thread_for_id() (or Pike_interpreter.thread_id) failed! %p != %p\n",thread_for_id(th_self()),Pike_interpreter.thread_id) ;
|
38e1e8 | 2001-11-08 | Fredrik Hübinette (Hubbe) | | } )
|
a29e02 | 1996-10-15 | Fredrik Hübinette (Hubbe) | | }
|
26cd94 | 1999-05-07 | Fredrik Hübinette (Hubbe) | | TH_RETURN_TYPE new_thread_func(void * data)
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | {
|
6d1a5e | 1996-10-07 | Fredrik Hübinette (Hubbe) | | struct thread_starter arg = *(struct thread_starter *)data;
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | JMP_BUF back;
|
725ba9 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | INT32 tmp;
|
b1b51f | 1996-10-11 | Fredrik Hübinette (Hubbe) | |
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | THREADS_FPRINTF(0, (stderr,"THREADS_DISALLOW() Thread %08x created...\n",
(unsigned int)arg.id));
|
c17fed | 2000-05-20 | Henrik Grubbström (Grubba) | |
|
222d92 | 2000-05-20 | Henrik Grubbström (Grubba) | | #ifdef HAVE_BROKEN_LINUX_THREAD_EUID
|
c17fed | 2000-05-20 | Henrik Grubbström (Grubba) | |
if (!geteuid()) {
|
661730 | 2000-05-22 | Henrik Grubbström (Grubba) | | setegid(arg.egid);
seteuid(arg.euid);
|
c17fed | 2000-05-20 | Henrik Grubbström (Grubba) | | }
|
222d92 | 2000-05-20 | Henrik Grubbström (Grubba) | | #endif /* HAVE_BROKEN_LINUX_THREAD_EUID */
|
fe76ce | 1997-09-08 | Fredrik Hübinette (Hubbe) | |
|
c91f89 | 2000-04-19 | Martin Stjernholm | | if((tmp=mt_lock_interpreter()))
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Failed to lock interpreter, return value=%d, errno=%d\n",tmp,
|
cd67ac | 1999-05-11 | Fredrik Hübinette (Hubbe) | | #ifdef __NT__
GetLastError()
#else
errno
#endif
);
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | SWAP_IN_THREAD(OBJ2THREAD(arg.id));
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | init_interpreter();
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | Pike_interpreter.thread_id=arg.id;
|
061244 | 2001-05-16 | Fredrik Hübinette (Hubbe) | | #ifdef PROFILING
Pike_interpreter.stack_bottom=((char *)&data);
#endif
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | Pike_interpreter.stack_top=((char *)&data)+ (thread_stack_size-16384) * STACK_DIRECTION;
Pike_interpreter.recoveries = NULL;
SWAP_OUT_THREAD(OBJ2THREAD(Pike_interpreter.thread_id));
OBJ2THREAD(Pike_interpreter.thread_id)->swapped=0;
|
f0cd4c | 1999-03-21 | Henrik Grubbström (Grubba) | |
|
26cd94 | 1999-05-07 | Fredrik Hübinette (Hubbe) | | #if defined(PIKE_DEBUG)
if(d_flag)
{
|
f46983 | 1999-05-08 | Henrik Grubbström (Grubba) | | THREAD_T self = th_self();
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | if( Pike_interpreter.thread_id && !th_equal( OBJ2THREAD(Pike_interpreter.thread_id)->id, self) )
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Current thread is wrong. %lx %lx\n",
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | (long)OBJ2THREAD(Pike_interpreter.thread_id)->id, (long)self);
|
26cd94 | 1999-05-07 | Fredrik Hübinette (Hubbe) | |
|
38e1e8 | 2001-11-08 | Fredrik Hübinette (Hubbe) | | if(thread_for_id(th_self()) != Pike_interpreter.thread_id) {
debug_list_all_threads();
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("thread_for_id() (or Pike_interpreter.thread_id) failed! %p != %p\n",thread_for_id(th_self()),Pike_interpreter.thread_id) ;
|
38e1e8 | 2001-11-08 | Fredrik Hübinette (Hubbe) | | }
|
f46983 | 1999-05-08 | Henrik Grubbström (Grubba) | | }
|
26cd94 | 1999-05-07 | Fredrik Hübinette (Hubbe) | | #endif
|
97ebb3 | 2003-01-09 | Henrik Grubbström (Grubba) | | Pike_interpreter.trace_level = default_t_flag;
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | |
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | THREADS_FPRINTF(0, (stderr,"THREAD %08x INITED\n",(unsigned int)Pike_interpreter.thread_id));
|
38e1e8 | 2001-11-08 | Fredrik Hübinette (Hubbe) | |
DO_IF_DEBUG(
if(thread_for_id(th_self()) != Pike_interpreter.thread_id) {
debug_list_all_threads();
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("thread_for_id() (or Pike_interpreter.thread_id) failed! %p != %p\n",thread_for_id(th_self()),Pike_interpreter.thread_id) ;
|
38e1e8 | 2001-11-08 | Fredrik Hübinette (Hubbe) | | } )
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | if(SETJMP(back))
{
|
61e9a0 | 1998-01-25 | Fredrik Hübinette (Hubbe) | | if(throw_severity < THROW_EXIT)
|
669704 | 2000-11-20 | Martin Stjernholm | | call_handle_error();
|
61e9a0 | 1998-01-25 | Fredrik Hübinette (Hubbe) | | if(throw_severity == THROW_EXIT)
{
|
d40e38 | 1999-10-14 | Henrik Grubbström (Grubba) | | free((char *) data);
|
eb2fd5 | 2000-11-06 | Henrik Grubbström (Grubba) | | pike_do_exit(throw_value.u.integer);
|
61e9a0 | 1998-01-25 | Fredrik Hübinette (Hubbe) | | }
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | } else {
|
725ba9 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | INT32 args=arg.args->size;
|
61e9a0 | 1998-01-25 | Fredrik Hübinette (Hubbe) | | back.severity=THROW_EXIT;
|
6d1a5e | 1996-10-07 | Fredrik Hübinette (Hubbe) | | push_array_items(arg.args);
arg.args=0;
|
97ffe4 | 1997-01-26 | Per Hedbor | | f_call_function(args);
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | |
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | |
object_low_set_index(Pike_interpreter.thread_id,
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | thread_id_result_variable,
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | Pike_sp-1);
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | pop_stack();
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | }
|
38e1e8 | 2001-11-08 | Fredrik Hübinette (Hubbe) | | DO_IF_DEBUG(
if(thread_for_id(th_self()) != Pike_interpreter.thread_id) {
debug_list_all_threads();
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("thread_for_id() (or Pike_interpreter.thread_id) failed! %p != %p\n",thread_for_id(th_self()),Pike_interpreter.thread_id) ;
|
38e1e8 | 2001-11-08 | Fredrik Hübinette (Hubbe) | | } )
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | if(OBJ2THREAD(Pike_interpreter.thread_id)->thread_local != NULL) {
free_mapping(OBJ2THREAD(Pike_interpreter.thread_id)->thread_local);
OBJ2THREAD(Pike_interpreter.thread_id)->thread_local = NULL;
|
d86cd7 | 1998-08-24 | Marcus Comstedt | | }
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | OBJ2THREAD(Pike_interpreter.thread_id)->status=THREAD_EXITED;
co_broadcast(& OBJ2THREAD(Pike_interpreter.thread_id)->status_change);
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | |
|
4bdad0 | 1997-09-01 | Per Hedbor | | free((char *)data);
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | UNSETJMP(back);
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | THREADS_FPRINTF(0, (stderr,"THREADS_ALLOW() Thread %08x done\n",
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | (unsigned int)Pike_interpreter.thread_id));
|
b1b51f | 1996-10-11 | Fredrik Hübinette (Hubbe) | |
|
60d987 | 2000-03-23 | Fredrik Hübinette (Hubbe) | | cleanup_interpret();
DO_IF_DMALLOC(
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | SWAP_OUT_THREAD(OBJ2THREAD(Pike_interpreter.thread_id));
OBJ2THREAD(Pike_interpreter.thread_id)->swapped=0;
|
60d987 | 2000-03-23 | Fredrik Hübinette (Hubbe) | | )
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | thread_table_delete(Pike_interpreter.thread_id);
free_object(Pike_interpreter.thread_id);
Pike_interpreter.thread_id=0;
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | num_threads--;
|
fe76ce | 1997-09-08 | Fredrik Hübinette (Hubbe) | | if(!num_threads && threads_evaluator_callback)
|
a29e02 | 1996-10-15 | Fredrik Hübinette (Hubbe) | | {
remove_callback(threads_evaluator_callback);
threads_evaluator_callback=0;
}
|
0f65e1 | 2002-09-14 | Martin Stjernholm | |
#ifdef INTERNAL_PROFILING
fprintf (stderr, "Thread usage summary:\n");
debug_print_rusage (stderr);
#endif
|
4bc7e4 | 2001-11-26 | Henrik Grubbström (Grubba) | |
|
c91f89 | 2000-04-19 | Martin Stjernholm | | mt_unlock_interpreter();
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | th_exit(0);
|
9c8b2d | 1997-04-20 | Henrik Grubbström (Grubba) | |
|
89fc4c | 2000-08-10 | Henrik Grubbström (Grubba) | | return(0);
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | }
|
97ffe4 | 1997-01-26 | Per Hedbor | | #ifdef UNIX_THREADS
int num_lwps = 1;
#endif
|
b1b51f | 1996-10-11 | Fredrik Hübinette (Hubbe) | |
|
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | |
|
a44a58 | 2002-09-29 | Martin Nilsson | | |
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | | *!
*! This function creates a new thread which will run simultaneously
*! to the rest of the program. The new thread will call the function
*! @[f] with the arguments @[args]. When @[f] returns the thread will cease
*! to exist.
*!
*! All Pike functions are 'thread safe' meaning that running
*! a function at the same time from different threads will not corrupt
*! any internal data in the Pike process.
*!
*! @returns
*! The returned value will be the same as the return value of
|
c7b7dd | 2001-10-28 | Martin Nilsson | | *! @[this_thread()] for the new thread.
|
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | | *!
*! @note
*! This function is only available on systems with POSIX or UNIX or WIN32
*! threads support.
*!
*! @seealso
*! @[Mutex], @[Condition], @[this_thread()]
*/
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | void f_thread_create(INT32 args)
{
|
b1b51f | 1996-10-11 | Fredrik Hübinette (Hubbe) | | struct thread_starter *arg;
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | int tmp;
|
d40e38 | 1999-10-14 | Henrik Grubbström (Grubba) | | arg = ALLOC_STRUCT(thread_starter);
|
6d1a5e | 1996-10-07 | Fredrik Hübinette (Hubbe) | | arg->args=aggregate_array(args);
|
e70975 | 1997-03-12 | Fredrik Hübinette (Hubbe) | | arg->id=clone_object(thread_id_prog,0);
|
9b92d3 | 1999-01-31 | Fredrik Hübinette (Hubbe) | | OBJ2THREAD(arg->id)->status=THREAD_RUNNING;
|
b2a0fb | 1997-02-06 | Henrik Grubbström (Grubba) | |
|
222d92 | 2000-05-20 | Henrik Grubbström (Grubba) | | #ifdef HAVE_BROKEN_LINUX_THREAD_EUID
|
c17fed | 2000-05-20 | Henrik Grubbström (Grubba) | | arg->euid = geteuid();
arg->egid = getegid();
|
222d92 | 2000-05-20 | Henrik Grubbström (Grubba) | | #endif /* HAVE_BROKEN_LINUX_THREAD_EUID */
|
c17fed | 2000-05-20 | Henrik Grubbström (Grubba) | |
|
4743f8 | 1999-06-02 | Fredrik Hübinette (Hubbe) | | do {
|
d40e38 | 1999-10-14 | Henrik Grubbström (Grubba) | | tmp = th_create(& OBJ2THREAD(arg->id)->id,
new_thread_func,
arg);
|
700dac | 2002-02-05 | Martin Stjernholm | | if (tmp == EINTR) check_threads_etc();
|
4743f8 | 1999-06-02 | Fredrik Hübinette (Hubbe) | | } while( tmp == EINTR );
|
b2a0fb | 1997-02-06 | Henrik Grubbström (Grubba) | |
|
6d1a5e | 1996-10-07 | Fredrik Hübinette (Hubbe) | | if(!tmp)
{
num_threads++;
|
eac209 | 1998-02-27 | Marcus Comstedt | | thread_table_insert(arg->id);
|
a29e02 | 1996-10-15 | Fredrik Hübinette (Hubbe) | |
|
fe76ce | 1997-09-08 | Fredrik Hübinette (Hubbe) | | if(!threads_evaluator_callback)
|
a29e02 | 1996-10-15 | Fredrik Hübinette (Hubbe) | | {
threads_evaluator_callback=add_to_callback(&evaluator_callbacks,
check_threads, 0,0);
|
424d9c | 1999-05-02 | Fredrik Hübinette (Hubbe) | | dmalloc_accept_leak(threads_evaluator_callback);
|
a29e02 | 1996-10-15 | Fredrik Hübinette (Hubbe) | | }
|
d6ac73 | 1998-04-20 | Henrik Grubbström (Grubba) | | ref_push_object(arg->id);
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | THREADS_FPRINTF(0, (stderr, "THREAD_CREATE -> t:%08x\n",
(unsigned int)arg->id));
|
6d1a5e | 1996-10-07 | Fredrik Hübinette (Hubbe) | | } else {
free_object(arg->id);
free_array(arg->args);
free((char *)arg);
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Failed to create thread (errno = %d).\n",tmp);
|
6d1a5e | 1996-10-07 | Fredrik Hübinette (Hubbe) | | }
}
|
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | |
|
1e4a64 | 1997-09-03 | Martin Stjernholm | | #ifdef UNIX_THREADS
|
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | | |
c7b7dd | 2001-10-28 | Martin Nilsson | | *!
*! @fixme
*! Document this function
|
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | | */
|
97ffe4 | 1997-01-26 | Per Hedbor | | void f_thread_set_concurrency(INT32 args)
{
int c=1;
|
d4ecd7 | 2003-01-05 | Martin Nilsson | | if(args)
c=Pike_sp[-args].u.integer;
else
SIMPLE_TOO_FEW_ARGS_ERROR("thread_set_concurrency", 1);
|
97ffe4 | 1997-01-26 | Per Hedbor | | pop_n_elems(args);
|
09dceb | 1997-09-01 | Per Hedbor | | num_lwps=c;
|
97ffe4 | 1997-01-26 | Per Hedbor | | th_setconcurrency(c);
}
|
1e4a64 | 1997-09-03 | Martin Stjernholm | | #endif
|
97ffe4 | 1997-01-26 | Per Hedbor | |
|
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | | |
c7b7dd | 2001-10-28 | Martin Nilsson | | *! @[Thread()]
|
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | | */
|
fa8c69 | 2000-11-30 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_this_thread(INT32 args)
|
6d1a5e | 1996-10-07 | Fredrik Hübinette (Hubbe) | | {
pop_n_elems(args);
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | ref_push_object(Pike_interpreter.thread_id);
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | }
|
60d987 | 2000-03-23 | Fredrik Hübinette (Hubbe) | | #define THIS_MUTEX ((struct mutex_storage *)(CURRENT_STORAGE))
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | |
struct mutex_storage
{
COND_T condition;
struct object *key;
};
struct key_storage
{
struct mutex_storage *mut;
|
33887a | 2002-10-28 | Martin Stjernholm | | struct object *mutex_obj;
|
09dceb | 1997-09-01 | Per Hedbor | | struct object *owner;
|
4bdad0 | 1997-09-01 | Per Hedbor | | int initialized;
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | };
#define OB2KEY(X) ((struct key_storage *)((X)->storage))
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | |
|
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | | |
c7b7dd | 2001-10-28 | Martin Nilsson | | *! @[Mutex] is a class that implements mutual exclusion locks.
|
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | | *! Mutex locks are used to prevent multiple threads from simultaneously
*! execute sections of code which access or change shared data. The basic
*! operations for a mutex is locking and unlocking. If a thread attempts
*! to lock an already locked mutex the thread will sleep until the mutex
*! is unlocked.
*!
*! @note
*! This class is simulated when Pike is compiled without thread support,
*! so it's always available.
*!
*! In POSIX threads, mutex locks can only be unlocked by the same thread
*! that locked them. In Pike any thread can unlock a locked mutex.
*/
|
4f6801 | 2002-10-28 | Martin Stjernholm | | *! the key is destructed or has no more references the mutex will
*! automatically be unlocked. The key will also be destructed if the mutex
|
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | | *! is destructed.
*!
*! The @[type] argument specifies what @[lock()] should do if the
*! mutex is already locked by this thread:
*! @int
|
a9cdcf | 2001-02-06 | Henrik Grubbström (Grubba) | | *! @value 0
|
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | | *! Throw an error.
*! @value 1
*! Sleep until the mutex is unlocked. Useful if some
*! other thread will unlock it.
*! @value 2
*! Return zero. This allows recursion within a locked region of
*! code, but in conjunction with other locks it easily leads
*! to unspecified locking order and therefore a risk for deadlocks.
*! @endint
*!
*! @seealso
*! @[trylock()]
*/
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | void f_mutex_lock(INT32 args)
{
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | struct mutex_storage *m;
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | struct object *o;
|
a49ee6 | 1999-04-02 | Fredrik Hübinette (Hubbe) | | INT_TYPE type;
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | |
|
38e1e8 | 2001-11-08 | Fredrik Hübinette (Hubbe) | | DO_IF_DEBUG(
if(thread_for_id(th_self()) != Pike_interpreter.thread_id) {
debug_list_all_threads();
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("thread_for_id() (or Pike_interpreter.thread_id) failed! %p != %p\n",thread_for_id(th_self()),Pike_interpreter.thread_id) ;
|
38e1e8 | 2001-11-08 | Fredrik Hübinette (Hubbe) | | } )
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | m=THIS_MUTEX;
|
a49ee6 | 1999-04-02 | Fredrik Hübinette (Hubbe) | | if(!args)
type=0;
else
get_all_args("mutex->lock",args,"%i",&type);
switch(type)
{
default:
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | bad_arg_error("mutex->lock", Pike_sp-args, args, 2, "int(0..2)", Pike_sp+1-args,
|
69aa4b | 2003-01-26 | Mirar (Pontus Hagland) | | "Unknown mutex locking style: %"PRINTPIKEINT"d\n",type);
|
a49ee6 | 1999-04-02 | Fredrik Hübinette (Hubbe) | |
case 0:
case 2:
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | if(m->key && OB2KEY(m->key)->owner == Pike_interpreter.thread_id)
|
a49ee6 | 1999-04-02 | Fredrik Hübinette (Hubbe) | | {
THREADS_FPRINTF(0,
(stderr, "Recursive LOCK k:%08x, m:%08x(%08x), t:%08x\n",
(unsigned int)OB2KEY(m->key),
(unsigned int)m,
(unsigned int)OB2KEY(m->key)->mut,
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | (unsigned int) Pike_interpreter.thread_id));
|
a49ee6 | 1999-04-02 | Fredrik Hübinette (Hubbe) | |
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | if(type==0) Pike_error("Recursive mutex locks!\n");
|
a49ee6 | 1999-04-02 | Fredrik Hübinette (Hubbe) | |
pop_n_elems(args);
push_int(0);
|
c27369 | 2000-02-10 | Fredrik Hübinette (Hubbe) | | return;
|
a49ee6 | 1999-04-02 | Fredrik Hübinette (Hubbe) | | }
case 1:
break;
}
|
46d7bf | 1997-09-03 | Henrik Grubbström (Grubba) | |
|
eaa4da | 2001-10-04 | Fredrik Hübinette (Hubbe) | | o=fast_clone_object(mutex_key,0);
|
4bdad0 | 1997-09-01 | Per Hedbor | |
|
38e1e8 | 2001-11-08 | Fredrik Hübinette (Hubbe) | | DO_IF_DEBUG(
if(thread_for_id(th_self()) != Pike_interpreter.thread_id) {
debug_list_all_threads();
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("thread_for_id() (or Pike_interpreter.thread_id) failed! %p != %p\n",thread_for_id(th_self()),Pike_interpreter.thread_id) ;
|
38e1e8 | 2001-11-08 | Fredrik Hübinette (Hubbe) | | } )
|
26cd94 | 1999-05-07 | Fredrik Hübinette (Hubbe) | |
|
0a861b | 1997-09-17 | Fredrik Hübinette (Hubbe) | | if(m->key)
|
fe76ce | 1997-09-08 | Fredrik Hübinette (Hubbe) | | {
|
adb19b | 1999-06-30 | Fredrik Hübinette (Hubbe) | | if(threads_disabled)
{
free_object(o);
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Cannot wait for mutexes when threads are disabled!\n");
|
adb19b | 1999-06-30 | Fredrik Hübinette (Hubbe) | | }
|
b504ed | 1997-09-21 | Fredrik Hübinette (Hubbe) | | do
|
0a861b | 1997-09-17 | Fredrik Hübinette (Hubbe) | | {
|
700dac | 2002-02-05 | Martin Stjernholm | | SWAP_OUT_CURRENT_THREAD();
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | THREADS_FPRINTF(1, (stderr,"WAITING TO LOCK m:%08x\n",(unsigned int)m));
|
c91f89 | 2000-04-19 | Martin Stjernholm | | co_wait_interpreter(& m->condition);
|
700dac | 2002-02-05 | Martin Stjernholm | | SWAP_IN_CURRENT_THREAD();
check_threads_etc();
|
b504ed | 1997-09-21 | Fredrik Hübinette (Hubbe) | | }while(m->key);
|
fe76ce | 1997-09-08 | Fredrik Hübinette (Hubbe) | | }
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | m->key=o;
|
46d7bf | 1997-09-03 | Henrik Grubbström (Grubba) | | OB2KEY(o)->mut=m;
|
33887a | 2002-10-28 | Martin Stjernholm | | add_ref (OB2KEY(o)->mutex_obj = Pike_fp->current_object);
|
fe76ce | 1997-09-08 | Fredrik Hübinette (Hubbe) | |
|
38e1e8 | 2001-11-08 | Fredrik Hübinette (Hubbe) | | DO_IF_DEBUG(
if(thread_for_id(th_self()) != Pike_interpreter.thread_id) {
debug_list_all_threads();
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("thread_for_id() (or Pike_interpreter.thread_id) failed! %p != %p\n",thread_for_id(th_self()),Pike_interpreter.thread_id) ;
|
38e1e8 | 2001-11-08 | Fredrik Hübinette (Hubbe) | | } )
|
26cd94 | 1999-05-07 | Fredrik Hübinette (Hubbe) | |
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | THREADS_FPRINTF(1, (stderr, "LOCK k:%08x, m:%08x(%08x), t:%08x\n",
(unsigned int)OB2KEY(o),
(unsigned int)m,
(unsigned int)OB2KEY(m->key)->mut,
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | (unsigned int)Pike_interpreter.thread_id));
|
65d3c3 | 1997-09-08 | Fredrik Hübinette (Hubbe) | | pop_n_elems(args);
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | push_object(o);
}
|
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | |
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | void f_mutex_trylock(INT32 args)
{
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | struct mutex_storage *m;
struct object *o;
|
65a549 | 2000-08-10 | Per Hedbor | | INT_TYPE type;
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | int i=0;
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | |
|
46d7bf | 1997-09-03 | Henrik Grubbström (Grubba) | |
|
a49ee6 | 1999-04-02 | Fredrik Hübinette (Hubbe) | | m=THIS_MUTEX;
if(!args)
type=0;
else
|
afcf5f | 2000-10-04 | Martin Stjernholm | | get_all_args("mutex->trylock",args,"%i",&type);
|
a49ee6 | 1999-04-02 | Fredrik Hübinette (Hubbe) | |
switch(type)
|
65df5c | 1997-09-01 | Per Hedbor | | {
|
a49ee6 | 1999-04-02 | Fredrik Hübinette (Hubbe) | | default:
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | bad_arg_error("mutex->trylock", Pike_sp-args, args, 2, "int(0..2)", Pike_sp+1-args,
|
69aa4b | 2003-01-26 | Mirar (Pontus Hagland) | | "Unknown mutex locking style: %"PRINTPIKEINT"d\n",type);
|
a49ee6 | 1999-04-02 | Fredrik Hübinette (Hubbe) | |
case 0:
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | if(m->key && OB2KEY(m->key)->owner == Pike_interpreter.thread_id)
|
a49ee6 | 1999-04-02 | Fredrik Hübinette (Hubbe) | | {
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Recursive mutex locks!\n");
|
a49ee6 | 1999-04-02 | Fredrik Hübinette (Hubbe) | | }
case 2:
case 1:
break;
|
65df5c | 1997-09-01 | Per Hedbor | | }
|
50fd18 | 1997-09-17 | Fredrik Hübinette (Hubbe) | |
|
a49ee6 | 1999-04-02 | Fredrik Hübinette (Hubbe) | | o=clone_object(mutex_key,0);
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | if(!m->key)
{
|
e4293f | 1997-04-17 | Fredrik Hübinette (Hubbe) | | OB2KEY(o)->mut=m;
|
33887a | 2002-10-28 | Martin Stjernholm | | add_ref (OB2KEY(o)->mutex_obj = Pike_fp->current_object);
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | m->key=o;
i=1;
}
|
4bdad0 | 1997-09-01 | Per Hedbor | |
|
65d3c3 | 1997-09-08 | Fredrik Hübinette (Hubbe) | | pop_n_elems(args);
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | if(i)
{
push_object(o);
} else {
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | destruct(o);
free_object(o);
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | push_int(0);
}
}
|
b9bba0 | 2001-08-08 | Leif Stensson | | |
c7b7dd | 2001-10-28 | Martin Nilsson | | *! @[Thread()]
|
b9bba0 | 2001-08-08 | Leif Stensson | | */
PMOD_EXPORT void f_mutex_locking_thread(INT32 args)
{
struct mutex_storage *m = THIS_MUTEX;
pop_n_elems(args);
if (m->key && OB2KEY(m->key)->owner)
ref_push_object(OB2KEY(m->key)->owner);
else
push_int(0);
}
|
33887a | 2002-10-28 | Martin Stjernholm | | |
b9bba0 | 2001-08-08 | Leif Stensson | | *!
*! This mutex method returns the key object currently governing
*! the lock on this mutex. 0 is returned if the mutex isn't locked.
*!
*! @seealso
|
c7b7dd | 2001-10-28 | Martin Nilsson | | *! @[Thread()]
|
b9bba0 | 2001-08-08 | Leif Stensson | | */
PMOD_EXPORT void f_mutex_locking_key(INT32 args)
{
struct mutex_storage *m = THIS_MUTEX;
pop_n_elems(args);
if (m->key)
ref_push_object(m->key);
else
push_int(0);
}
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | void init_mutex_obj(struct object *o)
{
co_init(& THIS_MUTEX->condition);
THIS_MUTEX->key=0;
}
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | |
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | void exit_mutex_obj(struct object *o)
{
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | THREADS_FPRINTF(1, (stderr, "DESTROYING MUTEX m:%08x\n",
(unsigned int)THIS_MUTEX));
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | if(THIS_MUTEX->key) destruct(THIS_MUTEX->key);
|
88fe36 | 1997-09-04 | Per Hedbor | | THIS_MUTEX->key=0;
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | co_destroy(& THIS_MUTEX->condition);
}
|
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | |
|
60d987 | 2000-03-23 | Fredrik Hübinette (Hubbe) | | #define THIS_KEY ((struct key_storage *)(CURRENT_STORAGE))
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | void init_mutex_key_obj(struct object *o)
{
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | THREADS_FPRINTF(1, (stderr, "KEY k:%08x, o:%08x\n",
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | (unsigned int)THIS_KEY, (unsigned int)Pike_interpreter.thread_id));
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | THIS_KEY->mut=0;
|
33887a | 2002-10-28 | Martin Stjernholm | | THIS_KEY->mutex_obj = NULL;
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | add_ref(THIS_KEY->owner=Pike_interpreter.thread_id);
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | THIS_KEY->initialized=1;
}
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | |
void exit_mutex_key_obj(struct object *o)
{
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | THREADS_FPRINTF(1, (stderr, "UNLOCK k:%08x m:(%08x) t:%08x o:%08x\n",
(unsigned int)THIS_KEY,
(unsigned int)THIS_KEY->mut,
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | (unsigned int)Pike_interpreter.thread_id,
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | (unsigned int)THIS_KEY->owner));
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | if(THIS_KEY->mut)
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | {
|
03b1fe | 1997-09-06 | Per Hedbor | | struct mutex_storage *mut = THIS_KEY->mut;
|
c11387 | 1997-09-15 | Henrik Grubbström (Grubba) | |
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
03b1fe | 1997-09-06 | Per Hedbor | | if(mut->key != o)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Mutex unlock from wrong key %p != %p!\n",THIS_KEY->mut->key,o);
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | #endif
|
03b1fe | 1997-09-06 | Per Hedbor | | mut->key=0;
|
46d7bf | 1997-09-03 | Henrik Grubbström (Grubba) | | if (THIS_KEY->owner) {
free_object(THIS_KEY->owner);
THIS_KEY->owner=0;
}
|
33887a | 2002-10-28 | Martin Stjernholm | | free_object (THIS_KEY->mutex_obj);
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | THIS_KEY->mut=0;
|
33887a | 2002-10-28 | Martin Stjernholm | | THIS_KEY->mutex_obj = NULL;
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | THIS_KEY->initialized=0;
|
c11387 | 1997-09-15 | Henrik Grubbström (Grubba) | | co_signal(& mut->condition);
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | }
}
|
60d987 | 2000-03-23 | Fredrik Hübinette (Hubbe) | | #define THIS_COND ((COND_T *)(CURRENT_STORAGE))
|
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | |
|
c7b7dd | 2001-10-28 | Martin Nilsson | | *! @[Mutex]
|
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | | */
|
4a59c0 | 2002-09-30 | Henrik Grubbström (Grubba) | | |
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | | *!
*! Wait for contition.
*!
*! This function makes the current thread sleep until the condition
*! variable is signalled. The optional argument should be the 'key'
*! to a mutex lock. If present the mutex lock will be unlocked before
*! waiting for the condition in one atomic operation. After waiting
*! for the condition the mutex referenced by mutex_key will be re-locked.
*!
|
4a59c0 | 2002-09-30 | Henrik Grubbström (Grubba) | | *! @note
*! In Pike 7.2 and earlier it was possible to call @[wait()]
*! without arguments. This possibility was removed in Pike 7.3,
*! since it lead to programs with deadlocks.
*!
|
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | | *! @seealso
|
c7b7dd | 2001-10-28 | Martin Nilsson | | *! @[Mutex->lock()]
|
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | | */
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | void f_cond_wait(INT32 args)
{
|
4a59c0 | 2002-09-30 | Henrik Grubbström (Grubba) | | struct object *key;
struct mutex_storage *mut;
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | COND_T *c;
|
1c3c3d | 2000-03-24 | Henrik Grubbström (Grubba) | | if(threads_disabled)
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Cannot wait for conditions when threads are disabled!\n");
|
4a59c0 | 2002-09-30 | Henrik Grubbström (Grubba) | |
get_all_args("condition->wait", args, "%o", &key);
|
1c3c3d | 2000-03-24 | Henrik Grubbström (Grubba) | |
|
4a59c0 | 2002-09-30 | Henrik Grubbström (Grubba) | | if ((key->prog != mutex_key) ||
(!(OB2KEY(key)->initialized)) ||
(!(mut = OB2KEY(key)->mut))) {
Pike_error("Bad argument 1 to condition->wait()\n");
}
|
1c3c3d | 2000-03-24 | Henrik Grubbström (Grubba) | | if(args > 1) {
pop_n_elems(args - 1);
args = 1;
}
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | |
|
4a59c0 | 2002-09-30 | Henrik Grubbström (Grubba) | | c = THIS_COND;
|
368d4a | 1997-09-03 | Per Hedbor | |
|
4a59c0 | 2002-09-30 | Henrik Grubbström (Grubba) | |
mut->key=0;
OB2KEY(key)->mut=0;
co_signal(& mut->condition);
|
88fe36 | 1997-09-04 | Per Hedbor | |
|
4a59c0 | 2002-09-30 | Henrik Grubbström (Grubba) | |
|
1c3c3d | 2000-03-24 | Henrik Grubbström (Grubba) | | SWAP_OUT_CURRENT_THREAD();
|
c91f89 | 2000-04-19 | Martin Stjernholm | | co_wait_interpreter(c);
|
1c3c3d | 2000-03-24 | Henrik Grubbström (Grubba) | | SWAP_IN_CURRENT_THREAD();
|
4a59c0 | 2002-09-30 | Henrik Grubbström (Grubba) | |
while(mut->key) {
SWAP_OUT_CURRENT_THREAD();
co_wait_interpreter(& mut->condition);
SWAP_IN_CURRENT_THREAD();
check_threads_etc();
}
mut->key=key;
OB2KEY(key)->mut=mut;
pop_stack();
return;
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | }
|
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | | |
a9cdcf | 2001-02-06 | Henrik Grubbström (Grubba) | | *! @note
|
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | | *! Sometimes more than one thread is woken up.
*!
*! @seealso
*! @[broadcast()]
*/
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | void f_cond_signal(INT32 args) { pop_n_elems(args); co_signal(THIS_COND); }
|
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | |
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | void f_cond_broadcast(INT32 args) { pop_n_elems(args); co_broadcast(THIS_COND); }
|
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | |
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | void init_cond_obj(struct object *o) { co_init(THIS_COND); }
void exit_cond_obj(struct object *o) { co_destroy(THIS_COND); }
|
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | |
|
a7fef4 | 1997-09-03 | Per Hedbor | | void f_thread_backtrace(INT32 args)
{
|
a8e989 | 2001-09-05 | Fredrik Hübinette (Hubbe) | | void low_backtrace(struct Pike_interpreter *);
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | struct thread_state *foo = THIS_THREAD;
|
a8e989 | 2001-09-05 | Fredrik Hübinette (Hubbe) | |
|
a7fef4 | 1997-09-03 | Per Hedbor | | pop_n_elems(args);
|
a8e989 | 2001-09-05 | Fredrik Hübinette (Hubbe) | |
|
fad4ca | 2001-09-05 | Fredrik Hübinette (Hubbe) | | if(foo->state.thread_id == Pike_interpreter.thread_id)
{
f_backtrace(0);
}
else if(foo->state.stack_pointer)
|
a7fef4 | 1997-09-03 | Per Hedbor | | {
|
a8e989 | 2001-09-05 | Fredrik Hübinette (Hubbe) | | low_backtrace(& foo->state);
|
fad4ca | 2001-09-05 | Fredrik Hübinette (Hubbe) | | }
else
{
|
a7fef4 | 1997-09-03 | Per Hedbor | | push_int(0);
f_allocate(1);
}
}
|
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | |
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | void f_thread_id_status(INT32 args)
{
pop_n_elems(args);
push_int(THIS_THREAD->status);
}
|
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | | |
5e50ef | 2001-09-25 | Henrik Grubbström (Grubba) | | *! Returns a string identifying the thread.
|
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | | */
|
9a0d42 | 2000-02-06 | Martin Stjernholm | | void f_thread_id__sprintf (INT32 args)
{
|
e6dbc2 | 2002-11-29 | Marcus Comstedt | | int c = 0;
if(args>0 && Pike_sp[-args].type == PIKE_T_INT)
c = Pike_sp[-args].u.integer;
|
9a0d42 | 2000-02-06 | Martin Stjernholm | | pop_n_elems (args);
|
e6dbc2 | 2002-11-29 | Marcus Comstedt | | if(c != 'O') {
push_undefined();
return;
}
|
9a0d42 | 2000-02-06 | Martin Stjernholm | | push_constant_text ("Thread.Thread(");
|
8a08db | 2003-01-10 | Henrik Grubbström (Grubba) | | push_int64(((char *)THREAD_T_TO_PTR(THIS_THREAD->id))-(char *)0);
|
9a0d42 | 2000-02-06 | Martin Stjernholm | | push_constant_text (")");
f_add (3);
}
|
5e50ef | 2001-09-25 | Henrik Grubbström (Grubba) | | |
d685b9 | 2001-09-25 | Henrik Grubbström (Grubba) | | *!
*! @note
*! This function was added in Pike 7.2.204.
|
5e50ef | 2001-09-25 | Henrik Grubbström (Grubba) | | */
void f_thread_id_id_number(INT32 args)
{
pop_n_elems(args);
|
8a08db | 2003-01-10 | Henrik Grubbström (Grubba) | | push_int64(((char *)THREAD_T_TO_PTR(THIS_THREAD->id))-(char *)0);
|
5e50ef | 2001-09-25 | Henrik Grubbström (Grubba) | | }
|
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | |
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | static void f_thread_id_result(INT32 args)
{
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | struct thread_state *th=THIS_THREAD;
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | |
|
4bc7e4 | 2001-11-26 | Henrik Grubbström (Grubba) | | if (threads_disabled) {
Pike_error("Cannot wait for threads when threads are disabled!\n");
}
|
700dac | 2002-02-05 | Martin Stjernholm | | while(th->status != THREAD_EXITED) {
SWAP_OUT_CURRENT_THREAD();
|
c91f89 | 2000-04-19 | Martin Stjernholm | | co_wait_interpreter(&th->status_change);
|
700dac | 2002-02-05 | Martin Stjernholm | | SWAP_IN_CURRENT_THREAD();
check_threads_etc();
}
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | |
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | low_object_index_no_free(Pike_sp,
Pike_fp->current_object,
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | thread_id_result_variable);
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | Pike_sp++;
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | }
|
a7fef4 | 1997-09-03 | Per Hedbor | | void init_thread_obj(struct object *o)
{
|
16479e | 2002-11-18 | Martin Stjernholm | | MEMSET(&THIS_THREAD->state, 0, sizeof(struct Pike_interpreter));
THIS_THREAD->swapped = 0;
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | THIS_THREAD->status=THREAD_NOT_STARTED;
co_init(& THIS_THREAD->status_change);
|
d86cd7 | 1998-08-24 | Marcus Comstedt | | THIS_THREAD->thread_local=NULL;
|
9699fc | 2003-02-10 | Martin Stjernholm | | #if CPU_TIME_IS_THREAD_LOCAL == PIKE_YES
|
f4a995 | 2003-02-08 | Martin Stjernholm | | THIS_THREAD->auto_gc_time = 0;
#endif
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | }
void exit_thread_obj(struct object *o)
{
|
d86cd7 | 1998-08-24 | Marcus Comstedt | | if(THIS_THREAD->thread_local != NULL) {
free_mapping(THIS_THREAD->thread_local);
THIS_THREAD->thread_local = NULL;
}
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | co_destroy(& THIS_THREAD->status_change);
|
b1f4eb | 1998-01-13 | Fredrik Hübinette (Hubbe) | | th_destroy(& THIS_THREAD->id);
|
a7fef4 | 1997-09-03 | Per Hedbor | | }
|
a9cdcf | 2001-02-06 | Henrik Grubbström (Grubba) | | |
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | | */
|
a5bd2b | 2000-06-10 | Martin Stjernholm | | static void thread_was_recursed(struct object *o)
|
f6d017 | 1997-10-15 | Fredrik Hübinette (Hubbe) | | {
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | struct thread_state *tmp=THIS_THREAD;
|
d86cd7 | 1998-08-24 | Marcus Comstedt | | if(tmp->thread_local != NULL)
|
b102b0 | 2000-06-10 | Martin Stjernholm | | gc_recurse_mapping(tmp->thread_local);
|
d86cd7 | 1998-08-24 | Marcus Comstedt | | }
static void thread_was_checked(struct object *o)
{
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | struct thread_state *tmp=THIS_THREAD;
|
d86cd7 | 1998-08-24 | Marcus Comstedt | | if(tmp->thread_local != NULL)
|
d9d6f0 | 2001-06-30 | Martin Stjernholm | | debug_gc_check2(tmp->thread_local, T_OBJECT, o,
" as mapping for thread local values in thread");
|
177321 | 2000-04-12 | Fredrik Hübinette (Hubbe) | |
#ifdef PIKE_DEBUG
if(tmp->swapped)
{
struct pike_frame *f;
debug_malloc_touch(o);
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | debug_gc_xmark_svalues(tmp->state.evaluator_stack,
tmp->state.stack_pointer-tmp->state.evaluator_stack-1,
" in idle thread stack");
|
177321 | 2000-04-12 | Fredrik Hübinette (Hubbe) | |
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | for(f=tmp->state.frame_pointer;f;f=f->next)
|
177321 | 2000-04-12 | Fredrik Hübinette (Hubbe) | | {
debug_malloc_touch(f);
if(f->context.parent)
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | gc_external_mark2(f->context.parent,0," in Pike_fp->context.parent of idle thread");
gc_external_mark2(f->current_object,0," in Pike_fp->current_object of idle thread");
gc_external_mark2(f->context.prog,0," in Pike_fp->context.prog of idle thread");
|
177321 | 2000-04-12 | Fredrik Hübinette (Hubbe) | | }
}
#endif
|
d86cd7 | 1998-08-24 | Marcus Comstedt | | }
|
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | | |
c7b7dd | 2001-10-28 | Martin Nilsson | | *! stored in an instance of @[Local] can only be retrieved by that
|
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | | *! same thread.
*!
*! @note
*! This class is simulated when Pike is compiled without thread support,
*! so it's always available.
*/
|
d4e637 | 2001-02-06 | Henrik Grubbström (Grubba) | |
|
031939 | 2001-02-06 | Per Hedbor | | void f_thread_local_create( INT32 args )
|
d86cd7 | 1998-08-24 | Marcus Comstedt | | {
static INT32 thread_local_id = 0;
|
6b8788 | 2001-06-21 | Martin Stjernholm | | ((struct thread_local *)CURRENT_STORAGE)->id =
|
031939 | 2001-02-06 | Per Hedbor | | thread_local_id++;
pop_n_elems(args);
push_int(0);
}
|
d86cd7 | 1998-08-24 | Marcus Comstedt | |
|
031939 | 2001-02-06 | Per Hedbor | | PMOD_EXPORT void f_thread_local(INT32 args)
{
|
d86cd7 | 1998-08-24 | Marcus Comstedt | | struct object *loc = clone_object(thread_local_prog,0);
pop_n_elems(args);
push_object(loc);
}
|
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | | |
c7b7dd | 2001-10-28 | Martin Nilsson | | *! This returns the value prevoiusly stored in the @[Local] object by
|
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | | *! the @[set()] method by this thread.
*!
*! @seealso
*! @[set()]
*/
|
d86cd7 | 1998-08-24 | Marcus Comstedt | | void f_thread_local_get(INT32 args)
{
struct svalue key;
struct mapping *m;
|
60d987 | 2000-03-23 | Fredrik Hübinette (Hubbe) | | key.u.integer = ((struct thread_local *)CURRENT_STORAGE)->id;
|
d86cd7 | 1998-08-24 | Marcus Comstedt | | key.type = T_INT;
key.subtype = NUMBER_NUMBER;
pop_n_elems(args);
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | if(Pike_interpreter.thread_id != NULL &&
(m = OBJ2THREAD(Pike_interpreter.thread_id)->thread_local) != NULL)
mapping_index_no_free(Pike_sp++, m, &key);
|
d86cd7 | 1998-08-24 | Marcus Comstedt | | else {
push_int(0);
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | Pike_sp[-1].subtype=NUMBER_UNDEFINED;
|
d86cd7 | 1998-08-24 | Marcus Comstedt | | }
}
|
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | |
|
d86cd7 | 1998-08-24 | Marcus Comstedt | | void f_thread_local_set(INT32 args)
{
struct svalue key;
struct mapping *m;
|
60d987 | 2000-03-23 | Fredrik Hübinette (Hubbe) | | key.u.integer = ((struct thread_local *)CURRENT_STORAGE)->id;
|
d86cd7 | 1998-08-24 | Marcus Comstedt | | key.type = T_INT;
key.subtype = NUMBER_NUMBER;
if(args>1)
pop_n_elems(args-1);
else if(args<1)
|
d4ecd7 | 2003-01-05 | Martin Nilsson | | SIMPLE_TOO_FEW_ARGS_ERROR("Thread.Local.set", 1);
|
d86cd7 | 1998-08-24 | Marcus Comstedt | |
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | if(Pike_interpreter.thread_id == NULL)
|
cd6f7e | 2000-12-01 | Martin Stjernholm | | Pike_error("Trying to set Thread.Local without thread!\n");
|
d86cd7 | 1998-08-24 | Marcus Comstedt | |
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | if((m = OBJ2THREAD(Pike_interpreter.thread_id)->thread_local) == NULL)
m = OBJ2THREAD(Pike_interpreter.thread_id)->thread_local =
|
d86cd7 | 1998-08-24 | Marcus Comstedt | | allocate_mapping(4);
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | mapping_insert(m, &key, &Pike_sp[-1]);
|
d86cd7 | 1998-08-24 | Marcus Comstedt | | }
|
f6d017 | 1997-10-15 | Fredrik Hübinette (Hubbe) | |
|
d9d6f0 | 2001-06-30 | Martin Stjernholm | | #ifdef PIKE_DEBUG
void gc_check_thread_local (struct object *o)
{
if (Pike_in_gc == GC_PASS_LOCATE) {
struct svalue key, *val;
INT32 x;
struct thread_state *s;
key.u.integer = ((struct thread_local *)CURRENT_STORAGE)->id;
key.type = T_INT;
key.subtype = NUMBER_NUMBER;
|
f2c01e | 2003-01-08 | Martin Stjernholm | | FOR_EACH_THREAD (s, {
|
d9d6f0 | 2001-06-30 | Martin Stjernholm | | if (s->thread_local &&
(val = low_mapping_lookup(s->thread_local, &key)))
debug_gc_check_svalues2(val, 1, T_OBJECT, o,
" as thread local value in Thread.Local object"
" (indirect ref)");
|
f2c01e | 2003-01-08 | Martin Stjernholm | | });
|
d9d6f0 | 2001-06-30 | Martin Stjernholm | | }
}
#endif
|
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | |
|
a9cdcf | 2001-02-06 | Henrik Grubbström (Grubba) | |
|
64b7b6 | 2000-11-02 | Henrik Grubbström (Grubba) | |
static struct farmer {
struct farmer *neighbour;
void *field;
void (*harvest)(void *);
THREAD_T me;
COND_T harvest_moon;
#ifdef HAVE_BROKEN_LINUX_THREAD_EUID
int euid, egid;
#endif /* HAVE_BROKEN_LINUX_THREAD_EUID */
} *farmers;
static MUTEX_T rosie;
static int _num_farmers, _num_idle_farmers;
static TH_RETURN_TYPE farm(void *_a)
{
struct farmer *me = (struct farmer *)_a;
#ifdef HAVE_BROKEN_LINUX_THREAD_EUID
if (!geteuid()) {
setegid(me->egid);
seteuid(me->euid);
}
#endif /* HAVE_BROKEN_LINUX_THREAD_EUID */
do
{
|
5aad93 | 2002-08-15 | Marcus Comstedt | |
|
64b7b6 | 2000-11-02 | Henrik Grubbström (Grubba) | |
me->harvest( me->field );
me->harvest = 0;
mt_lock( &rosie );
if( ++_num_idle_farmers > 16 )
{
--_num_idle_farmers;
--_num_farmers;
mt_unlock( &rosie );
free( me );
return 0;
}
me->neighbour = farmers;
farmers = me;
while(!me->harvest) co_wait( &me->harvest_moon, &rosie );
--_num_idle_farmers;
mt_unlock( &rosie );
} while(1);
return 0;
}
int th_num_idle_farmers(void)
{
return _num_idle_farmers;
}
int th_num_farmers(void)
{
return _num_farmers;
}
static struct farmer *new_farmer(void (*fun)(void *), void *args)
{
struct farmer *me = malloc(sizeof(struct farmer));
if (!me) {
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("new_farmer(): Out of memory!\n");
|
64b7b6 | 2000-11-02 | Henrik Grubbström (Grubba) | | }
dmalloc_accept_leak(me);
_num_farmers++;
me->neighbour = 0;
me->field = args;
me->harvest = fun;
co_init( &me->harvest_moon );
#ifdef HAVE_BROKEN_LINUX_THREAD_EUID
me->euid = geteuid();
me->egid = getegid();
#endif /* HAVE_BROKEN_LINUX_THREAD_EUID */
th_create_small(&me->me, farm, me);
return me;
}
PMOD_EXPORT void th_farm(void (*fun)(void *), void *here)
{
|
5aad93 | 2002-08-15 | Marcus Comstedt | | if(!fun) Pike_fatal("The farmers don't known how to handle empty fields\n");
|
64b7b6 | 2000-11-02 | Henrik Grubbström (Grubba) | | mt_lock( &rosie );
if(farmers)
{
struct farmer *f = farmers;
farmers = f->neighbour;
f->field = here;
f->harvest = fun;
mt_unlock( &rosie );
co_signal( &f->harvest_moon );
return;
}
mt_unlock( &rosie );
new_farmer( fun, here );
}
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | void low_th_init(void)
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | {
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | THREADS_FPRINTF(0, (stderr, "THREADS_DISALLOW() Initializing threads.\n"));
|
fed8de | 1997-10-05 | Henrik Grubbström (Grubba) | |
|
83b184 | 2003-02-08 | Martin Stjernholm | | really_low_th_init();
|
fed8de | 1997-10-05 | Henrik Grubbström (Grubba) | |
|
12ae2f | 1997-09-05 | Henrik Grubbström (Grubba) | | mt_init( & interpreter_lock);
|
bc21dc | 2001-11-01 | Martin Stjernholm | | low_mt_lock_interpreter();
|
eac209 | 1998-02-27 | Marcus Comstedt | | mt_init( & thread_table_lock);
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | mt_init( & interleave_lock);
|
64b7b6 | 2000-11-02 | Henrik Grubbström (Grubba) | | mt_init( & rosie);
|
ef1e93 | 1998-03-26 | Henrik Grubbström (Grubba) | | co_init( & live_threads_change);
co_init( & threads_disabled_change);
|
eac209 | 1998-02-27 | Marcus Comstedt | | thread_table_init();
|
864d3c | 1998-01-29 | Fredrik Hübinette (Hubbe) | |
|
83b184 | 2003-02-08 | Martin Stjernholm | | #ifdef POSIX_THREADS
|
b32ef1 | 2000-04-19 | Martin Stjernholm | | th_running = 1;
|
e4419e | 1997-02-06 | Fredrik Hübinette (Hubbe) | | #endif
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | }
void th_init(void)
{
|
89fc4c | 2000-08-10 | Henrik Grubbström (Grubba) | | ptrdiff_t mutex_key_offset;
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | |
|
e4419e | 1997-02-06 | Fredrik Hübinette (Hubbe) | | #ifdef UNIX_THREADS
|
45ee5d | 1999-02-10 | Fredrik Hübinette (Hubbe) | |
ADD_EFUN("thread_set_concurrency",f_thread_set_concurrency,tFunc(tInt,tVoid), OPT_SIDE_EFFECT);
|
e4419e | 1997-02-06 | Fredrik Hübinette (Hubbe) | | #endif
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | |
|
3f87be | 1999-12-14 | Martin Stjernholm | | START_NEW_PROGRAM_ID(THREAD_MUTEX_KEY);
|
90e978 | 1999-01-31 | Fredrik Hübinette (Hubbe) | | mutex_key_offset = ADD_STORAGE(struct key_storage);
|
46d7bf | 1997-09-03 | Henrik Grubbström (Grubba) | | |
e413da | 2001-02-01 | Henrik Grubbström (Grubba) | | * It also allows a thread to take over ownership of a key.
|
46d7bf | 1997-09-03 | Henrik Grubbström (Grubba) | | */
|
33887a | 2002-10-28 | Martin Stjernholm | | PIKE_MAP_VARIABLE("_owner", mutex_key_offset + OFFSETOF(key_storage, owner),
tObjIs_THREAD_ID, T_OBJECT, 0);
PIKE_MAP_VARIABLE("_mutex", mutex_key_offset + OFFSETOF(key_storage, mutex_obj),
tObjIs_THREAD_MUTEX, T_OBJECT, ID_STATIC|ID_PRIVATE);
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | set_init_callback(init_mutex_key_obj);
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | set_exit_callback(exit_mutex_key_obj);
|
bad516 | 2000-06-23 | Fredrik Hübinette (Hubbe) | | mutex_key=Pike_compiler->new_program;
|
3f87be | 1999-12-14 | Martin Stjernholm | | add_ref(mutex_key);
end_class("mutex_key", 0);
|
b1f4eb | 1998-01-13 | Fredrik Hübinette (Hubbe) | | mutex_key->flags|=PROGRAM_DESTRUCT_IMMEDIATE;
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
f839fa | 1997-02-28 | Fredrik Hübinette (Hubbe) | | if(!mutex_key)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Failed to initialize mutex_key program!\n");
|
e45f66 | 1998-03-20 | Fredrik Hübinette (Hubbe) | | #endif
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | |
|
3f87be | 1999-12-14 | Martin Stjernholm | | START_NEW_PROGRAM_ID(THREAD_MUTEX);
|
52e4c6 | 1999-12-13 | Martin Stjernholm | | ADD_STORAGE(struct mutex_storage);
|
3f87be | 1999-12-14 | Martin Stjernholm | | ADD_FUNCTION("lock",f_mutex_lock,
tFunc(tOr(tInt02,tVoid),tObjIs_THREAD_MUTEX_KEY),0);
|
52e4c6 | 1999-12-13 | Martin Stjernholm | |
|
3f87be | 1999-12-14 | Martin Stjernholm | | ADD_FUNCTION("trylock",f_mutex_trylock,
tFunc(tOr(tInt02,tVoid),tObjIs_THREAD_MUTEX_KEY),0);
|
b9bba0 | 2001-08-08 | Leif Stensson | |
ADD_FUNCTION("current_locking_thread",f_mutex_locking_thread,
tFunc(tNone,tObjIs_THREAD_ID), 0);
ADD_FUNCTION("current_locking_key",f_mutex_locking_key,
tFunc(tNone,tObjIs_THREAD_MUTEX_KEY), 0);
|
52e4c6 | 1999-12-13 | Martin Stjernholm | | set_init_callback(init_mutex_obj);
set_exit_callback(exit_mutex_obj);
end_class("mutex", 0);
|
3f87be | 1999-12-14 | Martin Stjernholm | | START_NEW_PROGRAM_ID(THREAD_CONDITION);
|
90e978 | 1999-01-31 | Fredrik Hübinette (Hubbe) | | ADD_STORAGE(COND_T);
|
4a59c0 | 2002-09-30 | Henrik Grubbström (Grubba) | |
|
3f87be | 1999-12-14 | Martin Stjernholm | | ADD_FUNCTION("wait",f_cond_wait,
|
4a59c0 | 2002-09-30 | Henrik Grubbström (Grubba) | | tFunc(tObjIs_THREAD_MUTEX_KEY,tVoid),0);
|
45ee5d | 1999-02-10 | Fredrik Hübinette (Hubbe) | |
|
b93e6e | 1999-06-19 | Fredrik Hübinette (Hubbe) | | ADD_FUNCTION("signal",f_cond_signal,tFunc(tNone,tVoid),0);
|
45ee5d | 1999-02-10 | Fredrik Hübinette (Hubbe) | |
|
b93e6e | 1999-06-19 | Fredrik Hübinette (Hubbe) | | ADD_FUNCTION("broadcast",f_cond_broadcast,tFunc(tNone,tVoid),0);
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | set_init_callback(init_cond_obj);
set_exit_callback(exit_cond_obj);
|
b98eb3 | 1997-02-11 | Henrik Grubbström (Grubba) | | end_class("condition", 0);
|
de413f | 1998-03-26 | Per Hedbor | |
{
struct program *tmp;
|
3f87be | 1999-12-14 | Martin Stjernholm | | START_NEW_PROGRAM_ID(THREAD_DISABLE_THREADS);
|
de413f | 1998-03-26 | Per Hedbor | | set_init_callback(init_threads_disable);
set_exit_callback(exit_threads_disable);
|
bad516 | 2000-06-23 | Fredrik Hübinette (Hubbe) | | tmp = Pike_compiler->new_program;
|
3f87be | 1999-12-14 | Martin Stjernholm | | add_ref(tmp);
end_class("threads_disabled", 0);
|
de413f | 1998-03-26 | Per Hedbor | | tmp->flags|=PROGRAM_DESTRUCT_IMMEDIATE;
add_global_program("_disable_threads", tmp);
|
56a696 | 1998-04-05 | Fredrik Hübinette (Hubbe) | | free_program(tmp);
|
de413f | 1998-03-26 | Per Hedbor | | }
|
6d1a5e | 1996-10-07 | Fredrik Hübinette (Hubbe) | |
|
3f87be | 1999-12-14 | Martin Stjernholm | | START_NEW_PROGRAM_ID(THREAD_LOCAL);
|
90e978 | 1999-01-31 | Fredrik Hübinette (Hubbe) | | ADD_STORAGE(struct thread_local);
|
b93e6e | 1999-06-19 | Fredrik Hübinette (Hubbe) | | ADD_FUNCTION("get",f_thread_local_get,tFunc(tNone,tMix),0);
|
b21d9e | 2000-11-06 | Martin Stjernholm | | ADD_FUNCTION("set",f_thread_local_set,tFunc(tSetvar(1,tMix),tVar(1)),0);
|
d4e637 | 2001-02-06 | Henrik Grubbström (Grubba) | | ADD_FUNCTION("create", f_thread_local_create,
tFunc(tVoid,tVoid), ID_STATIC);
|
d9d6f0 | 2001-06-30 | Martin Stjernholm | | #ifdef PIKE_DEBUG
set_gc_check_callback(gc_check_thread_local);
#endif
|
bad516 | 2000-06-23 | Fredrik Hübinette (Hubbe) | | thread_local_prog=Pike_compiler->new_program;
|
3f87be | 1999-12-14 | Martin Stjernholm | | add_ref(thread_local_prog);
end_class("thread_local", 0);
|
d86cd7 | 1998-08-24 | Marcus Comstedt | | if(!thread_local_prog)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Failed to initialize thread_local program!\n");
|
d4e637 | 2001-02-06 | Henrik Grubbström (Grubba) | | ADD_EFUN("thread_local", f_thread_local,
|
3f87be | 1999-12-14 | Martin Stjernholm | | tFunc(tNone,tObjIs_THREAD_LOCAL),
|
d4e637 | 2001-02-06 | Henrik Grubbström (Grubba) | | OPT_EXTERNAL_DEPEND);
|
d86cd7 | 1998-08-24 | Marcus Comstedt | |
|
3f87be | 1999-12-14 | Martin Stjernholm | | START_NEW_PROGRAM_ID(THREAD_ID);
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | thread_storage_offset=ADD_STORAGE(struct thread_state);
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | thread_id_result_variable=simple_add_variable("result","mixed",0);
|
45ee5d | 1999-02-10 | Fredrik Hübinette (Hubbe) | |
|
b93e6e | 1999-06-19 | Fredrik Hübinette (Hubbe) | | ADD_FUNCTION("backtrace",f_thread_backtrace,tFunc(tNone,tArray),0);
|
45ee5d | 1999-02-10 | Fredrik Hübinette (Hubbe) | |
|
b93e6e | 1999-06-19 | Fredrik Hübinette (Hubbe) | | ADD_FUNCTION("wait",f_thread_id_result,tFunc(tNone,tMix),0);
|
45ee5d | 1999-02-10 | Fredrik Hübinette (Hubbe) | |
|
b93e6e | 1999-06-19 | Fredrik Hübinette (Hubbe) | | ADD_FUNCTION("status",f_thread_id_status,tFunc(tNone,tInt),0);
|
9a0d42 | 2000-02-06 | Martin Stjernholm | | ADD_FUNCTION("_sprintf",f_thread_id__sprintf,tFunc(tNone,tStr),0);
|
5e50ef | 2001-09-25 | Henrik Grubbström (Grubba) | | ADD_FUNCTION("id_number",f_thread_id_id_number,tFunc(tNone,tInt),0);
|
a5bd2b | 2000-06-10 | Martin Stjernholm | | set_gc_recurse_callback(thread_was_recursed);
|
d86cd7 | 1998-08-24 | Marcus Comstedt | | set_gc_check_callback(thread_was_checked);
|
a7fef4 | 1997-09-03 | Per Hedbor | | set_init_callback(init_thread_obj);
|
a2db6b | 1998-01-02 | Fredrik Hübinette (Hubbe) | | set_exit_callback(exit_thread_obj);
|
bad516 | 2000-06-23 | Fredrik Hübinette (Hubbe) | | thread_id_prog=Pike_compiler->new_program;
|
95363a | 2000-04-11 | Fredrik Hübinette (Hubbe) | | thread_id_prog->flags |= PROGRAM_NO_EXPLICIT_DESTRUCT;
|
3f87be | 1999-12-14 | Martin Stjernholm | | add_ref(thread_id_prog);
end_class("thread_id", 0);
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | |
|
3f87be | 1999-12-14 | Martin Stjernholm | | ADD_EFUN("thread_create",f_thread_create,
tFuncV(tNone,tMixed,tObjIs_THREAD_ID),
OPT_SIDE_EFFECT);
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | |
|
3f87be | 1999-12-14 | Martin Stjernholm | | ADD_EFUN("this_thread",f_this_thread,
tFunc(tNone,tObjIs_THREAD_ID),
OPT_EXTERNAL_DEPEND);
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | |
|
3f87be | 1999-12-14 | Martin Stjernholm | | ADD_EFUN("all_threads",f_all_threads,
tFunc(tNone,tArr(tObjIs_THREAD_ID)),
OPT_EXTERNAL_DEPEND);
|
52e4c6 | 1999-12-13 | Martin Stjernholm | |
|
5d2f12 | 1998-08-27 | Henrik Grubbström (Grubba) | |
add_integer_constant("THREAD_NOT_STARTED", THREAD_NOT_STARTED, 0);
add_integer_constant("THREAD_RUNNING", THREAD_RUNNING, 0);
add_integer_constant("THREAD_EXITED", THREAD_EXITED, 0);
|
f839fa | 1997-02-28 | Fredrik Hübinette (Hubbe) | | if(!mutex_key)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Failed to initialize thread program!\n");
|
6d1a5e | 1996-10-07 | Fredrik Hübinette (Hubbe) | |
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | Pike_interpreter.thread_id=clone_object(thread_id_prog,0);
SWAP_OUT_THREAD(OBJ2THREAD(Pike_interpreter.thread_id));
OBJ2THREAD(Pike_interpreter.thread_id)->id=th_self();
OBJ2THREAD(Pike_interpreter.thread_id)->swapped=0;
thread_table_insert(Pike_interpreter.thread_id);
|
6d1a5e | 1996-10-07 | Fredrik Hübinette (Hubbe) | | }
|
be478c | 1997-08-30 | Henrik Grubbström (Grubba) | | void th_cleanup(void)
|
6d1a5e | 1996-10-07 | Fredrik Hübinette (Hubbe) | | {
|
b32ef1 | 2000-04-19 | Martin Stjernholm | | th_running = 0;
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | if(Pike_interpreter.thread_id)
|
c3b995 | 2000-02-15 | Henrik Grubbström (Grubba) | | {
|
17f08c | 2000-07-06 | Fredrik Hübinette (Hubbe) | | thread_table_delete(Pike_interpreter.thread_id);
destruct(Pike_interpreter.thread_id);
free_object(Pike_interpreter.thread_id);
Pike_interpreter.thread_id=0;
|
56f4f4 | 2001-09-18 | Fredrik Hübinette (Hubbe) | | destruct_objects_to_destruct_cb();
|
c3b995 | 2000-02-15 | Henrik Grubbström (Grubba) | | }
|
6d1a5e | 1996-10-07 | Fredrik Hübinette (Hubbe) | | if(mutex_key)
{
free_program(mutex_key);
mutex_key=0;
}
|
d86cd7 | 1998-08-24 | Marcus Comstedt | | if(thread_local_prog)
{
free_program(thread_local_prog);
thread_local_prog=0;
}
|
6d1a5e | 1996-10-07 | Fredrik Hübinette (Hubbe) | | if(thread_id_prog)
{
free_program(thread_id_prog);
thread_id_prog=0;
}
|
58580c | 2001-11-12 | Martin Stjernholm | |
#ifdef PIKE_USE_OWN_ATFORK
free_callback_list(&atfork_prepare_callback);
free_callback_list(&atfork_parent_callback);
free_callback_list(&atfork_child_callback);
#endif
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | }
|
83b184 | 2003-02-08 | Martin Stjernholm | | #endif /* !CONFIGURE_TEST */
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | #endif
|