source: mainline/uspace/drv/uhci-hcd/utils/slab.c@ b6049d7

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since b6049d7 was da88eb82, checked in by Jan Vesely <jano.vesely@…>, 14 years ago

Remove or degrade debug output

Remove intel specific cache flushes

  • Property mode set to 100644
File size: 4.5 KB
Line 
1/*
2 * Copyright (c) 2011 Jan Vesely
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28/** @addtogroup usb
29 * @{
30 */
31/** @file
32 * @brief UHCI driver
33 */
34#include <as.h>
35#include <assert.h>
36#include <fibril_synch.h>
37#include <usb/debug.h>
38
39#include "slab.h"
40
41#define SLAB_SIZE (PAGE_SIZE * 16)
42#define SLAB_ELEMENT_COUNT (SLAB_SIZE / SLAB_ELEMENT_SIZE)
43
44typedef struct slab {
45 void *page;
46 bool slabs[SLAB_ELEMENT_COUNT];
47 fibril_mutex_t guard;
48} slab_t;
49
50static slab_t global_slab;
51
52static void * slab_malloc(slab_t *intance);
53static bool slab_in_range(slab_t *intance, void *addr);
54static void slab_free(slab_t *intance, void *addr);
55/*----------------------------------------------------------------------------*/
56void * slab_malloc_g(void)
57{
58 return slab_malloc(&global_slab);
59}
60/*----------------------------------------------------------------------------*/
61void slab_free_g(void *addr)
62{
63 return slab_free(&global_slab, addr);
64}
65/*----------------------------------------------------------------------------*/
66bool slab_in_range_g(void *addr)
67{
68 return slab_in_range(&global_slab, addr);
69}
70/*----------------------------------------------------------------------------*/
71static void slab_init(slab_t *instance)
72{
73 static FIBRIL_MUTEX_INITIALIZE(init_mutex);
74 assert(instance);
75 fibril_mutex_lock(&init_mutex);
76 if (instance->page != NULL) {
77 /* already initialized */
78 fibril_mutex_unlock(&init_mutex);
79 return;
80 }
81 fibril_mutex_initialize(&instance->guard);
82 size_t i = 0;
83 for (;i < SLAB_ELEMENT_COUNT; ++i) {
84 instance->slabs[i] = true;
85 }
86 instance->page = as_get_mappable_page(SLAB_SIZE);
87 if (instance->page != NULL) {
88 void* ret =
89 as_area_create(instance->page, SLAB_SIZE, AS_AREA_READ | AS_AREA_WRITE);
90 if (ret != instance->page) {
91 instance->page = NULL;
92 }
93 }
94 memset(instance->page, 0xa, SLAB_SIZE);
95 fibril_mutex_unlock(&init_mutex);
96 usb_log_debug2("SLAB initialized at %p.\n", instance->page);
97}
98/*----------------------------------------------------------------------------*/
99static void * slab_malloc(slab_t *instance) {
100 assert(instance);
101 if (instance->page == NULL)
102 slab_init(instance);
103
104 fibril_mutex_lock(&instance->guard);
105 void *addr = NULL;
106 size_t i = 0;
107 for (; i < SLAB_ELEMENT_COUNT; ++i) {
108 if (instance->slabs[i]) {
109 instance->slabs[i] = false;
110 addr = (instance->page + (i * SLAB_ELEMENT_SIZE));
111 break;
112 }
113 }
114 fibril_mutex_unlock(&instance->guard);
115
116 return addr;
117}
118/*----------------------------------------------------------------------------*/
119static bool slab_in_range(slab_t *instance, void *addr) {
120 assert(instance);
121 bool in_range = (instance->page != NULL) &&
122 (addr >= instance->page) && (addr < instance->page + SLAB_SIZE);
123 return in_range;
124}
125/*----------------------------------------------------------------------------*/
126static void slab_free(slab_t *instance, void *addr)
127{
128 assert(instance);
129 assert(slab_in_range(instance, addr));
130 memset(addr, 0xa, SLAB_ELEMENT_SIZE);
131
132 const size_t pos = (addr - instance->page) / SLAB_ELEMENT_SIZE;
133
134 fibril_mutex_lock(&instance->guard);
135 assert(instance->slabs[pos] == false);
136 instance->slabs[pos] = true;
137 fibril_mutex_unlock(&instance->guard);
138}
139/**
140 * @}
141 */
Note: See TracBrowser for help on using the repository browser.