1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-04-28 01:00:52 -07:00

Merging branch/2012-07-26/linux-catchup.

Copied from Perforce
 Change: 178816
 ServerID: perforce.ravenbrook.com
This commit is contained in:
Richard Brooksby 2012-08-02 13:05:51 +01:00
commit 6b9cf31fa2
24 changed files with 125 additions and 263 deletions

View file

@ -168,7 +168,7 @@ Res ABQPeek(ABQ abq, CBSBlock *blockReturn)
/* ABQDelete -- delete a block from the ABQ */
Res ABQDelete(ABQ abq, CBSBlock block)
{
Index index, next, elements, in;
Index index, next, in;
CBSBlock *queue;
AVERT(ABQ, abq);
@ -178,7 +178,6 @@ Res ABQDelete(ABQ abq, CBSBlock block)
index = abq->out;
in = abq->in;
elements = abq->elements;
queue = abq->queue;
while (index != in) {

View file

@ -206,9 +206,7 @@ static void test(mps_ap_t leafap, mps_ap_t exactap, mps_ap_t weakap,
for(j = 0; j < ITERATIONS; ++j) {
for(i = 0; i < TABLE_SLOTS; ++i) {
mps_word_t *string;
string = alloc_string("spong", leafap);
(void)alloc_string("spong", leafap);
}
}

View file

@ -211,9 +211,7 @@ static void test(mps_ap_t leafap, mps_ap_t exactap, mps_ap_t weakap,
for(j = 0; j < ITERATIONS; ++j) {
for(i = 0; i < TABLE_SLOTS; ++i) {
mps_word_t *string;
string = alloc_string("spong", leafap);
(void)alloc_string("spong", leafap);
}
}

View file

@ -176,13 +176,11 @@ static void *test(void *arg, size_t s)
die(mps_arena_collect(arena), "collect");
printf(" Done.\n");
while (mps_message_poll(arena)) {
mps_word_t obj;
mps_addr_t objaddr;
cdie(mps_message_get(&message, arena,
mps_message_type_finalization()),
"get");
mps_message_finalization_ref(&objaddr, arena, message);
obj = (mps_word_t)objaddr;
mps_message_discard(arena, message);
++ final_this_time;
}
@ -216,13 +214,11 @@ static void *test(void *arg, size_t s)
die(mps_arena_collect(arena), "collect");
printf(" Done.\n");
while (mps_message_poll(arena)) {
mps_word_t obj;
mps_addr_t objaddr;
cdie(mps_message_get(&message, arena,
mps_message_type_finalization()),
"get");
mps_message_finalization_ref(&objaddr, arena, message);
obj = (mps_word_t)objaddr;
mps_message_discard(arena, message);
++ final_this_time;
}

View file

@ -129,24 +129,30 @@ int dylan_wrapper_check(mps_word_t *w)
/* The first field is traceable, the second field can be traced, */
/* but doesn't need to be. */
assert((ww[WP] == 1) || (ww[WP] == 3));
unused(ww);
/* Unpack the wrapper. */
class = w[WC]; /* class */
unused(class);
fh = w[WF]; /* fixed part header word */
fl = fh >> 2; /* fixed part length */
ff = fh & 3; /* fixed part format code */
vh = w[WV]; /* variable part header */
version = (vh >> (MPS_WORD_WIDTH - 8)) & 0xff;
assert(version == 2); /* Code in this file only works for version 2 */
unused(version);
reserved = (vh >> 8) & 0xff;
assert(reserved == 0);
unused(reserved);
vb = (vh >> 16) & 0xff;
unused(vb);
es = (vh & 0xff) >> 3;/* element size */
vf = vh & 7; /* variable part format code */
vt = w[WS]; /* vector total word (Dylan-tagged) */
t = vt >> 2; /* vector total length */
unused(t);
/* The second word is the class of the wrapped object. */
/* It would be good to check which pool this is in. */
@ -160,23 +166,26 @@ int dylan_wrapper_check(mps_word_t *w)
/* Fixed part format 3 is reserved. */
assert(ff != 3);
unused(ff);
/* Zero length fixed part is only legal in format 0. */
/* Current Dylan run-time does not honour this so I remove it for now */
/* We probably want this check as then we can scan without having to */
/* check for 0 fixed length fields as a special case */
/* assert(ff == 0 || fl != 0); */
unused(fl);
/* The fourth word contains the variable part format and element */
/* size. This assumes that DylanWorks is only going to use byte */
/* vectors in the non-word case. */
/* Variable part format 6 is reserved. */
assert(vf != 6);
unused(vf);
/* There should be no shift in word vector formats. */
assert((vf & 6) == 4 || es == 0);
unused(es);
/* The fifth word is the number of patterns in the pattern */
/* vector. This can be calculated from the fixed part length. */
/* The word is also tagged like a DylanWorks integer. */
@ -247,9 +256,11 @@ extern mps_addr_t dylan_weak_dependent(mps_addr_t parent)
ff = fword & 3;
/* traceable fixed part */
assert(ff == 1);
unused(ff);
fl = fword & ~(mps_word_t)3;
/* at least one fixed field */
assert(fl >= 1);
unused(fl);
return (mps_addr_t) object[1];
}
@ -555,7 +566,8 @@ extern mps_res_t dylan_scan1_weak(mps_ss_t mps_ss, mps_addr_t *object_io)
h = (mps_word_t)p[0];
/* object should not be forwarded (as there is no forwarding method) */
assert((h & 3) == 0);
unused(h);
res = mps_fix(mps_ss, p);
if ( res != MPS_RES_OK ) return res;
@ -576,7 +588,8 @@ extern mps_res_t dylan_scan1_weak(mps_ss_t mps_ss, mps_addr_t *object_io)
/* weak vectors should have traceable fixed format */
assert(ff == 1);
unused(ff);
assoc = (mps_addr_t *)p[0];
vword = w[WV];
@ -585,7 +598,8 @@ extern mps_res_t dylan_scan1_weak(mps_ss_t mps_ss, mps_addr_t *object_io)
/* weak vectors should be non-stretchy traceable */
assert(vf == 2);
unused(vf);
/* q is end of the object. There are fl fixed fields, vl variable */
/* fields and another slot that contains the vector length */
q = p + fl + vl + 1;

View file

@ -8,7 +8,9 @@ PFM = lii4gc
THREADSRC = lockli.c thlii4.c pthrdext.c
THREADLIB = -lpthread
PFMDEFS = -D_REENTRANT
# _XOPEN_SOURCE is to get the modern POSIX signal handling
# _GNU_SOURCE is to get register numbers in prmci3li.c
PFMDEFS = -D_REENTRANT -D_XOPEN_SOURCE=500 -D_GNU_SOURCE
MPMPF = ${THREADSRC} vmix.c \
protix.c protlii3.c proti3.c prmci3li.c ssixi3.c span.c
@ -23,7 +25,7 @@ CC = cc
# Suppress some warnings (SuSE).
# .void: -Wpointer-arith cannot be used because the string.h header does
# arithmetic on void*.
CFLAGSCOMPILER := $(subst -Wpointer-arith,,$(CFLAGSCOMPILER))
CFLAGSCOMPILER := -pthread $(subst -Wpointer-arith,,$(CFLAGSCOMPILER))
include comm.gmk

View file

@ -300,7 +300,8 @@ Res ChainCondemnAuto(double *mortalityReturn, Chain chain, Trace trace)
" (of $U)", (WriteFU)chain->genCount,
" of this chain $P.", (WriteFP)chain,
NULL ));
UNUSED(topCondemnedGenSerial); /* only used for DIAG */
/* Condemn everything in these zones. */
if (condemnedSet != ZoneSetEMPTY) {
res = TraceCondemnZones(trace, condemnedSet);

View file

@ -481,7 +481,7 @@ static void *test(void *arg, size_t s)
if(collections != c) {
collections = c;
printf("\nCollection %"PRIuLONGEST", %lu objects.\n", (ulongest_t)c, (unsigned long)i);
printf("\nCollection %"PRIuLONGEST", %lu objects.\n", (ulongest_t)c, i);
for(r = 0; r < exactRootsCOUNT; ++r) {
cdie(exactRoots[r] == objNULL || dylan_check(exactRoots[r]),
"all roots check");

View file

@ -1583,7 +1583,6 @@ static Res amcScanNailed(Bool *totalReturn, ScanState ss, Pool pool,
static Res AMCScan(Bool *totalReturn, ScanState ss, Pool pool, Seg seg)
{
Addr base, limit;
Arena arena;
Format format;
AMC amc;
Res res;
@ -1597,7 +1596,6 @@ static Res AMCScan(Bool *totalReturn, ScanState ss, Pool pool, Seg seg)
format = pool->format;
arena = pool->arena;
if(amcSegHasNailboard(seg)) {
return amcScanNailed(totalReturn, ss, pool, seg, amc);

View file

@ -234,7 +234,6 @@ static Bool loSegFindFree(Addr *bReturn, Addr *lReturn,
Index baseIndex, limitIndex;
LO lo;
Seg seg;
Arena arena;
Count agrains;
Count bits;
Addr segBase;
@ -246,7 +245,6 @@ static Bool loSegFindFree(Addr *bReturn, Addr *lReturn,
lo = loseg->lo;
seg = LOSegSeg(loseg);
AVER(SizeIsAligned(size, LOPool(lo)->alignment));
arena = PoolArena(LOPool(lo));
/* agrains is the number of grains corresponding to the size */
/* of the allocation request */
@ -547,7 +545,6 @@ static Res LOBufferFill(Addr *baseReturn, Addr *limitReturn,
Ring node, nextNode;
LO lo;
LOSeg loseg;
Arena arena;
Addr base, limit;
AVER(baseReturn != NULL);
@ -562,8 +559,6 @@ static Res LOBufferFill(Addr *baseReturn, Addr *limitReturn,
AVER(SizeIsAligned(size, PoolAlignment(pool)));
AVER(BoolCheck(withReservoirPermit));
arena = PoolArena(pool);
/* Try to find a segment with enough space already. */
RING_FOR(node, &pool->segRing, nextNode) {
Seg seg = SegOfPoolRing(node);
@ -619,7 +614,6 @@ static void LOBufferEmpty(Pool pool, Buffer buffer, Addr init, Addr limit)
Seg seg;
LOSeg loseg;
Index baseIndex, initIndex, limitIndex;
Arena arena;
AVERT(Pool, pool);
lo = PARENT(LOStruct, poolStruct, pool);
@ -634,7 +628,6 @@ static void LOBufferEmpty(Pool pool, Buffer buffer, Addr init, Addr limit)
AVERT(LOSeg, loseg);
AVER(loseg->lo == lo);
arena = PoolArena(pool);
base = BufferBase(buffer);
segBase = SegBase(seg);

View file

@ -477,9 +477,6 @@ static MessageClassStruct MRGMessageClassStruct = {
*/
static void MRGSegPairDestroy(MRGRefSeg refseg, MRG mrg)
{
Pool pool;
pool = MRG2Pool(mrg);
RingRemove(&refseg->mrgRing);
RingFinish(&refseg->mrgRing);
refseg->sig = SigInvalid;

View file

@ -824,7 +824,6 @@ size_t mps_mv_size(mps_pool_t mps_pool)
Pool pool;
MV mv;
MVSpan span;
Arena arena;
Size f = 0;
Ring spans, node = NULL, nextNode; /* gcc whinge stop */
@ -833,7 +832,6 @@ size_t mps_mv_size(mps_pool_t mps_pool)
AVERT(Pool, pool);
mv = Pool2MV(pool);
AVERT(MV, mv);
arena = PoolArena(pool);
spans = &mv->spans;
RING_FOR(node, spans, nextNode) {

View file

@ -643,8 +643,8 @@ static void SNCWalk(Pool pool, Seg seg, FormattedObjectsStepMethod f,
limit = SegLimit(seg);
while(object < limit) {
(*f)(object, pool->format, pool, p, s);
nextObject = (*pool->format->skip)(object);
(*f)(object, format, pool, p, s);
nextObject = (*format->skip)(object);
AVER(nextObject > object);
object = nextObject;
}

View file

@ -21,8 +21,7 @@
* storing into an MRef pointer.
*/
/* prmcli.h will include mpm.h after defining open sesame magic */
#include "prmcli.h"
#include "prmcix.h"
#include "prmci3.h"
SRCID(prmci3li, "$Id$");
@ -30,26 +29,28 @@ SRCID(prmci3li, "$Id$");
/* Prmci3AddressHoldingReg -- return an address of a register in a context */
MRef Prmci3AddressHoldingReg(MutatorFaultContext context, unsigned int regnum)
MRef Prmci3AddressHoldingReg(MutatorFaultContext mfc, unsigned int regnum)
{
struct sigcontext *scp;
gregset_t *gregs;
AVER(regnum <= 7);
AVER(regnum >= 0);
scp = context->scp;
gregs = &mfc->ucontext->uc_mcontext.gregs;
/* .source.i486 */
/* .assume.regref */
/* The REG_EAX etc. symbols are only present if _GNU_SOURCE is defined.
Currently this is in lii4gc.gmk in PFMDEFS. */
switch (regnum) {
case 0: return (MRef)&scp->eax;
case 1: return (MRef)&scp->ecx;
case 2: return (MRef)&scp->edx;
case 3: return (MRef)&scp->ebx;
case 4: return (MRef)&scp->esp;
case 5: return (MRef)&scp->ebp;
case 6: return (MRef)&scp->esi;
case 7: return (MRef)&scp->edi;
case 0: return (MRef)&gregs[REG_EAX];
case 1: return (MRef)&gregs[REG_ECX];
case 2: return (MRef)&gregs[REG_EDX];
case 3: return (MRef)&gregs[REG_EBX];
case 4: return (MRef)&gregs[REG_ESP];
case 5: return (MRef)&gregs[REG_EBP];
case 6: return (MRef)&gregs[REG_ESI];
case 7: return (MRef)&gregs[REG_EDI];
}
NOTREACHED;
return (MRef)NULL; /* Avoids compiler warning. */
@ -60,29 +61,19 @@ MRef Prmci3AddressHoldingReg(MutatorFaultContext context, unsigned int regnum)
void Prmci3DecodeFaultContext(MRef *faultmemReturn,
Byte **insvecReturn,
MutatorFaultContext context)
MutatorFaultContext mfc)
{
struct sigcontext *scp;
scp = context->scp;
/* Assert that this is a page fault exception. The computation of */
/* faultmem depends on this. See .source.i486 (9.9.14). */
AVER(scp->trapno == 14);
/* cr2 contains the address which caused the fault. */
/* See .source.i486 (9.9.14) and */
/* .source.linux.kernel (linux/arch/i386/mm/fault.c). */
*faultmemReturn = (MRef)scp->cr2;
*insvecReturn = (Byte*)scp->eip;
*faultmemReturn = (MRef)mfc->info->si_addr;
*insvecReturn = (Byte*)mfc->ucontext->uc_mcontext.gregs[REG_EIP];
}
/* Prmci3StepOverIns -- modify context to step over instruction */
void Prmci3StepOverIns(MutatorFaultContext context, Size inslen)
void Prmci3StepOverIns(MutatorFaultContext mfc, Size inslen)
{
context->scp->eip += (unsigned long)inslen;
mfc->ucontext->uc_mcontext.gregs[REG_EIP] += (unsigned long)inslen;
}

View file

@ -1,4 +1,4 @@
/* prmcfr.h: PROTECTION MUTATOR CONTEXT (FREEBSD)
/* prmcix.h: PROTECTION MUTATOR CONTEXT (UNIX)
*
* $Id$
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
@ -6,19 +6,20 @@
* .readership: MPS developers.
*/
#ifndef prmcfr_h
#define prmcfr_h
#ifndef prmcix_h
#define prmcix_h
#include "mpm.h"
#include <ucontext.h>
typedef struct MutatorFaultContextStruct { /* Protection fault context data */
siginfo_t *info;
ucontext_t *ucontext;
} MutatorFaultContextStruct;
#endif /* prmcfr_h */
#endif /* prmcix_h */
/* C. COPYRIGHT AND LICENSE

View file

@ -1,68 +0,0 @@
/* prmcli.h: PROTECTION MUTATOR CONTEXT (Linux)
*
* $Id$
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
*
* .readership: MPS developers.
*/
#ifndef prmcli_h
#define prmcli_h
/* open sesame magic */
#define _BSD_SOURCE 1
#define _XOPEN_SOURCE 500
#include "mpm.h"
#include <signal.h>
typedef struct MutatorFaultContextStruct { /* Protection fault context data */
struct sigcontext *scp; /* Linux sigcontext */
} MutatorFaultContextStruct;
#endif /* prmcli_h */
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2002 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Redistributions in any form must be accompanied by information on how
* to obtain complete source code for this software and any accompanying
* software that uses this software. The source code must either be
* included in the distribution or be available for no more than the cost
* of distribution plus a nominal fee, and must be freely redistributable
* under reasonable conditions. For an executable file, complete source
* code means the source code for all modules it contains. It does not
* include source code for modules or files that typically accompany the
* major components of the operating system on which the executable file
* runs.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE, OR NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

View file

@ -11,7 +11,7 @@
* .source.linux.kernel: Linux kernel source files.
*/
#include "prmcli.h"
#include "prmcix.h"
#ifndef MPS_OS_LI
#error "protlii3.c is Linux-specific, but MPS_OS_LI is not set"
@ -27,20 +27,11 @@
#include <stddef.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
SRCID(protlii3, "$Id$");
/* Useful stuff that doesn't appear to be in any header files. */
/* Interrupt number 14 is Page Fault. */
#define TRAPNO_PAGE_FAULT 14
/* Bits in err field of sigcontext for interrupt 14 (page fault) */
#define PAGE_FAULT_ERR_PAGEPROT 0x1
#define PAGE_FAULT_ERR_WRITE 0x2
#define PAGE_FAULT_ERR_USERMODE 0x4
/* The previously-installed signal action, as returned by */
/* sigaction(3). See ProtSetup. */
@ -48,9 +39,6 @@ SRCID(protlii3, "$Id$");
static struct sigaction sigNext;
typedef void (*__real_lii3_sighandler_t)(int, struct sigcontext);
/* sigHandle -- protection signal handler
*
* This is the signal handler installed by ProtSetup to deal with
@ -62,39 +50,44 @@ typedef void (*__real_lii3_sighandler_t)(int, struct sigcontext);
* then sigHandle does its best to pass the signal on to the
* previously installed signal handler (sigNext).
*
* .sigh.args: There is no officially documented way of getting the
* sigcontext, but on x86 Linux at least it is passed BY VALUE as a
* second argument to the signal handler. The prototype doesn't
* include this arg.
* See .source.linux.kernel (linux/arch/i386/kernel/signal.c).
*
* .sigh.context: We only know how to handle interrupt 14, where
* context.err gives the page fault error code and context.cr2 gives
* the fault address. See .source.i486 (9.9.14) and
* .sigh.context: We check si_code for being a memory access
* si_addr gives the fault address. See
* .source.linux.kernel (linux/arch/i386/mm/fault.c).
*
* .sigh.addr: We assume that the OS decodes the address to something
* sensible
*/
/* This is defined here to keep the sources closer to those in protsgix.c
* They can't be merged yet because protsgix doesn't pass the context to
* ArenaAccess */
static void sigHandle(int sig, struct sigcontext context) /* .sigh.args */
#define PROT_SIGNAL SIGSEGV
static void sigHandle(int sig, siginfo_t *info, void *context) /* .sigh.args */
{
AVER(sig == SIGSEGV);
int e;
/* sigset renamed to asigset due to clash with global on Darwin. */
sigset_t asigset, oldset;
struct sigaction sa;
if(context.trapno == TRAPNO_PAGE_FAULT) { /* .sigh.context */
AVER(sig == PROT_SIGNAL);
if(info->si_code == SEGV_ACCERR) { /* .sigh.context */
AccessSet mode;
Addr base, limit;
Addr base;
ucontext_t *ucontext;
MutatorFaultContextStruct mfContext;
mfContext.scp = &context;
ucontext = (ucontext_t *)context;
mfContext.ucontext = ucontext;
mfContext.info = info;
mode = ((context.err & PAGE_FAULT_ERR_WRITE) != 0) /* .sigh.context */
? (AccessREAD | AccessWRITE)
: AccessREAD;
/* on linux we used to be able to tell whether this was a read or a write */
mode = AccessREAD | AccessWRITE;
/* We assume that the access is for one word at the address. */
base = (Addr)context.cr2; /* .sigh.addr */
limit = AddrAdd(base, (Size)sizeof(Addr));
base = (Addr)info->si_addr; /* .sigh.addr */
/* limit = AddrAdd(base, (Size)sizeof(Addr)); */
/* Offer each protection structure the opportunity to handle the */
/* exception. If it succeeds, then allow the mutator to continue. */
@ -104,23 +97,21 @@ static void sigHandle(int sig, struct sigcontext context) /* .sigh.args */
}
/* The exception was not handled by any known protection structure, */
/* so throw it to the previously installed handler. */
/* so throw it to the previously installed handler. That handler won't */
/* get an accurate context (the MPS would fail if it were the second in */
/* line) but it's the best we can do. */
/* @@@@ This is really weak. */
/* Need to implement rest of the contract of sigaction */
/* We might also want to set SA_RESETHAND in the flags and explicitly */
/* reinstall the handler from withint itself so the SIG_DFL/SIG_IGN */
/* case can work properly by just returning. */
switch ((int)sigNext.sa_handler) {
case (int)SIG_DFL:
case (int)SIG_IGN:
abort();
NOTREACHED;
break;
default:
(*(__real_lii3_sighandler_t)sigNext.sa_handler)(sig, context);
break;
}
e = sigaction(PROT_SIGNAL, &sigNext, &sa);
AVER(e == 0);
sigemptyset(&asigset);
sigaddset(&asigset, PROT_SIGNAL);
e = sigprocmask(SIG_UNBLOCK, &asigset, &oldset);
AVER(e == 0);
kill(getpid(), PROT_SIGNAL);
e = sigprocmask(SIG_SETMASK, &oldset, NULL);
AVER(e == 0);
e = sigaction(PROT_SIGNAL, &sa, NULL);
AVER(e == 0);
}
@ -142,15 +133,14 @@ void ProtSetup(void)
struct sigaction sa;
int result;
sa.sa_handler = (__sighandler_t)sigHandle; /* .sigh.args */
sa.sa_sigaction = sigHandle;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sa.sa_flags = SA_SIGINFO;
result = sigaction(SIGSEGV, &sa, &sigNext);
result = sigaction(PROT_SIGNAL, &sa, &sigNext);
AVER(result == 0);
}
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2002 Ravenbrook Limited <http://www.ravenbrook.com/>.

View file

@ -15,12 +15,6 @@
#include "mpm.h"
#if defined(MPS_OS_LI)
/* open sesame magic */
#define _BSD_SOURCE 1
#define _XOPEN_SOURCE 500
#endif
#include <pthread.h>
#include <sched.h>
#include <signal.h>
@ -79,34 +73,7 @@ static RingStruct suspendedRing; /* PThreadext suspend ring */
* suspend protocol.
*/
#if defined(MPS_OS_LI)
#include "prmcli.h"
static void suspendSignalHandler(int sig, struct sigcontext scp)
{
sigset_t signal_set;
MutatorFaultContextStruct mfContext;
AVER(sig == PTHREADEXT_SIGSUSPEND);
UNUSED(sig);
AVER(suspendingVictim != NULL);
mfContext.scp = &scp;
suspendingVictim->suspendedMFC = &mfContext;
/* Block all signals except PTHREADEXT_SIGRESUME while suspended. */
sigfillset(&signal_set);
sigdelset(&signal_set, PTHREADEXT_SIGRESUME);
sem_post(&pthreadextSem);
sigsuspend(&signal_set);
/* Once here, the resume signal handler has run to completion. */
return;
}
#elif defined(MPS_OS_FR)
#include "prmcfr.h"
#include "prmcix.h"
static void suspendSignalHandler(int sig,
siginfo_t *info,
@ -135,8 +102,6 @@ static void suspendSignalHandler(int sig,
return;
}
#endif
/* resumeSignalHandler -- signal handler called when resuming a thread
*
@ -184,15 +149,8 @@ static void PThreadextModuleInit(void)
status = sigaddset(&pthreadext_sigsuspend.sa_mask, PTHREADEXT_SIGRESUME);
AVER(status == 0);
#if defined(MPS_OS_LI)
pthreadext_sigsuspend.sa_flags = 0;
pthreadext_sigsuspend.sa_handler = (__sighandler_t)suspendSignalHandler;
#elif defined(MPS_OS_FR)
pthreadext_sigsuspend.sa_flags = SA_SIGINFO;
pthreadext_sigsuspend.sa_sigaction = suspendSignalHandler;
#endif
pthreadext_sigresume.sa_flags = 0;
pthreadext_sigresume.sa_handler = resumeSignalHandler;
status = sigemptyset(&pthreadext_sigresume.sa_mask);

View file

@ -215,7 +215,6 @@ static void reservoirShrink(Reservoir reservoir, Size want)
Res ReservoirWithdraw(Addr *baseReturn, Tract *baseTractReturn,
Reservoir reservoir, Size size, Pool pool)
{
Pool respool;
Arena arena;
AVER(baseReturn != NULL);
@ -226,7 +225,6 @@ Res ReservoirWithdraw(Addr *baseReturn, Tract *baseTractReturn,
AVER(SizeIsAligned(size, ArenaAlign(arena)));
AVER(size > 0);
AVERT(Pool, pool);
respool = &reservoir->poolStruct;
/* @@@@ As a short-term measure, we only permit the reservoir to */
/* allocate single-page regions. */

View file

@ -210,7 +210,7 @@ failInit:
static void SegFinish(Seg seg)
{
Arena arena;
Addr addr, base, limit;
Addr addr, limit;
Tract tract;
SegClass class;
@ -231,8 +231,8 @@ static void SegFinish(Seg seg)
/* See <code/shield.c#shield.flush> */
ShieldFlush(PoolArena(SegPool(seg)));
base = SegBase(seg);
limit = SegLimit(seg);
TRACT_TRACT_FOR(tract, addr, arena, seg->firstTract, limit) {
AVER(TractCheck(tract)); /* <design/check/#type.no-sig> */
TractSetWhite(tract, TraceSetEMPTY);

View file

@ -433,14 +433,10 @@ static Bool AMSSegRegionIsFree(Seg seg, Addr base, Addr limit)
*/
static void AMSUnallocateRange(Seg seg, Addr base, Addr limit)
{
Pool pool;
AMS ams;
AMSSeg amsseg;
Index baseIndex, limitIndex;
/* parameters checked by caller */
pool = SegPool(seg);
ams = Pool2AMS(pool);
amsseg = Seg2AMSSeg(seg);
baseIndex = AMS_ADDR_INDEX(seg, base);
@ -475,14 +471,10 @@ static void AMSUnallocateRange(Seg seg, Addr base, Addr limit)
*/
static void AMSAllocateRange(Seg seg, Addr base, Addr limit)
{
Pool pool;
AMS ams;
AMSSeg amsseg;
Index baseIndex, limitIndex;
/* parameters checked by caller */
pool = SegPool(seg);
ams = Pool2AMS(pool);
amsseg = Seg2AMSSeg(seg);
baseIndex = AMS_ADDR_INDEX(seg, base);

View file

@ -22,6 +22,8 @@
*
* .source.callees.saves: Set of callee-saved registers taken from
* CALL_USED_REGISTERS in <gcc-sources>/config/i386/i386.h.
* ebp added to the list because gcc now doesn't always use it as
* a frame pointer so it could contain a root.
*
* ASSUMPTIONS
*
@ -49,20 +51,23 @@ SRCID(ssixi3, "$Id$");
Res StackScan(ScanState ss, Addr *stackBot)
{
Addr calleeSaveRegs[4];
Addr *stackTop;
Res res;
/* .assume.asm.stack */
ASMV("push %ebx"); /* These registers are callee-saved */
ASMV("push %esi"); /* and so may contain roots. They are pushed */
ASMV("push %edi"); /* for scanning. See .source.callees.saves. */
/* Store the callee save registers on the stack so they get scanned
* as they may contain roots.
*/
ASMV("mov %%ebx, %0" : "=m" (calleeSaveRegs[0]));
ASMV("mov %%esi, %0" : "=m" (calleeSaveRegs[1]));
ASMV("mov %%edi, %0" : "=m" (calleeSaveRegs[2]));
ASMV("mov %%ebp, %0" : "=m" (calleeSaveRegs[3]));
ASMV("mov %%esp, %0" : "=r" (stackTop) :); /* stackTop = esp */
AVER(AddrIsAligned((Addr)stackTop, sizeof(Addr))); /* .assume.align */
res = TraceScanArea(ss, stackTop, stackBot);
ASMV("add $12, %esp"); /* pop 3 regs to restore the stack pointer */
return res;
}

View file

@ -36,7 +36,7 @@
* assumed to be recorded in the context at pointer-aligned boundaries.
*/
#include "prmcfr.h"
#include "prmcix.h"
#include "mpm.h"
#if !defined(MPS_OS_FR) || !defined(MPS_ARCH_I4)

View file

@ -1,4 +1,4 @@
/* thlii3.c: Threads Manager for Intel x86 systems with LinuxThreads
/* thlii4.c: Threads Manager for Intel x86 systems with LinuxThreads
*
* $Id$
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
@ -36,7 +36,7 @@
* assumed to be recorded in the context at pointer-aligned boundaries.
*/
#include "prmcli.h"
#include "prmcix.h"
#include "mpm.h"
#if !defined(MPS_OS_LI) || !defined(MPS_ARCH_I4)
@ -243,18 +243,18 @@ Res ThreadScan(ScanState ss, Thread thread, void *stackBot)
if(res != ResOK)
return res;
} else {
struct sigcontext *scp;
MutatorFaultContext mfc;
Addr *stackBase, *stackLimit, stackPtr;
scp = thread->mfc->scp;
if(scp == NULL) {
mcontext_t *mc;
mfc = thread->mfc;
if(mfc == NULL) {
/* .error.suspend */
/* We assume that the thread must have been destroyed. */
/* We ignore the situation by returning immediately. */
return ResOK;
}
stackPtr = (Addr)scp->esp; /* .i3.sp */
stackPtr = (Addr)mfc->ucontext->uc_stack.ss_sp; /* .i3.sp */
/* .stack.align */
stackBase = (Addr *)AddrAlignUp(stackPtr, sizeof(Addr));
stackLimit = (Addr *)stackBot;
@ -273,8 +273,9 @@ Res ThreadScan(ScanState ss, Thread thread, void *stackBot)
* unecessarily scans the rest of the context. The optimisation
* to scan only relevent parts would be machine dependent.
*/
res = TraceScanAreaTagged(ss, (Addr *)scp,
(Addr *)((char *)scp + sizeof(*scp)));
mc = &mfc->ucontext->uc_mcontext;
res = TraceScanAreaTagged(ss, (Addr *)mc,
(Addr *)((char *)mc + sizeof(*mc)));
if(res != ResOK)
return res;
}