mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-29 23:52:22 +00:00
Use a per-portal rwlock for portal updates.
This should make qfvis scale a little better with cpu count.
This commit is contained in:
parent
c824e668ed
commit
cb096c601d
3 changed files with 26 additions and 10 deletions
|
@ -40,6 +40,7 @@
|
||||||
#ifdef USE_PTHREADS
|
#ifdef USE_PTHREADS
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
extern pthread_rwlock_t *global_lock;
|
extern pthread_rwlock_t *global_lock;
|
||||||
|
extern pthread_rwlock_t *portal_locks;
|
||||||
|
|
||||||
#define WRLOCK(l) \
|
#define WRLOCK(l) \
|
||||||
do { \
|
do { \
|
||||||
|
@ -58,6 +59,11 @@ extern pthread_rwlock_t *global_lock;
|
||||||
if (options.threads > 1) \
|
if (options.threads > 1) \
|
||||||
pthread_rwlock_unlock (l); \
|
pthread_rwlock_unlock (l); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define WRLOCK_PORTAL(p) WRLOCK (&portal_locks[p - portals])
|
||||||
|
#define RDLOCK_PORTAL(p) RDLOCK (&portal_locks[p - portals])
|
||||||
|
#define UNLOCK_PORTAL(p) UNLOCK (&portal_locks[p - portals])
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define LOCK
|
#define LOCK
|
||||||
#define UNLOCK
|
#define UNLOCK
|
||||||
|
|
|
@ -459,11 +459,11 @@ RecursiveClusterFlow (int clusternum, threaddata_t *thread, pstack_t *prevstack)
|
||||||
void
|
void
|
||||||
PortalFlow (threaddata_t *data, portal_t *portal)
|
PortalFlow (threaddata_t *data, portal_t *portal)
|
||||||
{
|
{
|
||||||
WRLOCK (global_lock);
|
WRLOCK_PORTAL (portal);
|
||||||
if (portal->status != stat_selected)
|
if (portal->status != stat_selected)
|
||||||
Sys_Error ("PortalFlow: reflowed");
|
Sys_Error ("PortalFlow: reflowed");
|
||||||
portal->status = stat_working;
|
portal->status = stat_working;
|
||||||
UNLOCK (global_lock);
|
UNLOCK_PORTAL (portal);
|
||||||
|
|
||||||
portal->visbits = set_new_size_r (&data->set_pool, portalclusters);
|
portal->visbits = set_new_size_r (&data->set_pool, portalclusters);
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,7 @@
|
||||||
#ifdef USE_PTHREADS
|
#ifdef USE_PTHREADS
|
||||||
pthread_attr_t threads_attrib;
|
pthread_attr_t threads_attrib;
|
||||||
pthread_rwlock_t *global_lock;
|
pthread_rwlock_t *global_lock;
|
||||||
|
pthread_rwlock_t *portal_locks;
|
||||||
pthread_rwlock_t *stats_lock;
|
pthread_rwlock_t *stats_lock;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -310,8 +311,10 @@ GetNextPortal (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p) {
|
if (p) {
|
||||||
|
WRLOCK_PORTAL (p);
|
||||||
portal_count++;
|
portal_count++;
|
||||||
p->status = stat_selected;
|
p->status = stat_selected;
|
||||||
|
UNLOCK_PORTAL (p);
|
||||||
}
|
}
|
||||||
|
|
||||||
UNLOCK (global_lock);
|
UNLOCK (global_lock);
|
||||||
|
@ -325,19 +328,19 @@ UpdateMightsee (cluster_t *source, cluster_t *dest)
|
||||||
int i, clusternum;
|
int i, clusternum;
|
||||||
portal_t *portal;
|
portal_t *portal;
|
||||||
|
|
||||||
WRLOCK (global_lock);
|
|
||||||
clusternum = dest - clusters;
|
clusternum = dest - clusters;
|
||||||
for (i = 0; i < source->numportals; i++) {
|
for (i = 0; i < source->numportals; i++) {
|
||||||
portal = source->portals[i];
|
portal = source->portals[i];
|
||||||
if (portal->status != stat_none)
|
WRLOCK_PORTAL (portal);
|
||||||
continue;
|
if (portal->status == stat_none) {
|
||||||
if (set_is_member (portal->mightsee, clusternum)) {
|
if (set_is_member (portal->mightsee, clusternum)) {
|
||||||
set_remove (portal->mightsee, clusternum);
|
set_remove (portal->mightsee, clusternum);
|
||||||
portal->nummightsee--;
|
portal->nummightsee--;
|
||||||
stats.mightseeupdate++;
|
stats.mightseeupdate++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UNLOCK (global_lock);
|
UNLOCK_PORTAL (portal);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -888,6 +891,13 @@ LoadPortals (char *name)
|
||||||
// each file portal is split into two memory portals, one for each
|
// each file portal is split into two memory portals, one for each
|
||||||
// direction
|
// direction
|
||||||
portals = calloc (2 * numportals, sizeof (portal_t));
|
portals = calloc (2 * numportals, sizeof (portal_t));
|
||||||
|
#ifdef USE_PTHREADS
|
||||||
|
portal_locks = calloc (2 * numportals, sizeof (pthread_rwlock_t));
|
||||||
|
for (i = 0; i < 2 * numportals; i++) {
|
||||||
|
if (pthread_rwlock_init (&portal_locks[i], 0))
|
||||||
|
Sys_Error ("pthread_rwlock_init failed");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
clusters = calloc (portalclusters, sizeof (cluster_t));
|
clusters = calloc (portalclusters, sizeof (cluster_t));
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue