From e83eb988ee51a103ddc7b3b6e5271eced0a330c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net> Date: Thu, 22 Mar 2001 19:14:41 -0800 Subject: [PATCH] experimental code for SMP, does nothing exciting yet Rev: src/acconfig.h:1.83 Rev: src/array.h:1.32 Rev: src/configure.in:1.508 Rev: src/global.h:1.59 Rev: src/mapping.h:1.35 Rev: src/multiset.h:1.17 Rev: src/object.h:1.60 Rev: src/pike_cpulib.h:1.1 Rev: src/program.h:1.121 Rev: src/stralloc.h:1.60 Rev: src/svalue.h:1.82 --- src/acconfig.h | 5 ++++- src/array.h | 4 ++-- src/configure.in | 4 +++- src/global.h | 4 ++-- src/mapping.h | 4 ++-- src/multiset.h | 4 ++-- src/object.h | 4 ++-- src/pike_cpulib.h | 49 +++++++++++++++++++++++++++++++++++++++++++++++ src/program.h | 4 ++-- src/stralloc.h | 4 ++-- src/svalue.h | 38 ++++++++++++++++++++++++++++++------ 11 files changed, 102 insertions(+), 22 deletions(-) create mode 100644 src/pike_cpulib.h diff --git a/src/acconfig.h b/src/acconfig.h index f93ce09115..dceb1c57f9 100644 --- a/src/acconfig.h +++ b/src/acconfig.h @@ -1,5 +1,5 @@ /* - * $Id: acconfig.h,v 1.82 2001/03/13 04:09:18 hubbe Exp $ + * $Id: acconfig.h,v 1.83 2001/03/23 03:14:39 hubbe Exp $ */ #ifndef MACHINE_H #define MACHINE_H @@ -36,6 +36,9 @@ /* Define this to enable the internal bignum conversion */ #undef AUTO_BIGNUM +/* Define this to enable experimental code for multicpu machines */ +#define PIKE_RUN_UNLOCKED + /* Define this if you want to enable the shared nodes mode of the optimizer. */ #undef SHARED_NODES diff --git a/src/array.h b/src/array.h index 41a5850e26..5a278bac12 100644 --- a/src/array.h +++ b/src/array.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: array.h,v 1.31 2001/02/03 01:02:51 mast Exp $ + * $Id: array.h,v 1.32 2001/03/23 03:14:39 hubbe Exp $ */ #ifndef ARRAY_H #define ARRAY_H @@ -78,7 +78,7 @@ extern struct array *gc_internal_array; #define PIKE_ARRAY_OP_SUB PIKE_MINTERM(PIKE_ARRAY_OP_TAKE_A,PIKE_ARRAY_OP_SKIP_A ,PIKE_ARRAY_OP_SKIP_B) -#define free_array(V) do{ struct array *v_=(V); debug_malloc_touch(v_); if(!--v_->refs) really_free_array(v_); }while(0) +#define free_array(V) do{ struct array *v_=(V); debug_malloc_touch(v_); if(!sub_ref(v_)) really_free_array(v_); }while(0) #define allocate_array(X) low_allocate_array((X),0) #define allocate_array_no_init(X,Y) low_allocate_array((X),(Y)) diff --git a/src/configure.in b/src/configure.in index c9af4202aa..1c3a7b6f04 100644 --- a/src/configure.in +++ b/src/configure.in @@ -1,4 +1,4 @@ -AC_REVISION("$Id: configure.in,v 1.507 2001/03/23 01:05:41 grubba Exp $") +AC_REVISION("$Id: configure.in,v 1.508 2001/03/23 03:14:39 hubbe Exp $") AC_INIT(interpret.c) AC_CONFIG_HEADER(machine.h) @@ -878,6 +878,8 @@ AC_ARG_WITH(security, [ --with-security enable internal pike security AC_ARG_WITH(bignums, [ --without-bignums disable internal conversion to bignums],[],[with_bignums=yes]) AC_ARG_WITH(shared-nodes,[ --without-shared-nodes disable the SHARED_NODES mode of the optimizer],[],[with_shared_nodes=yes]) +AC_ARG_WITH(shared-nodes,[ --without-lock Enable experimental code for multicpu machines.],[ AC_DEFINE(PIKE_RUN_UNLOCKED) ],[]) + # This makes configure default to --without-Perl # Remove this when the Perl module stops crashing and hanging. -Hubbe AC_ARG_WITH(perl, [ --with-perl enable the embedded Perl module (EXPERIMENTAL)],[], diff --git a/src/global.h b/src/global.h index df658160d3..8c0796c338 100644 --- a/src/global.h +++ b/src/global.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: global.h,v 1.58 2001/03/04 15:27:53 mirar Exp $ + * $Id: global.h,v 1.59 2001/03/23 03:14:40 hubbe Exp $ */ #ifndef GLOBAL_H #define GLOBAL_H @@ -377,7 +377,7 @@ static inline long PTRDIFF_T_TO_LONG(ptrdiff_t x) #include "port.h" #include "dmalloc.h" - +#include "pike_cpulib.h" #ifdef BUFSIZ #define PROT_STDIO(x) PROT(x) diff --git a/src/mapping.h b/src/mapping.h index 3969d6e2c1..d25b987509 100644 --- a/src/mapping.h +++ b/src/mapping.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: mapping.h,v 1.34 2000/12/16 05:45:44 marcus Exp $ + * $Id: mapping.h,v 1.35 2001/03/23 03:14:40 hubbe Exp $ */ #ifndef MAPPING_H #define MAPPING_H @@ -70,7 +70,7 @@ extern struct mapping *gc_internal_mapping; #define MAPPING_LOOP(m) \ for((e=0) DO_IF_DMALLOC( ?0:(debug_malloc_touch(m),debug_malloc_touch(m->data))) ;e<m->data->hashsize;e++) for(k=m->data->hash[e];k;k=k->next) -#define free_mapping(M) do{ struct mapping *m_=(M); debug_malloc_touch(m_); if(!--m_->refs) really_free_mapping(m_); }while(0) +#define free_mapping(M) do{ struct mapping *m_=(M); debug_malloc_touch(m_); if(!sub_ref(m_)) really_free_mapping(m_); }while(0) #define free_mapping_data(M) do{ \ struct mapping_data *md_=(M); \ diff --git a/src/multiset.h b/src/multiset.h index f73477da3e..ae0a6e67a9 100644 --- a/src/multiset.h +++ b/src/multiset.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: multiset.h,v 1.16 2000/12/16 05:24:41 marcus Exp $ + * $Id: multiset.h,v 1.17 2001/03/23 03:14:40 hubbe Exp $ */ #ifndef MULTISET_H #define MULTISET_H @@ -25,7 +25,7 @@ struct multiset extern struct multiset *first_multiset; extern struct multiset *gc_internal_multiset; -#define free_multiset(L) do{ struct multiset *l_=(L); debug_malloc_touch(l_); if(!--l_->refs) really_free_multiset(l_); }while(0) +#define free_multiset(L) do{ struct multiset *l_=(L); debug_malloc_touch(l_); if(!sub_ref(l_)) really_free_multiset(l_); }while(0) #define l_sizeof(L) ((L)->ind->size) diff --git a/src/object.h b/src/object.h index 8deaec1e37..4b9737cb77 100644 --- a/src/object.h +++ b/src/object.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: object.h,v 1.59 2001/03/20 19:27:33 hubbe Exp $ + * $Id: object.h,v 1.60 2001/03/23 03:14:40 hubbe Exp $ */ #ifndef OBJECT_H #define OBJECT_H @@ -43,7 +43,7 @@ extern struct program *master_program; extern struct program *magic_index_program; extern struct program *magic_set_index_program; -#define free_object(O) do{ struct object *o_=(O); debug_malloc_touch(o_); debug_malloc_touch(o_->storage); if(!--o_->refs) schedule_really_free_object(o_); }while(0) +#define free_object(O) do{ struct object *o_=(O); debug_malloc_touch(o_); debug_malloc_touch(o_->storage); if(!sub_ref(o_)) schedule_really_free_object(o_); }while(0) #define LOW_GET_GLOBAL(O,I,ID) ((O)->storage+INHERIT_FROM_INT((O)->prog, (I))->storage_offset+(ID)->func.offset) #define GET_GLOBAL(O,I) LOW_GET_GLOBAL(O,I,ID_FROM_INT((O)->prog,I)) diff --git a/src/pike_cpulib.h b/src/pike_cpulib.h new file mode 100644 index 0000000000..974a292444 --- /dev/null +++ b/src/pike_cpulib.h @@ -0,0 +1,49 @@ +#ifndef PIKE_CPULIB_H +#define PIKE_CPULIB_H + + +/* Autoconf this? */ +#if defined(__i386__) && defined(__GNUC__) + +#define PIKE_HAS_COMPARE_AND_SWAP + +static inline int +pike_atomic_compare_and_swap (INT32 *p, INT32 oldval, INT32 newval) +{ + char ret; + INT32 readval; + + __asm__ __volatile__ ("lock; cmpxchgl %3, %1; sete %0" + : "=q" (ret), "=m" (*p), "=a" (readval) + : "r" (newval), "m" (*p), "a" (oldval) + : "memory"); + return ret; +} + +#endif + + + + +#ifdef PIKE_HAS_COMPARE_AND_SWAP +static inline INT32 pike_atomic_add_ref(INT32 *ref) +{ + INT32 oldrefs; + do + oldrefs=*ref; + while(! pike_atomic_compare_and_swap(ref, oldrefs, oldrefs+1)); + return oldrefs; +} + +static inline INT32 pike_atomic_sub_ref(INT32 *ref) +{ + INT32 oldrefs; + do + oldrefs=*ref; + while(! pike_atomic_compare_and_swap(ref, oldrefs, oldrefs-1)); + return oldrefs-1; +} + +#endif + +#endif diff --git a/src/program.h b/src/program.h index 2d7978dda8..666d46b499 100644 --- a/src/program.h +++ b/src/program.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: program.h,v 1.120 2001/03/20 02:45:51 hubbe Exp $ + * $Id: program.h,v 1.121 2001/03/23 03:14:41 hubbe Exp $ */ #ifndef PROGRAM_H #define PROGRAM_H @@ -315,7 +315,7 @@ struct program #define FIND_LFUN(P,N) ( dmalloc_touch(struct program *,(P))->flags & PROGRAM_FIXED?((P)->lfuns[(N)]):low_find_lfun((P), (N)) ) -#define free_program(p) do{ struct program *_=(p); debug_malloc_touch(_); if(!--_->refs) really_free_program(_); }while(0) +#define free_program(p) do{ struct program *_=(p); debug_malloc_touch(_); if(!sub_ref(_)) really_free_program(_); }while(0) extern struct object *error_handler; diff --git a/src/stralloc.h b/src/stralloc.h index 7dadef8a47..8459231b1d 100644 --- a/src/stralloc.h +++ b/src/stralloc.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: stralloc.h,v 1.59 2001/02/02 20:36:23 mast Exp $ + * $Id: stralloc.h,v 1.60 2001/03/23 03:14:41 hubbe Exp $ */ #ifndef STRALLOC_H #define STRALLOC_H @@ -39,7 +39,7 @@ struct string_builder PMOD_EXPORT struct pike_string *debug_findstring(const struct pike_string *foo); #endif -#define free_string(s) do{ struct pike_string *_=(s); debug_malloc_touch(_); if(--_->refs<=0) really_free_string(_); }while(0) +#define free_string(s) do{ struct pike_string *_=(s); debug_malloc_touch(_); if(sub_ref(_)<=0) really_free_string(_); }while(0) #define my_hash_string(X) ((size_t)(X)) #define my_order_strcmp(X,Y) ((char *)(X)-(char *)(Y)) diff --git a/src/svalue.h b/src/svalue.h index a33bfb28c8..07fe19a00a 100644 --- a/src/svalue.h +++ b/src/svalue.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: svalue.h,v 1.81 2001/03/19 00:41:20 grubba Exp $ + * $Id: svalue.h,v 1.82 2001/03/23 03:14:41 hubbe Exp $ */ #ifndef SVALUE_H #define SVALUE_H @@ -53,6 +53,11 @@ struct processing void *pointer_a, *pointer_b; }; +struct ref_dummy +{ + INT32 refs; +}; + union anything { struct callable *efun; @@ -64,6 +69,7 @@ union anything struct pike_string *string; struct pike_type *type; INT32 *refs; + struct ref_dummy *dummy; INT_TYPE integer; FLOAT_TYPE float_number; struct svalue *lval; /* only used on stack */ @@ -264,6 +270,16 @@ do{ \ } \ }while(0) + +#ifdef PIKE_RUN_UNLOCKED +#define add_ref(X) pike_atomic_add_ref(&(X)->refs) +#define sub_ref(X) pike_atomic_sub_ref(&(X)->refs) +#else +#define add_ref(X) (X)->refs++ +#define sub_ref(X) (X)->refs-- +#endif + + #ifdef PIKE_DEBUG PMOD_EXPORT extern void describe(void *); /* defined in gc.c */ #define check_type(T) if(T > MAX_TYPE && T!=T_LVALUE && T!=T_SHORT_LVALUE && T!=T_VOID && T!=T_DELETED && T!=T_ARRAY_LVALUE) fatal("Type error: %d\n",T) @@ -303,13 +319,23 @@ static inline union anything *dmalloc_check_union(union anything *u,int type, ch return u; } +#undef add_ref +#undef sub_ref + +#ifdef PIKE_RUN_UNLOCKED +#define add_ref(X) pike_atomic_add_ref((INT32 *)debug_malloc_pass( &((X)->refs))) +#define sub_ref(X) pike_atomic_sub_ref((INT32 *)debug_malloc_pass( &((X)->refs))) +#else #define add_ref(X) ((INT32 *)debug_malloc_pass( &((X)->refs)))[0]++ +#define sub_ref(X) ((INT32 *)debug_malloc_pass( &((X)->refs)))[0]-- +#endif + + #else #define dmalloc_check_svalue(S,L) (S) #define dmalloc_check_union(U,T,L) (U) -#define add_ref(X) (X)->refs++ -#endif +#endif #else @@ -319,15 +345,15 @@ static inline union anything *dmalloc_check_union(union anything *u,int type, ch #define check_refs2(S,T) #define dmalloc_check_svalue(S,L) (S) #define dmalloc_check_union(U,T,L) (U) -#define add_ref(X) (X)->refs++ + #endif #define swap_svalues(X,Y) do { struct svalue *_a=(X),*_b=(Y),_tmp; _tmp=*_a; *_a=*_b; *_b=_tmp; }while(0) #define free_svalue(X) do { struct svalue *_s=(X); check_type(_s->type); check_refs(_s); if(_s->type<=MAX_REF_TYPE) { debug_malloc_touch(_s->u.refs); if(--*(_s->u.refs) <=0) { really_free_svalue(_s); } DO_IF_DMALLOC(_s->u.refs=(void *)-1;) }}while(0) #define free_short_svalue(X,T) do { union anything *_s=(X); TYPE_T _t=(T); check_type(_t); check_refs2(_s,_t); if(_t<=MAX_REF_TYPE && _s->refs) if(--*(_s->refs) <= 0) { really_free_short_svalue(_s,_t); } DO_IF_DMALLOC(_s->refs=(void *)-1;) }while(0) -#define add_ref_svalue(X) do { struct svalue *_tmp=(X); check_type(_tmp->type); check_refs(_tmp); if(_tmp->type <= MAX_REF_TYPE) { debug_malloc_touch(_tmp->u.refs); _tmp->u.refs[0]++; } }while(0) -#define assign_svalue_no_free(X,Y) do { struct svalue _tmp, *_to=(X), *_from=(Y); check_type(_from->type); check_refs(_from); *_to=_tmp=*_from; if(_tmp.type <= MAX_REF_TYPE) { debug_malloc_touch(_tmp.u.refs); _tmp.u.refs[0]++; } }while(0) +#define add_ref_svalue(X) do { struct svalue *_tmp=(X); check_type(_tmp->type); check_refs(_tmp); if(_tmp->type <= MAX_REF_TYPE) { add_ref(_tmp->u.dummy); } }while(0) +#define assign_svalue_no_free(X,Y) do { struct svalue _tmp, *_to=(X), *_from=(Y); check_type(_from->type); check_refs(_from); *_to=_tmp=*_from; if(_tmp.type <= MAX_REF_TYPE) { add_ref(_tmp.u.dummy); } }while(0) #define assign_svalue(X,Y) do { struct svalue *_to2=(X), *_from2=(Y); if (_to2 != _from2) { free_svalue(_to2); assign_svalue_no_free(_to2, _from2); } }while(0) extern struct svalue dest_ob_zero; -- GitLab