svn commit: r254541 - in projects/umtx/sys: kern sys
Davide Italiano
davide at FreeBSD.org
Mon Aug 19 20:46:15 UTC 2013
Author: davide
Date: Mon Aug 19 20:46:14 2013
New Revision: 254541
URL: http://svnweb.freebsd.org/changeset/base/254541
Log:
- Unset the proper bit in the bitmap that keeps track which structures
are in use and which aren't when the thread exits.
- Protect the bitmap using PROC_SLOCK.
Discussed with: attilio[1]
Pointed out by: jhb[2]
Modified:
projects/umtx/sys/kern/kern_schedctl.c
projects/umtx/sys/kern/kern_thread.c
projects/umtx/sys/sys/schedctl.h
Modified: projects/umtx/sys/kern/kern_schedctl.c
==============================================================================
--- projects/umtx/sys/kern/kern_schedctl.c Mon Aug 19 18:57:58 2013 (r254540)
+++ projects/umtx/sys/kern/kern_schedctl.c Mon Aug 19 20:46:14 2013 (r254541)
@@ -58,6 +58,7 @@ static size_t bitmap_len; /* # of bits
* Public prototypes.
*/
int schedctl(struct thread *td, struct schedctl_args *uap);
+void schedctl_thread_exit(struct thread *td);
static int
schedctl_alloc_page(struct proc *p, shpage_t **ret)
@@ -82,9 +83,9 @@ schedctl_alloc_page(struct proc *p, shpa
pmap_qenter(spg->pageaddr, &m, 1);
/* Map in userspace */
- PROC_LOCK(p);
+ PROC_SLOCK(p);
SLIST_INSERT_HEAD(&(p->p_shpg), spg, pg_next);
- PROC_UNLOCK(p);
+ PROC_SUNLOCK(p);
map = &p->p_vmspace->vm_map;
vm_object_reference(spg->shared_page_obj);
@@ -126,6 +127,7 @@ schedctl_shared_alloc(struct thread *td,
sh_pg = NULL;
p = curproc;
KASSERT(p != NULL, ("proc should never be NULL"));
+ PROC_SLOCK(p);
if (!SLIST_EMPTY(&(p->p_shpg))) {
/*
@@ -140,9 +142,11 @@ schedctl_shared_alloc(struct thread *td,
}
}
if (sh_pg == NULL) {
+ PROC_SUNLOCK(p);
error = schedctl_alloc_page(p, &sh_pg);
if (error != 0)
return (ENOMEM);
+ PROC_SLOCK(p);
}
/* Now were's (mostly) sure there's room for allocation. */
@@ -152,6 +156,7 @@ schedctl_shared_alloc(struct thread *td,
KASSERT(idx != -1, ("schedctl_page_alloc: invalid bitmap index"));
*usroff = sh_pg->usraddr + (sizeof(shstate_t) * idx);
*krnoff = sh_pg->pageaddr + (sizeof(shstate_t) * idx);
+ PROC_SUNLOCK(p);
return (0);
}
@@ -190,6 +195,43 @@ schedctl_init(void)
}
/*
+ * thread_exit() hook.
+ */
+void
+schedctl_thread_exit(struct thread *td)
+{
+ struct proc *p;
+ shpage_t *sh_pg;
+ vm_offset_t end, shptr, start;
+ int idx;
+
+ if (td->td_schedctl == NULL)
+ return;
+ p = td->td_proc;
+ shptr = (vm_offset_t)td->td_schedctl;
+ SLIST_FOREACH(sh_pg, &(p->p_shpg), pg_next) {
+ start = (vm_offset_t)sh_pg->pageaddr;
+ end = (vm_offset_t)start + PAGE_SIZE;
+ if ((shptr >= start) && (shptr < end))
+ break;
+ }
+ KASSERT(sh_pg != NULL, ("schedctl_thread_exit: can't find shpage_t"));
+ idx = 0;
+ while (start <= end) {
+ if (shptr == start)
+ break;
+ start += sizeof(shstate_t);
+ idx++;
+ }
+ KASSERT(idx <= bitmap_len, ("schedctl_thread_exit: invalid bmp idx"));
+ setbit(&(sh_pg->bitmap), idx);
+ sh_pg->available++;
+ td->td_schedctl->sh_state = STATE_FREE;
+ td->td_schedctl = NULL;
+ td->td_usrschedctl = NULL;
+}
+
+/*
* XXX: SI_SUB_KMEM is the right place to call schedctl_init?
*/
SYSINIT(schedctl, SI_SUB_KMEM, SI_ORDER_ANY, schedctl_init, NULL);
Modified: projects/umtx/sys/kern/kern_thread.c
==============================================================================
--- projects/umtx/sys/kern/kern_thread.c Mon Aug 19 18:57:58 2013 (r254540)
+++ projects/umtx/sys/kern/kern_thread.c Mon Aug 19 20:46:14 2013 (r254541)
@@ -416,6 +416,7 @@ thread_exit(void)
AUDIT_SYSCALL_EXIT(0, td);
#endif
umtx_thread_exit(td);
+ schedctl_thread_exit(td);
/*
* drop FPU & debug register state storage, or any other
* architecture specific resources that
Modified: projects/umtx/sys/sys/schedctl.h
==============================================================================
--- projects/umtx/sys/sys/schedctl.h Mon Aug 19 18:57:58 2013 (r254540)
+++ projects/umtx/sys/sys/schedctl.h Mon Aug 19 20:46:14 2013 (r254541)
@@ -66,7 +66,7 @@ typedef struct page_shared shpage_t;
* Function prototypes.
*/
void schedctl_init(void);
-void schedctl_thread_cleanup(struct thread *);
-void schedctl_proc_cleanup(void);
+void schedctl_thread_exit(struct thread *);
+void schedctl_proc_exit(void);
#endif /* _SYS_SCHEDCTL_H_ */
More information about the svn-src-projects
mailing list