diff -urN -X ../dontdiff ../base/linux-2.5.30/ipc/util.c 2.5.30-ipc/ipc/util.c --- ../base/linux-2.5.30/ipc/util.c Thu Aug 1 14:16:21 2002 +++ 2.5.30-ipc/ipc/util.c Fri Aug 2 16:06:19 2002 @@ -74,9 +74,11 @@ printk(KERN_ERR "ipc_init_ids() failed, ipc service disabled.\n"); ids->size = 0; } - ids->ary = SPIN_LOCK_UNLOCKED; - for(i=0;isize;i++) + ids->ary_lock =RW_LOCK_UNLOCKED; + for(i=0;isize;i++) { ids->entries[i].p = NULL; + ids->entries[i].lock = SPIN_LOCK_UNLOCKED; + } } /** @@ -119,14 +121,15 @@ memcpy(new, ids->entries, sizeof(struct ipc_id)*ids->size); for(i=ids->size;iary); + write_lock(&ids->ary_lock); old = ids->entries; ids->entries = new; i = ids->size; ids->size = newsize; - spin_unlock(&ids->ary); + write_unlock(&ids->ary_lock); ipc_free(old, sizeof(struct ipc_id)*i); return ids->size; } @@ -165,7 +168,8 @@ if(ids->seq > ids->seq_max) ids->seq = 0; - spin_lock(&ids->ary); + read_lock(&ids->ary_lock); + spin_lock(&ids->entries[id].lock); ids->entries[id].p = new; return id; } diff -urN -X ../dontdiff ../base/linux-2.5.30/ipc/util.h 2.5.30-ipc/ipc/util.h --- ../base/linux-2.5.30/ipc/util.h Thu Aug 1 14:16:28 2002 +++ 2.5.30-ipc/ipc/util.h Fri Aug 2 16:06:19 2002 @@ -20,11 +20,13 @@ unsigned short seq_max; struct semaphore sem; spinlock_t ary; + rwlock_t ary_lock; struct ipc_id* entries; }; struct ipc_id { struct kern_ipc_perm* p; + spinlock_t lock; }; @@ -72,16 +74,25 @@ if(lid >= ids->size) return NULL; - spin_lock(&ids->ary); + /*spin_lock(&ids->ary);*/ + read_lock(&ids->ary_lock); + spin_lock(&ids->entries[lid].lock); out = ids->entries[lid].p; - if(out==NULL) - spin_unlock(&ids->ary); + if(out==NULL) { + spin_unlock(&ids->entries[lid].lock); + read_unlock(&ids->ary_lock); + } return out; } extern inline void ipc_unlock(struct ipc_ids* ids, int id) { - spin_unlock(&ids->ary); + int lid = id % SEQ_MULTIPLIER; + if(lid >= ids->size) + return; + + spin_unlock(&ids->entries[lid].lock); + read_unlock(&ids->ary_lock); } extern inline int ipc_buildid(struct ipc_ids* ids, int id, int seq)