[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[hurd] 25/98: libports: implement lockless management of threads
From: |
Samuel Thibault |
Subject: |
[hurd] 25/98: libports: implement lockless management of threads |
Date: |
Tue, 14 Jan 2014 01:59:59 +0000 |
This is an automated email from the git hooks/post-receive script.
sthibault pushed a commit to branch upstream
in repository hurd.
commit e971ab1a229d1ef1d5c1e5e1ff52ec597c55270e
Author: Justus Winter <address@hidden>
Date: Mon Nov 11 20:53:07 2013 +0100
libports: implement lockless management of threads
ports_manage_port_operations_multithread uses two values, totalthreads
and nreqthreads, to manage the threads it creates. Previously a lock
was used to synchronize the access to them. Use atomic operations
instead.
* libports/manage-multithread.c (ports_manage_port_operations_multithread):
Use atomic operations instead of a lock to synchronize the access to
totalthreads and nreqthreads.
---
libports/manage-multithread.c | 53 +++++++++++++++----------------------------
1 file changed, 18 insertions(+), 35 deletions(-)
diff --git a/libports/manage-multithread.c b/libports/manage-multithread.c
index 0c2da00..842665a 100644
--- a/libports/manage-multithread.c
+++ b/libports/manage-multithread.c
@@ -91,9 +91,12 @@ ports_manage_port_operations_multithread (struct port_bucket
*bucket,
int global_timeout,
void (*hook)())
{
- volatile unsigned int nreqthreads;
- volatile unsigned int totalthreads;
- pthread_spinlock_t lock = PTHREAD_SPINLOCK_INITIALIZER;
+ /* totalthreads is the number of total threads created. nreqthreads
+ is the number of threads not currently servicing any client. The
+ initial values account for the main thread. */
+ unsigned int totalthreads = 1;
+ unsigned int nreqthreads = 1;
+
pthread_attr_t attr;
auto void * thread_function (void *);
@@ -120,30 +123,22 @@ ports_manage_port_operations_multithread (struct
port_bucket *bucket,
/* msgt_unused = */ 0
};
- pthread_spin_lock (&lock);
- assert (nreqthreads);
- nreqthreads--;
- if (nreqthreads != 0)
- pthread_spin_unlock (&lock);
- else
+ if (__atomic_sub_fetch (&nreqthreads, 1, __ATOMIC_RELAXED) == 0)
/* No thread would be listening for requests, spawn one. */
{
pthread_t pthread_id;
error_t err;
- totalthreads++;
- nreqthreads++;
- pthread_spin_unlock (&lock);
+ __atomic_add_fetch (&totalthreads, 1, __ATOMIC_RELAXED);
+ __atomic_add_fetch (&nreqthreads, 1, __ATOMIC_RELAXED);
err = pthread_create (&pthread_id, &attr, thread_function, NULL);
if (!err)
pthread_detach (pthread_id);
else
{
- pthread_spin_lock (&lock);
- totalthreads--;
- nreqthreads--;
- pthread_spin_unlock (&lock);
+ __atomic_sub_fetch (&totalthreads, 1, __ATOMIC_RELAXED);
+ __atomic_sub_fetch (&nreqthreads, 1, __ATOMIC_RELAXED);
/* There is not much we can do at this point. The code
and design of the Hurd servers just don't handle
thread creation failure. */
@@ -189,9 +184,7 @@ ports_manage_port_operations_multithread (struct
port_bucket *bucket,
status = 1;
}
- pthread_spin_lock (&lock);
- nreqthreads++;
- pthread_spin_unlock (&lock);
+ __atomic_add_fetch (&nreqthreads, 1, __ATOMIC_RELAXED);
return status;
}
@@ -203,8 +196,7 @@ ports_manage_port_operations_multithread (struct
port_bucket *bucket,
int timeout;
error_t err;
- /* No need to lock as an approximation is sufficient. */
- adjust_priority (totalthreads);
+ adjust_priority (__atomic_load_n (&totalthreads, __ATOMIC_RELAXED));
if (hook)
(*hook) ();
@@ -224,30 +216,21 @@ ports_manage_port_operations_multithread (struct
port_bucket *bucket,
if (master)
{
- pthread_spin_lock (&lock);
- if (totalthreads != 1)
- {
- pthread_spin_unlock (&lock);
- goto startover;
- }
+ if (__atomic_load_n (&totalthreads, __ATOMIC_RELAXED) != 1)
+ goto startover;
}
else
{
- pthread_spin_lock (&lock);
- if (nreqthreads == 1)
+ if (__atomic_sub_fetch (&nreqthreads, 1, __ATOMIC_RELAXED) == 0)
{
/* No other thread is listening for requests, continue. */
- pthread_spin_unlock (&lock);
+ __atomic_add_fetch (&nreqthreads, 1, __ATOMIC_RELAXED);
goto startover;
}
- nreqthreads--;
- totalthreads--;
- pthread_spin_unlock (&lock);
+ __atomic_sub_fetch (&totalthreads, 1, __ATOMIC_RELAXED);
}
return NULL;
}
- nreqthreads = 1;
- totalthreads = 1;
thread_function ((void *) 1);
}
--
Alioth's /usr/local/bin/git-commit-notice on
/srv/git.debian.org/git/pkg-hurd/hurd.git
- [hurd] branch upstream updated (90b039d -> 5aa7b58), Samuel Thibault, 2014/01/13
- [hurd] 22/98: mach-defpager: fix the page offsets returned by pager_pages, Samuel Thibault, 2014/01/13
- [hurd] 28/98: utils: fix dead initialization, Samuel Thibault, 2014/01/13
- [hurd] 29/98: libps: fix the length computation in fprint_frac_value, Samuel Thibault, 2014/01/13
- [hurd] 27/98: Merge branch 'master' of git.savannah.gnu.org:/srv/git/hurd/hurd, Samuel Thibault, 2014/01/13
- [hurd] 35/98: libshouldbeinlibc: fix error handling in maptime_map, Samuel Thibault, 2014/01/13
- [hurd] 25/98: libports: implement lockless management of threads,
Samuel Thibault <=
- [hurd] 33/98: usermux: actually use the computed flags value in netfs_attempt_utimes, Samuel Thibault, 2014/01/13
- [hurd] 32/98: nfsd: fix error handling in op_remove, Samuel Thibault, 2014/01/13
- [hurd] 30/98: fatfs: fix error handling in diskfs_lookup_hard, Samuel Thibault, 2014/01/13
- [hurd] 42/98: libports: improve error handling in ports_transfer_right, Samuel Thibault, 2014/01/13
- [hurd] 43/98: libdiskfs: improve error reporting in diskfs_start_disk_pager, Samuel Thibault, 2014/01/13
- [hurd] 44/98: libports: improve error reporting in adjust_priority, Samuel Thibault, 2014/01/13
- [hurd] 47/98: libfshelp: improve error handling in fshelp_start_translator_long, Samuel Thibault, 2014/01/13
- [hurd] 46/98: proc: store the device master port in _hurd_device_master, Samuel Thibault, 2014/01/13
- [hurd] 50/98: libnetfs: improve the netfs_demuxer function, Samuel Thibault, 2014/01/13
- [hurd] 31/98: fatfs: fix error handling in diskfs_get_directs, Samuel Thibault, 2014/01/13