X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;ds=sidebyside;f=ipc%2Fsem.c;h=cb5bb2a5df96f417f5c44b1108e8483ee3a10585;hb=1224b375ed7982128602a3fa1da53eeeac1750b4;hp=70975ce0784a9082207659c31e4e1cd946f32c7b;hpb=95f193aa4fe50eb2dc987081d066edd6e13027de;p=~andy%2Flinux diff --git a/ipc/sem.c b/ipc/sem.c index 70975ce0784..cb5bb2a5df9 100644 --- a/ipc/sem.c +++ b/ipc/sem.c @@ -73,6 +73,7 @@ #include #include #include +#include #include #include "util.h" @@ -89,7 +90,7 @@ static struct ipc_ids sem_ids; static int newary (key_t, int, int); static void freeary (struct sem_array *sma, int id); #ifdef CONFIG_PROC_FS -static int sysvipc_sem_read_proc(char *buffer, char **start, off_t offset, int length, int *eof, void *data); +static int sysvipc_sem_proc_show(struct seq_file *s, void *it); #endif #define SEMMSL_FAST 256 /* 512 bytes on stack */ @@ -116,10 +117,10 @@ void __init sem_init (void) { used_sems = 0; ipc_init_ids(&sem_ids,sc_semmni); - -#ifdef CONFIG_PROC_FS - create_proc_read_entry("sysvipc/sem", 0, NULL, sysvipc_sem_read_proc, NULL); -#endif + ipc_init_proc_interface("sysvipc/sem", + " key semid perms nsems uid gid cuid cgid otime ctime\n", + &sem_ids, + sysvipc_sem_proc_show); } /* @@ -193,6 +194,7 @@ static int newary (key_t key, int nsems, int semflg) } used_sems += nsems; + sma->sem_id = sem_buildid(id, sma->sem_perm.seq); sma->sem_base = (struct sem *) &sma[1]; /* sma->sem_pending = NULL; */ sma->sem_pending_last = &sma->sem_pending; @@ -201,7 +203,7 @@ static int newary (key_t key, int nsems, int semflg) sma->sem_ctime = get_seconds(); sem_unlock(sma); - return sem_buildid(id, sma->sem_perm.seq); + return sma->sem_id; } asmlinkage long sys_semget (key_t key, int nsems, int semflg) @@ -379,6 +381,7 @@ static void update_queue (struct sem_array * sma) /* hands-off: q will disappear immediately after * writing q->status. */ + smp_wmb(); q->status = error; q = n; } else { @@ -459,6 +462,7 @@ static void freeary (struct sem_array *sma, int id) n = q->next; q->status = IN_WAKEUP; wake_up_process(q->sleeper); /* doesn't sleep */ + smp_wmb(); q->status = -EIDRM; /* hands-off q */ q = n; } @@ -1328,50 +1332,21 @@ next_entry: } #ifdef CONFIG_PROC_FS -static int sysvipc_sem_read_proc(char *buffer, char **start, off_t offset, int length, int *eof, void *data) +static int sysvipc_sem_proc_show(struct seq_file *s, void *it) { - off_t pos = 0; - off_t begin = 0; - int i, len = 0; - - len += sprintf(buffer, " key semid perms nsems uid gid cuid cgid otime ctime\n"); - down(&sem_ids.sem); - - for(i = 0; i <= sem_ids.max_id; i++) { - struct sem_array *sma; - sma = sem_lock(i); - if(sma) { - len += sprintf(buffer + len, "%10d %10d %4o %10lu %5u %5u %5u %5u %10lu %10lu\n", - sma->sem_perm.key, - sem_buildid(i,sma->sem_perm.seq), - sma->sem_perm.mode, - sma->sem_nsems, - sma->sem_perm.uid, - sma->sem_perm.gid, - sma->sem_perm.cuid, - sma->sem_perm.cgid, - sma->sem_otime, - sma->sem_ctime); - sem_unlock(sma); - - pos += len; - if(pos < offset) { - len = 0; - begin = pos; - } - if(pos > offset + length) - goto done; - } - } - *eof = 1; -done: - up(&sem_ids.sem); - *start = buffer + (offset - begin); - len -= (offset - begin); - if(len > length) - len = length; - if(len < 0) - len = 0; - return len; + struct sem_array *sma = it; + + return seq_printf(s, + "%10d %10d %4o %10lu %5u %5u %5u %5u %10lu %10lu\n", + sma->sem_perm.key, + sma->sem_id, + sma->sem_perm.mode, + sma->sem_nsems, + sma->sem_perm.uid, + sma->sem_perm.gid, + sma->sem_perm.cuid, + sma->sem_perm.cgid, + sma->sem_otime, + sma->sem_ctime); } #endif