Ingo,
> semaphore -> mutex is explained a bit in Documentation/mutex-design.txt
>
> Still missing:
> - semaphore -> completion
Sempahore to completion is rather simple to explain.
The pattern is mostly like this
threadA
init_MUTEX_LOCKED(&shared_data_struct.mutex);
kick_off_threadB();
down(&shared_data_struct.mutex);
threadB
wait_for_kick_off();
do_some_work();
up(&shared_data_struct.mutex);
The conversion is:
threadA
init_completion(&shared_data_struct.completion);
kick_off_threadB();
wait_for_completion(&shared_data_struct.completion);
threadB
wait_for_kick_off();
do_some_work();
complete(&shared_data_struct.completion);
Note, that a completion is only useful, when there are only two parties
involved. The one which initiates an action and the one which signals
completion of the requested action. The action can be some deferred
workload or synchronization of startup / shutdown of related threads.
Its a synchronization mechanism not a concurrency control in the sense
of data protection across multiple potential users of a data structure.
Real life example:
> --- jffs2_fs_sb.h 28 Feb 2005 08:21:06 -0000 1.51
> +++ jffs2_fs_sb.h 19 May 2005 16:12:17 -0000 1.52
> @@ -32,7 +32,7 @@
> unsigned int flags;
>
> struct task_struct *gc_task; /* GC task struct */
> - struct semaphore gc_thread_start; /* GC thread start mutex */
> + struct completion gc_thread_start; /* GC thread start completion */
> struct completion gc_thread_exit; /* GC thread exit completion port */
>
> struct semaphore alloc_sem; /* Used to protect all the following
>
>
> --- background.c 17 Mar 2005 20:15:58 -0000 1.51
> +++ background.c 19 May 2005 16:18:08 -0000 1.52
> @@ -37,7 +37,7 @@
> if (c->gc_task)
> BUG();
ThreadA
> - init_MUTEX_LOCKED(&c->gc_thread_start);
> + init_completion(&c->gc_thread_start);
> init_completion(&c->gc_thread_exit);
>
> pid = kernel_thread(jffs2_garbage_collect_thread, c, CLONE_FS|CLONE_FILES);
> @@ -48,7 +48,7 @@
> } else {
> /* Wait for it... */
> D1(printk(KERN_DEBUG "JFFS2: Garbage collect thread is pid %d\n", pid));
> - down(&c->gc_thread_start);
> + wait_for_completion(&c->gc_thread_start);
> }
>
> return ret;
> @@ -75,7 +75,7 @@
> allow_signal(SIGCONT);
ThreadB
> c->gc_task = current;
> - up(&c->gc_thread_start);
> + complete(&c->gc_thread_start);
>
> set_user_nice(current, 10);
>
Hope that helps
tglx
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[Index of Archives]
[Kernel Newbies]
[Netfilter]
[Bugtraq]
[Photo]
[Stuff]
[Gimp]
[Yosemite News]
[MIPS Linux]
[ARM Linux]
[Linux Security]
[Linux RAID]
[Video 4 Linux]
[Linux for the blind]
[Linux Resources]