Home | History | Annotate | Download | only in diskomizer
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 
     22 /*
     23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 #pragma ident	"@(#)shm_ops.c	1.15	09/05/26 SMI"
     28 
     29 #include <sys/types.h>
     30 #include <strings.h>
     31 #include <assert.h>
     32 #include <stdlib.h>
     33 
     34 #include <diskomizer/log.h>
     35 #include "shm_ops.h"
     36 #include "args.h"
     37 #define	ZERO_OBJ(X) (void) memset(&X, NULL, sizeof (X))
     38 
     39 static struct shm_ops *all_shm_ops[] =
     40 	{&shm_ism_ops, &shm_shm_ops, &shm_mmap_ops, &shm_mmap_no_frag_ops,
     41 		&shm_bestshm_ops, &shm_best_ops, NULL};
     42 
     43 struct shm_ops *
     44 choose_shm_ops(const char *key)
     45 {
     46 	int i;
     47 	for (i = 0; all_shm_ops[i] != NULL; i++) {
     48 		if (strcasecmp(key, all_shm_ops[i]->name(NULL)) == 0)
     49 			return (all_shm_ops[i]);
     50 	}
     51 	return (&shm_best_ops);
     52 }
     53 #ifndef _LP64
     54 static void
     55 check_4_overflow(long a, long b)
     56 {
     57 	long long big;
     58 	ulong_t little;
     59 
     60 	big = a;
     61 	big *= b;
     62 
     63 	/*LINTED*/
     64 	little = big;
     65 
     66 	if (big != (long long) little) {
     67 		pprintf("Unable to allocate %#llx bytes in a %ld (%#lx) bit\n",
     68 		    big, sizeof (long) * 8, sizeof (long) * 8);
     69 		pprintf("address space, exiting\n");
     70 		exit(1);
     71 	}
     72 }
     73 #else
     74 #define	check_4_overflow(A, B)
     75 #endif
     76 void *
     77 alloc_mem(long a, long b)
     78 {
     79 	void *handle, *addr;
     80 	shm_flags flags;
     81 	ZERO_OBJ(flags);
     82 
     83 	flags.execute = opts.obscure_execute;
     84 	assert(a);
     85 	assert(b);
     86 	check_4_overflow(a, b);
     87 	if ((handle = shm_ops->init(a, b, flags)) == NULL) {
     88 		pperror("Init using %s(%#lx) failed", shm_ops->longname(NULL),
     89 		    a * b);
     90 		exit(1);
     91 	}
     92 	plog(LOG_DEBUG, "alloc_mem handle %#lx\n", (ulong_t)handle);
     93 	if ((addr = shm_ops->attach(handle)) == NULL) {
     94 		pperror("Attach using %s(%#lx) failed",
     95 		    shm_ops->longname(addr), a * b);
     96 		exit(1);
     97 	}
     98 	return (addr);
     99 }
    100