source: mainline/uspace/lib/c/generic/io/kio.c@ 6340b4d2

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 6340b4d2 was 40abf56a, checked in by Jiří Zárevúcky <jiri.zarevucky@…>, 7 years ago

Make sure that a thread with uninitialized TLS does not need to call malloc()
to initialize it.

For threads and tasks created by loader, we create TLS beforehand and pass
it to the child. For tasks spawned directly by the kernel, we require it is
a static executable and allocate the initial TLS using as_area_create() instead
of the libc allocator.

  • Property mode set to 100644
File size: 4.0 KB
Line 
1/*
2 * Copyright (c) 2006 Josef Cejka
3 * Copyright (c) 2006 Jakub Vana
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/** @addtogroup libc
31 * @{
32 */
33/** @file
34 */
35
36#include <stddef.h>
37#include <libc.h>
38#include <str.h>
39#include <stdint.h>
40#include <errno.h>
41#include <abi/kio.h>
42#include <io/kio.h>
43#include <io/printf_core.h>
44#include <macros.h>
45#include <libarch/config.h>
46#include <futex.h>
47
48#define KIO_BUFFER_SIZE PAGE_SIZE
49
50static struct {
51 futex_t futex;
52 char data[KIO_BUFFER_SIZE];
53 size_t used;
54} kio_buffer = { .futex = FUTEX_INITIALIZER, };
55
56errno_t kio_write(const void *buf, size_t size, size_t *nwritten)
57{
58 /* Using down/up instead of lock/unlock so we can print very early. */
59 futex_down(&kio_buffer.futex);
60
61 const char *s = buf;
62 while (true) {
63 const char *endl = memchr(s, '\n', size);
64 if (endl) {
65 size_t used = kio_buffer.used;
66
67 size_t sz = min(KIO_BUFFER_SIZE - used, (size_t) (endl - s));
68 memcpy(&kio_buffer.data[used], s, sz);
69
70 __SYSCALL3(SYS_KIO, KIO_WRITE,
71 (sysarg_t) &kio_buffer.data[0], used + sz);
72
73 kio_buffer.used = 0;
74 size -= endl + 1 - s;
75 s = endl + 1;
76 } else {
77 size_t used = kio_buffer.used;
78 size_t sz = min(KIO_BUFFER_SIZE - used, size);
79 memcpy(&kio_buffer.data[used], s, sz);
80 kio_buffer.used += sz;
81 break;
82 }
83 }
84
85 futex_up(&kio_buffer.futex);
86 if (nwritten)
87 *nwritten = size;
88 return EOK;
89}
90
91void kio_update(void)
92{
93 (void) __SYSCALL3(SYS_KIO, KIO_UPDATE, (uintptr_t) NULL, 0);
94}
95
96void kio_command(const void *buf, size_t size)
97{
98 (void) __SYSCALL3(SYS_KIO, KIO_COMMAND, (sysarg_t) buf, (sysarg_t) size);
99}
100
101/** Print formatted text to kio.
102 *
103 * @param fmt Format string
104 *
105 * \see For more details about format string see printf_core.
106 *
107 */
108int kio_printf(const char *fmt, ...)
109{
110 va_list args;
111 va_start(args, fmt);
112
113 int ret = kio_vprintf(fmt, args);
114
115 va_end(args);
116
117 return ret;
118}
119
120static int kio_vprintf_str_write(const char *str, size_t size, void *data)
121{
122 size_t wr;
123
124 wr = 0;
125 (void) kio_write(str, size, &wr);
126 return str_nlength(str, wr);
127}
128
129static int kio_vprintf_wstr_write(const wchar_t *str, size_t size, void *data)
130{
131 size_t offset = 0;
132 size_t chars = 0;
133 size_t wr;
134
135 while (offset < size) {
136 char buf[STR_BOUNDS(1)];
137 size_t sz = 0;
138
139 if (chr_encode(str[chars], buf, &sz, STR_BOUNDS(1)) == EOK)
140 kio_write(buf, sz, &wr);
141
142 chars++;
143 offset += sizeof(wchar_t);
144 }
145
146 return chars;
147}
148
149/** Print formatted text to kio.
150 *
151 * @param fmt Format string
152 * @param ap Format parameters
153 *
154 * \see For more details about format string see printf_core.
155 *
156 */
157int kio_vprintf(const char *fmt, va_list ap)
158{
159 printf_spec_t ps = {
160 kio_vprintf_str_write,
161 kio_vprintf_wstr_write,
162 NULL
163 };
164
165 return printf_core(fmt, &ps, ap);
166}
167
168/** @}
169 */
Note: See TracBrowser for help on using the repository browser.