added the equality(=) method to Array.
fixed the equality primitive handler to accept the subclasses of Semaphore/SemaphoreGroup
This commit is contained in:
parent
c412097f6f
commit
a54c2e21f2
@ -76,6 +76,29 @@ class(#pointer) Array(Collection)
|
|||||||
{
|
{
|
||||||
0 priorTo: (anArray basicSize) do: [:i | self at: i put: (anArray at: i) ].
|
0 priorTo: (anArray basicSize) do: [:i | self at: i put: (anArray at: i) ].
|
||||||
}
|
}
|
||||||
|
|
||||||
|
method = anArray
|
||||||
|
{
|
||||||
|
| size i |
|
||||||
|
if (self class ~~ anArray class) { ^false }.
|
||||||
|
|
||||||
|
size := self size.
|
||||||
|
if (size ~~ anArray size) { ^false }.
|
||||||
|
|
||||||
|
i := 0.
|
||||||
|
while (i < size)
|
||||||
|
{
|
||||||
|
if ((self at: i) ~= (anArray at: i)) { ^false }.
|
||||||
|
i := i + 1.
|
||||||
|
}.
|
||||||
|
|
||||||
|
^true.
|
||||||
|
}
|
||||||
|
|
||||||
|
method ~= anArray
|
||||||
|
{
|
||||||
|
^(self = anArray) not
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
## -------------------------------------------------------------------------------
|
## -------------------------------------------------------------------------------
|
||||||
|
@ -62,46 +62,11 @@ class Semaphore(Object)
|
|||||||
|
|
||||||
var(#get,#set) _group := nil.
|
var(#get,#set) _group := nil.
|
||||||
|
|
||||||
method(#class) forMutualExclusion
|
|
||||||
{
|
|
||||||
| sem |
|
|
||||||
sem := self new.
|
|
||||||
sem signal.
|
|
||||||
^sem
|
|
||||||
}
|
|
||||||
|
|
||||||
## ==================================================================
|
## ==================================================================
|
||||||
|
|
||||||
method(#primitive) signal.
|
method(#primitive) signal.
|
||||||
method(#primitive) wait.
|
method(#primitive) wait.
|
||||||
|
|
||||||
(*
|
|
||||||
TODO: timed wait...
|
|
||||||
method waitWithTimeout: seconds
|
|
||||||
{
|
|
||||||
| s |
|
|
||||||
s := Semaphore new.
|
|
||||||
Processor signal: s after: seconds.
|
|
||||||
self waitWithTimedSemaphore: s.
|
|
||||||
|
|
||||||
if (self.
|
|
||||||
}
|
|
||||||
|
|
||||||
method waitWithTimeout: seconds and: nanoSeconds
|
|
||||||
{
|
|
||||||
<primitive: #_semaphore_wait>
|
|
||||||
self primitiveFailed
|
|
||||||
}
|
|
||||||
*)
|
|
||||||
|
|
||||||
(* TODO: MIGRATE TO MUTEX...
|
|
||||||
method critical: aBlock
|
|
||||||
{
|
|
||||||
self wait.
|
|
||||||
^aBlock ensure: [ self signal ]
|
|
||||||
}*)
|
|
||||||
|
|
||||||
|
|
||||||
## ==================================================================
|
## ==================================================================
|
||||||
|
|
||||||
method heapIndex
|
method heapIndex
|
||||||
@ -145,8 +110,14 @@ class Mutex(Semaphore)
|
|||||||
^s.
|
^s.
|
||||||
}
|
}
|
||||||
|
|
||||||
method lock { ^self wait }
|
(*
|
||||||
method unlock { ^self signal }
|
TODO: how to prohibit wait and signal???
|
||||||
|
method(#prohibited) wait.
|
||||||
|
method(#prohibited) signal.
|
||||||
|
*)
|
||||||
|
|
||||||
|
method lock { ^super wait }
|
||||||
|
method unlock { ^super signal }
|
||||||
|
|
||||||
method critical: block
|
method critical: block
|
||||||
{
|
{
|
||||||
|
@ -49,6 +49,42 @@ class MyObject(Object)
|
|||||||
^true
|
^true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
method(#class) test_mutex
|
||||||
|
{
|
||||||
|
| mtx sem v p q |
|
||||||
|
|
||||||
|
mtx := Mutex new.
|
||||||
|
sem := Semaphore new.
|
||||||
|
|
||||||
|
p := 0.
|
||||||
|
|
||||||
|
[ mtx lock.
|
||||||
|
v := 0.
|
||||||
|
2000 timesRepeat: [v := v + 1. p := p + 1. ].
|
||||||
|
q := v.
|
||||||
|
mtx unlock.
|
||||||
|
sem signal.
|
||||||
|
] fork.
|
||||||
|
|
||||||
|
[ mtx critical: [
|
||||||
|
v := 0.
|
||||||
|
2000 timesRepeat: [v := v + 1. p := p + 1. ].
|
||||||
|
q := v.
|
||||||
|
].
|
||||||
|
sem signal.
|
||||||
|
] fork.
|
||||||
|
|
||||||
|
mtx lock.
|
||||||
|
v := 0.
|
||||||
|
2000 timesRepeat: [v := v + 1. p := p + 1. ].
|
||||||
|
mtx unlock.
|
||||||
|
|
||||||
|
sem wait.
|
||||||
|
sem wait.
|
||||||
|
|
||||||
|
^%( v, p ) ## v must be 2000, p must be 6000
|
||||||
|
}
|
||||||
|
|
||||||
method(#class) main
|
method(#class) main
|
||||||
{
|
{
|
||||||
| tc limit |
|
| tc limit |
|
||||||
@ -57,7 +93,8 @@ class MyObject(Object)
|
|||||||
## 0 - 4
|
## 0 - 4
|
||||||
[ self proc1 == 100 ],
|
[ self proc1 == 100 ],
|
||||||
[ Processor sleepFor: 2. self proc1 == 200 ],
|
[ Processor sleepFor: 2. self proc1 == 200 ],
|
||||||
[ self test_semaphore_heap == true ]
|
[ self test_semaphore_heap == true ],
|
||||||
|
[ self test_mutex = #(2000 6000) ]
|
||||||
).
|
).
|
||||||
|
|
||||||
limit := tc size.
|
limit := tc size.
|
||||||
|
@ -67,16 +67,19 @@ class MyObject(TestObject)
|
|||||||
[(Apex isKindOf: Class) == true],
|
[(Apex isKindOf: Class) == true],
|
||||||
[(Apex isKindOf: Apex) == true],
|
[(Apex isKindOf: Apex) == true],
|
||||||
[(SmallInteger isKindOf: Integer) == false],
|
[(SmallInteger isKindOf: Integer) == false],
|
||||||
[(10 isKindOf: Integer) == true],
|
[(SmallInteger isKindOf: SmallInteger) == false],
|
||||||
[(10 isKindOf: 20) == false],
|
[(Object isKindOf: SmallInteger) == false],
|
||||||
|
|
||||||
## 10-14
|
## 10-14
|
||||||
|
[(10 isKindOf: Integer) == true],
|
||||||
|
[(10 isKindOf: 20) == false],
|
||||||
[([] isKindOf: BlockContext) == true],
|
[([] isKindOf: BlockContext) == true],
|
||||||
[([] isKindOf: MethodContext) == false],
|
[([] isKindOf: MethodContext) == false],
|
||||||
[([] isKindOf: Context) == true],
|
[([] isKindOf: Context) == true],
|
||||||
|
|
||||||
|
## 15-20
|
||||||
[('string' isKindOf: String) == true],
|
[('string' isKindOf: String) == true],
|
||||||
[(#symbol isKindOf: String) == true],
|
[(#symbol isKindOf: String) == true],
|
||||||
|
|
||||||
[('string' isKindOf: Symbol) == false],
|
[('string' isKindOf: Symbol) == false],
|
||||||
[(#symbol isKindOf: Symbol) == true]
|
[(#symbol isKindOf: Symbol) == true]
|
||||||
).
|
).
|
||||||
|
@ -494,8 +494,8 @@ static MOO_INLINE void chain_into_semaphore (moo_t* moo, moo_oop_process_t proc,
|
|||||||
MOO_ASSERT (moo, (moo_oop_t)proc->sem_wait.next == moo->_nil);
|
MOO_ASSERT (moo, (moo_oop_t)proc->sem_wait.next == moo->_nil);
|
||||||
|
|
||||||
/* a semaphore or a semaphore group must be given for process chaining */
|
/* a semaphore or a semaphore group must be given for process chaining */
|
||||||
MOO_ASSERT (moo, MOO_CLASSOF(moo,sem) == moo->_semaphore ||
|
MOO_ASSERT (moo, moo_iskindof(moo, (moo_oop_t)sem, moo->_semaphore) ||
|
||||||
MOO_CLASSOF(moo,sem) == moo->_semaphore_group);
|
moo_iskindof(moo, (moo_oop_t)sem, moo->_semaphore_group));
|
||||||
|
|
||||||
/* i assume the head part of the semaphore has the same layout as
|
/* i assume the head part of the semaphore has the same layout as
|
||||||
* the semaphore group */
|
* the semaphore group */
|
||||||
@ -513,8 +513,8 @@ static MOO_INLINE void unchain_from_semaphore (moo_t* moo, moo_oop_process_t pro
|
|||||||
|
|
||||||
MOO_ASSERT (moo, (moo_oop_t)proc->sem != moo->_nil);
|
MOO_ASSERT (moo, (moo_oop_t)proc->sem != moo->_nil);
|
||||||
|
|
||||||
MOO_ASSERT (moo, MOO_CLASSOF(moo, proc->sem) == moo->_semaphore ||
|
MOO_ASSERT (moo, moo_iskindof(moo, proc->sem, moo->_semaphore) ||
|
||||||
MOO_CLASSOF(moo, proc->sem) == moo->_semaphore_group);
|
moo_iskindof(moo, proc->sem, moo->_semaphore_group));
|
||||||
|
|
||||||
MOO_ASSERT (moo, MOO_OFFSETOF(moo_semaphore_t,waiting) ==
|
MOO_ASSERT (moo, MOO_OFFSETOF(moo_semaphore_t,waiting) ==
|
||||||
MOO_OFFSETOF(moo_semaphore_group_t,waiting));
|
MOO_OFFSETOF(moo_semaphore_group_t,waiting));
|
||||||
@ -859,7 +859,7 @@ static MOO_INLINE moo_oop_t await_semaphore_group (moo_t* moo, moo_oop_semaphore
|
|||||||
moo_oop_semaphore_t sem;
|
moo_oop_semaphore_t sem;
|
||||||
moo_ooi_t numsems, sempos, i, count;
|
moo_ooi_t numsems, sempos, i, count;
|
||||||
|
|
||||||
MOO_ASSERT (moo, MOO_CLASSOF(moo,semgrp) == moo->_semaphore_group);
|
MOO_ASSERT (moo, moo_iskindof(moo, (moo_oop_t)semgrp, moo->_semaphore_group));
|
||||||
|
|
||||||
/* check if there is a signaled semaphore in the group */
|
/* check if there is a signaled semaphore in the group */
|
||||||
numsems = MOO_OOP_TO_SMOOI(semgrp->size);
|
numsems = MOO_OOP_TO_SMOOI(semgrp->size);
|
||||||
@ -1673,15 +1673,10 @@ static moo_pfrc_t pf_not_identical (moo_t* moo, moo_ooi_t nargs)
|
|||||||
return MOO_PF_SUCCESS;
|
return MOO_PF_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static moo_pfrc_t _equal_objects (moo_t* moo, moo_ooi_t nargs)
|
static int _equal_objects (moo_t* moo, moo_oop_t rcv, moo_oop_t arg)
|
||||||
{
|
{
|
||||||
moo_oop_t rcv, arg;
|
|
||||||
int rtag;
|
int rtag;
|
||||||
|
|
||||||
MOO_ASSERT (moo, nargs == 1);
|
|
||||||
|
|
||||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
|
||||||
arg = MOO_STACK_GETARG(moo, nargs, 0);
|
|
||||||
if (rcv == arg) return 1; /* identical. so equal */
|
if (rcv == arg) return 1; /* identical. so equal */
|
||||||
|
|
||||||
rtag = MOO_OOP_GET_TAG(rcv);
|
rtag = MOO_OOP_GET_TAG(rcv);
|
||||||
@ -1721,18 +1716,33 @@ static moo_pfrc_t _equal_objects (moo_t* moo, moo_ooi_t nargs)
|
|||||||
case MOO_OBJ_TYPE_CHAR:
|
case MOO_OBJ_TYPE_CHAR:
|
||||||
case MOO_OBJ_TYPE_HALFWORD:
|
case MOO_OBJ_TYPE_HALFWORD:
|
||||||
case MOO_OBJ_TYPE_WORD:
|
case MOO_OBJ_TYPE_WORD:
|
||||||
return (MOO_MEMCMP (((moo_oop_byte_t)rcv)->slot, ((moo_oop_byte_t)arg)->slot, MOO_BYTESOF(moo,rcv)) == 0)? 1: 0;
|
return (MOO_MEMCMP (MOO_OBJ_GET_BYTE_SLOT(rcv), MOO_OBJ_GET_BYTE_SLOT(arg), MOO_BYTESOF(moo,rcv)) == 0)? 1: 0;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
{
|
||||||
if (rcv == moo->_nil) return arg == moo->_nil? 1: 0;
|
if (rcv == moo->_nil) return arg == moo->_nil? 1: 0;
|
||||||
if (rcv == moo->_true) return arg == moo->_true? 1: 0;
|
if (rcv == moo->_true) return arg == moo->_true? 1: 0;
|
||||||
if (rcv == moo->_false) return arg == moo->_false? 1: 0;
|
if (rcv == moo->_false) return arg == moo->_false? 1: 0;
|
||||||
|
|
||||||
/* MOO_OBJ_TYPE_OOP, ... */
|
|
||||||
MOO_DEBUG1 (moo, "<_equal_objects> Cannot compare objects of type %d\n", (int)MOO_OBJ_GET_FLAGS_TYPE(rcv));
|
|
||||||
|
|
||||||
|
/* MOO_OBJ_TYPE_OOP, ... */
|
||||||
|
MOO_ASSERT (moo, MOO_OBJ_GET_FLAGS_TYPE(rcv) == MOO_OBJ_TYPE_OOP);
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
MOO_DEBUG1 (moo, "<_equal_objects> Cannot compare objects of type %d\n", (int)MOO_OBJ_GET_FLAGS_TYPE(rcv));
|
||||||
moo_seterrnum (moo, MOO_ENOIMPL); /* TODO: better error code */
|
moo_seterrnum (moo, MOO_ENOIMPL); /* TODO: better error code */
|
||||||
return -1;
|
return -1;
|
||||||
|
#else
|
||||||
|
for (i = 0; i < MOO_OBJ_GET_SIZE(rcv); i++)
|
||||||
|
{
|
||||||
|
/* TODO: remove recursion */
|
||||||
|
|
||||||
|
/* NOTE: even if the object implements the equality method,
|
||||||
|
* this primitive method doesn't honor it. */
|
||||||
|
if (!_equal_objects(moo, ((moo_oop_oop_t)rcv)->slot[i], ((moo_oop_oop_t)arg)->slot[i])) return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1740,9 +1750,13 @@ static moo_pfrc_t _equal_objects (moo_t* moo, moo_ooi_t nargs)
|
|||||||
|
|
||||||
static moo_pfrc_t pf_equal (moo_t* moo, moo_ooi_t nargs)
|
static moo_pfrc_t pf_equal (moo_t* moo, moo_ooi_t nargs)
|
||||||
{
|
{
|
||||||
|
moo_oop_t rcv, arg;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
n = _equal_objects (moo, nargs);
|
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||||
|
arg = MOO_STACK_GETARG(moo, nargs, 0);
|
||||||
|
|
||||||
|
n = _equal_objects (moo, rcv, arg);
|
||||||
if (n <= -1) return MOO_PF_FAILURE;
|
if (n <= -1) return MOO_PF_FAILURE;
|
||||||
|
|
||||||
MOO_STACK_SETRET (moo, nargs, (n? moo->_true: moo->_false));
|
MOO_STACK_SETRET (moo, nargs, (n? moo->_true: moo->_false));
|
||||||
@ -1751,9 +1765,13 @@ static moo_pfrc_t pf_equal (moo_t* moo, moo_ooi_t nargs)
|
|||||||
|
|
||||||
static moo_pfrc_t pf_not_equal (moo_t* moo, moo_ooi_t nargs)
|
static moo_pfrc_t pf_not_equal (moo_t* moo, moo_ooi_t nargs)
|
||||||
{
|
{
|
||||||
|
moo_oop_t rcv, arg;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
n = _equal_objects (moo, nargs);
|
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||||
|
arg = MOO_STACK_GETARG(moo, nargs, 0);
|
||||||
|
|
||||||
|
n = _equal_objects (moo, rcv, arg);
|
||||||
if (n <= -1) return MOO_PF_FAILURE;
|
if (n <= -1) return MOO_PF_FAILURE;
|
||||||
|
|
||||||
MOO_STACK_SETRET (moo, nargs, (n? moo->_false: moo->_true));
|
MOO_STACK_SETRET (moo, nargs, (n? moo->_false: moo->_true));
|
||||||
@ -2588,7 +2606,7 @@ static moo_pfrc_t pf_processor_add_gcfin_semaphore (moo_t* moo, moo_ooi_t nargs)
|
|||||||
|
|
||||||
MOO_ASSERT (moo, nargs == 1);
|
MOO_ASSERT (moo, nargs == 1);
|
||||||
sem = (moo_oop_semaphore_t)MOO_STACK_GETARG(moo, nargs, 0);
|
sem = (moo_oop_semaphore_t)MOO_STACK_GETARG(moo, nargs, 0);
|
||||||
MOO_PF_CHECK_ARGS (moo, nargs, MOO_CLASSOF(moo,sem) == moo->_semaphore);
|
MOO_PF_CHECK_ARGS (moo, nargs, moo_iskindof(moo, (moo_oop_t)sem, moo->_semaphore));
|
||||||
|
|
||||||
/* TODO: no overwriting.. */
|
/* TODO: no overwriting.. */
|
||||||
moo->sem_gcfin = sem;
|
moo->sem_gcfin = sem;
|
||||||
|
@ -359,7 +359,7 @@ struct moo_iotok_t
|
|||||||
MOO_IOTOK_RPAREN,
|
MOO_IOTOK_RPAREN,
|
||||||
MOO_IOTOK_HASHPAREN, /* #( - array literal */
|
MOO_IOTOK_HASHPAREN, /* #( - array literal */
|
||||||
MOO_IOTOK_HASHBRACK, /* #[ - byte array literal */
|
MOO_IOTOK_HASHBRACK, /* #[ - byte array literal */
|
||||||
MOO_IOTOK_PERCPAREN, /* %{ - array expression */
|
MOO_IOTOK_PERCPAREN, /* %( - array expression */
|
||||||
MOO_IOTOK_PERCBRACE, /* %{ - dictionary expression */
|
MOO_IOTOK_PERCBRACE, /* %{ - dictionary expression */
|
||||||
MOO_IOTOK_PERIOD,
|
MOO_IOTOK_PERIOD,
|
||||||
MOO_IOTOK_COMMA,
|
MOO_IOTOK_COMMA,
|
||||||
|
Loading…
Reference in New Issue
Block a user