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);
|
||||
struct sig_pending *getsigpending(struct thread *thread, int delflag);
|
||||
int interrupt_from_user(void *regs0);
|
||||
extern unsigned long shmid_index[];
|
||||
#endif
|
||||
|
||||
@@ -225,8 +225,6 @@ int shmobj_create_indexed(struct shmid_ds *ds, struct shmobj **objp)
|
||||
static void shmobj_destroy(struct shmobj *obj)
|
||||
{
|
||||
extern struct shm_info the_shm_info;
|
||||
extern struct list_head kds_free_list;
|
||||
extern int the_maxi;
|
||||
struct shmlock_user *user;
|
||||
size_t size;
|
||||
int npages;
|
||||
@@ -306,27 +304,13 @@ static void shmobj_destroy(struct shmobj *obj)
|
||||
kfree(obj);
|
||||
}
|
||||
else {
|
||||
int i = obj->index / 64;
|
||||
unsigned long x = 1UL << (obj->index % 64);
|
||||
|
||||
list_del(&obj->chain);
|
||||
--the_shm_info.used_ids;
|
||||
|
||||
list_add(&obj->chain, &kds_free_list);
|
||||
/* 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;
|
||||
}
|
||||
shmid_index[i] &= ~x;
|
||||
kfree(obj);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -6161,9 +6161,40 @@ struct kshmid_ds {
|
||||
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_free_list);
|
||||
struct shminfo the_shminfo = {
|
||||
.shmmax = 64L * 1024 * 1024 * 1024,
|
||||
.shmmin = 1,
|
||||
@@ -6384,7 +6415,7 @@ int do_shmget(const key_t key, const size_t size, const int shmflg)
|
||||
return error;
|
||||
}
|
||||
|
||||
obj->index = ++the_maxi;
|
||||
obj->index = get_shmid_index();
|
||||
|
||||
list_add(&obj->chain, &kds_list);
|
||||
++the_shm_info.used_ids;
|
||||
@@ -6670,7 +6701,7 @@ SYSCALL_DECLARE(shmctl)
|
||||
return error;
|
||||
}
|
||||
|
||||
maxi = the_maxi;
|
||||
maxi = get_shmid_max_index();
|
||||
if (maxi < 0) {
|
||||
maxi = 0;
|
||||
}
|
||||
@@ -6777,7 +6808,7 @@ SYSCALL_DECLARE(shmctl)
|
||||
return error;
|
||||
}
|
||||
|
||||
maxi = the_maxi;
|
||||
maxi = get_shmid_max_index();
|
||||
if (maxi < 0) {
|
||||
maxi = 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user