shmget: make small free numbers reusable.
Change-Id: Ic6670214fa31a309e96794361e3ec2dcc6375f4a Refs: #1531
This commit is contained in:
committed by
Masamichi Takagi
parent
b3ddd60277
commit
e6e66e0392
@@ -679,4 +679,5 @@ extern int (*linux_clock_gettime)(clockid_t clk_id, struct timespec *tp);
|
|||||||
extern void terminate_host(int pid, struct thread *thread);
|
extern void terminate_host(int pid, struct thread *thread);
|
||||||
struct sig_pending *getsigpending(struct thread *thread, int delflag);
|
struct sig_pending *getsigpending(struct thread *thread, int delflag);
|
||||||
int interrupt_from_user(void *regs0);
|
int interrupt_from_user(void *regs0);
|
||||||
|
extern unsigned long shmid_index[];
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -225,8 +225,6 @@ int shmobj_create_indexed(struct shmid_ds *ds, struct shmobj **objp)
|
|||||||
static void shmobj_destroy(struct shmobj *obj)
|
static void shmobj_destroy(struct shmobj *obj)
|
||||||
{
|
{
|
||||||
extern struct shm_info the_shm_info;
|
extern struct shm_info the_shm_info;
|
||||||
extern struct list_head kds_free_list;
|
|
||||||
extern int the_maxi;
|
|
||||||
struct shmlock_user *user;
|
struct shmlock_user *user;
|
||||||
size_t size;
|
size_t size;
|
||||||
int npages;
|
int npages;
|
||||||
@@ -306,27 +304,13 @@ static void shmobj_destroy(struct shmobj *obj)
|
|||||||
kfree(obj);
|
kfree(obj);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
int i = obj->index / 64;
|
||||||
|
unsigned long x = 1UL << (obj->index % 64);
|
||||||
|
|
||||||
list_del(&obj->chain);
|
list_del(&obj->chain);
|
||||||
--the_shm_info.used_ids;
|
--the_shm_info.used_ids;
|
||||||
|
shmid_index[i] &= ~x;
|
||||||
list_add(&obj->chain, &kds_free_list);
|
kfree(obj);
|
||||||
/* For index reuse, release in descending order of index. */
|
|
||||||
for (;;) {
|
|
||||||
struct shmobj *p;
|
|
||||||
|
|
||||||
list_for_each_entry(p, &kds_free_list, chain) {
|
|
||||||
if (p->index == the_maxi) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (&p->chain == &kds_free_list) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
list_del(&p->chain);
|
|
||||||
kfree(p);
|
|
||||||
--the_maxi;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6161,9 +6161,40 @@ struct kshmid_ds {
|
|||||||
struct list_head chain;
|
struct list_head chain;
|
||||||
};
|
};
|
||||||
|
|
||||||
int the_maxi = -1;
|
unsigned long shmid_index[512];
|
||||||
|
|
||||||
|
static int get_shmid_max_index(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int index = -1;
|
||||||
|
|
||||||
|
for (i = 511; i >= 0; i--) {
|
||||||
|
if (shmid_index[i]) {
|
||||||
|
index = i * 64 + 63 - __builtin_clzl(shmid_index[i]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_shmid_index(void)
|
||||||
|
{
|
||||||
|
int index = get_shmid_max_index();
|
||||||
|
int i;
|
||||||
|
unsigned long x;
|
||||||
|
|
||||||
|
for (index = 0;; index++) {
|
||||||
|
i = index / 64;
|
||||||
|
x = 1UL << (index % 64);
|
||||||
|
if (!(shmid_index[i] & x)) {
|
||||||
|
shmid_index[i] |= x;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
LIST_HEAD(kds_list);
|
LIST_HEAD(kds_list);
|
||||||
LIST_HEAD(kds_free_list);
|
|
||||||
struct shminfo the_shminfo = {
|
struct shminfo the_shminfo = {
|
||||||
.shmmax = 64L * 1024 * 1024 * 1024,
|
.shmmax = 64L * 1024 * 1024 * 1024,
|
||||||
.shmmin = 1,
|
.shmmin = 1,
|
||||||
@@ -6384,7 +6415,7 @@ int do_shmget(const key_t key, const size_t size, const int shmflg)
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
obj->index = ++the_maxi;
|
obj->index = get_shmid_index();
|
||||||
|
|
||||||
list_add(&obj->chain, &kds_list);
|
list_add(&obj->chain, &kds_list);
|
||||||
++the_shm_info.used_ids;
|
++the_shm_info.used_ids;
|
||||||
@@ -6670,7 +6701,7 @@ SYSCALL_DECLARE(shmctl)
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
maxi = the_maxi;
|
maxi = get_shmid_max_index();
|
||||||
if (maxi < 0) {
|
if (maxi < 0) {
|
||||||
maxi = 0;
|
maxi = 0;
|
||||||
}
|
}
|
||||||
@@ -6777,7 +6808,7 @@ SYSCALL_DECLARE(shmctl)
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
maxi = the_maxi;
|
maxi = get_shmid_max_index();
|
||||||
if (maxi < 0) {
|
if (maxi < 0) {
|
||||||
maxi = 0;
|
maxi = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user