Add rmlock - almost links

This commit is contained in:
Joel Sherrill 2012-03-07 15:10:49 -06:00
parent b23aecc8eb
commit d4f439f27e
4 changed files with 196 additions and 0 deletions

View File

@ -265,6 +265,7 @@ C_FILES = \
rtems/freebsd/rtems/rtems-bsd-condvar.c \ rtems/freebsd/rtems/rtems-bsd-condvar.c \
rtems/freebsd/rtems/rtems-bsd-lock.c \ rtems/freebsd/rtems/rtems-bsd-lock.c \
rtems/freebsd/rtems/rtems-bsd-sx.c \ rtems/freebsd/rtems/rtems-bsd-sx.c \
rtems/freebsd/rtems/rtems-bsd-rmlock.c \
rtems/freebsd/rtems/rtems-bsd-rwlock.c \ rtems/freebsd/rtems/rtems-bsd-rwlock.c \
rtems/freebsd/rtems/rtems-bsd-generic.c \ rtems/freebsd/rtems/rtems-bsd-generic.c \
rtems/freebsd/rtems/rtems-bsd-panic.c \ rtems/freebsd/rtems/rtems-bsd-panic.c \

View File

@ -24,11 +24,19 @@
#include <rtems/freebsd/sys/types.h> #include <rtems/freebsd/sys/types.h>
#include <rtems/freebsd/sys/systm.h> #include <rtems/freebsd/sys/systm.h>
#include <rtems/freebsd/vm/uma.h>
#include <rtems/freebsd/sys/malloc.h> #include <rtems/freebsd/sys/malloc.h>
#include <rtems/freebsd/sys/ucred.h> #include <rtems/freebsd/sys/ucred.h>
#include <rtems/freebsd/sys/refcount.h>
static MALLOC_DEFINE(M_CRED, "cred", "credentials"); static MALLOC_DEFINE(M_CRED, "cred", "credentials");
static void crextend(struct ucred *cr, int n);
static void crsetgroups_locked(struct ucred *cr, int ngrp,
gid_t *groups);
/* /*
* Allocate a zeroed cred structure. * Allocate a zeroed cred structure.
*/ */
@ -140,3 +148,93 @@ crdup(struct ucred *cr)
crcopy(newcr, cr); crcopy(newcr, cr);
return (newcr); return (newcr);
} }
/*
* Extend the passed in credential to hold n items.
*/
static void
crextend(struct ucred *cr, int n)
{
int cnt;
/* Truncate? */
if (n <= cr->cr_agroups)
return;
/*
* We extend by 2 each time since we're using a power of two
* allocator until we need enough groups to fill a page.
* Once we're allocating multiple pages, only allocate as many
* as we actually need. The case of processes needing a
* non-power of two number of pages seems more likely than
* a real world process that adds thousands of groups one at a
* time.
*/
if ( n < PAGE_SIZE / sizeof(gid_t) ) {
if (cr->cr_agroups == 0)
cnt = MINALLOCSIZE / sizeof(gid_t);
else
cnt = cr->cr_agroups * 2;
while (cnt < n)
cnt *= 2;
} else
cnt = roundup2(n, PAGE_SIZE / sizeof(gid_t));
/* Free the old array. */
if (cr->cr_groups)
free(cr->cr_groups, M_CRED);
cr->cr_groups = malloc(cnt * sizeof(gid_t), M_CRED, M_WAITOK | M_ZERO);
cr->cr_agroups = cnt;
}
/*
* Copy groups in to a credential, preserving any necessary invariants.
* Currently this includes the sorting of all supplemental gids.
* crextend() must have been called before hand to ensure sufficient
* space is available.
*/
static void
crsetgroups_locked(struct ucred *cr, int ngrp, gid_t *groups)
{
int i;
int j;
gid_t g;
KASSERT(cr->cr_agroups >= ngrp, ("cr_ngroups is too small"));
bcopy(groups, cr->cr_groups, ngrp * sizeof(gid_t));
cr->cr_ngroups = ngrp;
/*
* Sort all groups except cr_groups[0] to allow groupmember to
* perform a binary search.
*
* XXX: If large numbers of groups become common this should
* be replaced with shell sort like linux uses or possibly
* heap sort.
*/
for (i = 2; i < ngrp; i++) {
g = cr->cr_groups[i];
for (j = i-1; j >= 1 && g < cr->cr_groups[j]; j--)
cr->cr_groups[j + 1] = cr->cr_groups[j];
cr->cr_groups[j + 1] = g;
}
}
/*
* Copy groups in to a credential after expanding it if required.
* Truncate the list to (ngroups_max + 1) if it is too large.
*/
void
crsetgroups(struct ucred *cr, int ngrp, gid_t *groups)
{
if (ngrp > ngroups_max + 1)
ngrp = ngroups_max + 1;
crextend(cr, ngrp);
crsetgroups_locked(cr, ngrp, groups);
}

View File

@ -0,0 +1,92 @@
/**
* @file
*
* @ingroup rtems_bsd_rtems
*
* @brief TODO.
*/
/*
* COPYRIGHT (c) 2012.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
#include <rtems/freebsd/machine/rtems-bsd-config.h>
#include <sys/types.h>
#include <rtems/freebsd/sys/param.h>
#include <rtems/freebsd/sys/types.h>
#include <rtems/freebsd/sys/systm.h>
#include <rtems/freebsd/sys/lock.h>
#include <rtems/freebsd/sys/rmlock.h>
#include <pthread.h>
#define RMPF_ONQUEUE 1
#define RMPF_SIGNAL 2
/*
* To support usage of rmlock in CVs and msleep yet another list for the
* priority tracker would be needed. Using this lock for cv and msleep also
* does not seem very useful
*/
static __inline void compiler_memory_barrier(void) {
__asm __volatile("":::"memory");
}
static void assert_rm(struct lock_object *lock, int what);
static void lock_rm(struct lock_object *lock, int how);
#ifdef KDTRACE_HOOKS
static int owner_rm(struct lock_object *lock, struct thread **owner);
#endif
static int unlock_rm(struct lock_object *lock);
struct lock_class lock_class_rm = {
.lc_name = "rm",
.lc_flags = LC_SLEEPLOCK | LC_RECURSABLE,
.lc_assert = assert_rm,
#if 0
#ifdef DDB
.lc_ddb_show = db_show_rwlock,
#endif
#endif
.lc_lock = lock_rm,
.lc_unlock = unlock_rm,
#ifdef KDTRACE_HOOKS
.lc_owner = owner_rm,
#endif
};
static void
assert_rm(struct lock_object *lock, int what)
{
panic("assert_rm called");
}
static void
lock_rm(struct lock_object *lock, int how)
{
panic("lock_rm called");
}
static int
unlock_rm(struct lock_object *lock)
{
panic("unlock_rm called");
}
#ifdef KDTRACE_HOOKS
static int
owner_rm(struct lock_object *lock, struct thread **owner)
{
panic("owner_rm called");
}
#endif

View File

@ -9,12 +9,17 @@
#include <stdio.h> #include <stdio.h>
#include <rtems/freebsd/bsd.h> #include <rtems/freebsd/bsd.h>
/* needed by rtems-bsd-resource.c */
int maxproc; int maxproc;
/* needed by rtems-bsd-prot.c */
int ngroups_max; int ngroups_max;
/* needed by rtems-bsd-prot.c */
void prison_hold() {} void prison_hold() {}
void prison_free() {} void prison_free() {}
/* needed by rtems-bsd-init-with-irq.c */
void rtems_interrupt_server_initialize(void) { } void rtems_interrupt_server_initialize(void) { }
rtems_task Init( rtems_task Init(