Changeset 84876aa4 in mainline for uspace/lib/c
- Timestamp:
- 2019-11-15T13:46:34Z (6 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- ecb7828
- Parents:
- b093a62 (diff), d548fc0 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- uspace/lib/c
- Files:
-
- 7 edited
- 3 moved
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/capa.c
rb093a62 r84876aa4 34 34 */ 35 35 36 #include <cap .h>36 #include <capa.h> 37 37 #include <errno.h> 38 38 #include <imath.h> … … 43 43 enum { 44 44 /** Simplified capacity maximum integer digits */ 45 scap _max_idig = 3,45 scapa_max_idig = 3, 46 46 /** Simplified capacity maximum significant digits */ 47 scap _max_sdig = 447 scapa_max_sdig = 4 48 48 }; 49 49 … … 60 60 }; 61 61 62 void cap _from_blocks(uint64_t nblocks, size_t block_size, cap_spec_t *cap)62 void capa_from_blocks(uint64_t nblocks, size_t block_size, capa_spec_t *capa) 63 63 { 64 64 uint64_t tsize; 65 65 66 66 tsize = nblocks * block_size; 67 cap ->m = tsize;68 cap ->dp = 0;69 cap ->cunit = cu_byte;67 capa->m = tsize; 68 capa->dp = 0; 69 capa->cunit = cu_byte; 70 70 } 71 71 … … 81 81 * and @c cv_max gives the maximum value. 82 82 */ 83 errno_t cap _to_blocks(cap_spec_t *cap, cap_vsel_t cvsel, size_t block_size,83 errno_t capa_to_blocks(capa_spec_t *capa, capa_vsel_t cvsel, size_t block_size, 84 84 uint64_t *rblocks) 85 85 { … … 92 92 errno_t rc; 93 93 94 exp = cap ->cunit * 3 - cap->dp;94 exp = capa->cunit * 3 - capa->dp; 95 95 if (exp < 0) { 96 96 rc = ipow10_u64(-exp, &f); 97 97 if (rc != EOK) 98 98 return ERANGE; 99 bytes = (cap ->m + (f / 2)) / f;100 if (bytes * f - (f / 2) != cap ->m)99 bytes = (capa->m + (f / 2)) / f; 100 if (bytes * f - (f / 2) != capa->m) 101 101 return ERANGE; 102 102 } else { … … 118 118 } 119 119 120 bytes = cap ->m * f + adj;121 if ((bytes - adj) / f != cap ->m)120 bytes = capa->m * f + adj; 121 if ((bytes - adj) / f != capa->m) 122 122 return ERANGE; 123 123 } … … 138 138 * digits and at most two fractional digits, e.g abc.xy <unit>. 139 139 */ 140 void cap _simplify(cap_spec_t *cap)140 void capa_simplify(capa_spec_t *capa) 141 141 { 142 142 uint64_t div; … … 146 146 errno_t rc; 147 147 148 /* Change units so that we have at most @c scap _max_idig integer digits */149 rc = ipow10_u64(scap _max_idig, &maxv);148 /* Change units so that we have at most @c scapa_max_idig integer digits */ 149 rc = ipow10_u64(scapa_max_idig, &maxv); 150 150 assert(rc == EOK); 151 151 152 rc = ipow10_u64(cap ->dp, &div);152 rc = ipow10_u64(capa->dp, &div); 153 153 assert(rc == EOK); 154 154 155 while (cap->m / div >= maxv) { 156 ++cap->cunit; 157 cap->dp += 3; 155 /* Change units until we have no more than scapa_max_idig integer digits */ 156 while (capa->m / div >= maxv) { 157 ++capa->cunit; 158 capa->dp += 3; 158 159 div = div * 1000; 159 160 } 160 161 161 /* Round the number so that we have at most @c scap _max_sdig significant digits */162 sdig = 1 + ilog10_u64(cap ->m); /* number of significant digits */163 if (sdig > scap _max_sdig) {162 /* Round the number so that we have at most @c scapa_max_sdig significant digits */ 163 sdig = 1 + ilog10_u64(capa->m); /* number of significant digits */ 164 if (sdig > scapa_max_sdig) { 164 165 /* Number of digits to remove */ 165 rdig = sdig - scap _max_sdig;166 if (rdig > cap ->dp)167 rdig = cap ->dp;166 rdig = sdig - scapa_max_sdig; 167 if (rdig > capa->dp) 168 rdig = capa->dp; 168 169 169 170 rc = ipow10_u64(rdig, &div); 170 171 assert(rc == EOK); 171 172 172 cap->m = (cap->m + (div / 2)) / div; 173 cap->dp -= rdig; 174 } 175 } 176 177 errno_t cap_format(cap_spec_t *cap, char **rstr) 173 /* Division with rounding */ 174 capa->m = (capa->m + (div / 2)) / div; 175 capa->dp -= rdig; 176 } 177 178 /* 179 * If we rounded up from something like 999.95 to 1000.0,, we still 180 * have more than scapa_max_idig integer digits and need to change 181 * units once more. 182 */ 183 rc = ipow10_u64(capa->dp, &div); 184 assert(rc == EOK); 185 186 if (capa->m / div >= 1000) { 187 ++capa->cunit; 188 capa->dp += 3; 189 190 /* 191 * We now have one more significant digit than we want 192 * so round to one less digits 193 */ 194 capa->m = (capa->m + 5) / 10; 195 --capa->dp; 196 } 197 } 198 199 errno_t capa_format(capa_spec_t *capa, char **rstr) 178 200 { 179 201 errno_t rc; … … 186 208 sunit = NULL; 187 209 188 assert(cap ->cunit < CU_LIMIT);189 190 rc = ipow10_u64(cap ->dp, &div);210 assert(capa->cunit < CU_LIMIT); 211 212 rc = ipow10_u64(capa->dp, &div); 191 213 if (rc != EOK) 192 214 return rc; 193 215 194 ipart = cap ->m / div;195 fpart = cap ->m % div;196 197 sunit = cu_str[cap ->cunit];198 if (cap ->dp > 0) {216 ipart = capa->m / div; 217 fpart = capa->m % div; 218 219 sunit = cu_str[capa->cunit]; 220 if (capa->dp > 0) { 199 221 ret = asprintf(rstr, "%" PRIu64 ".%0*" PRIu64 " %s", ipart, 200 (int)cap ->dp, fpart, sunit);222 (int)capa->dp, fpart, sunit); 201 223 } else { 202 224 ret = asprintf(rstr, "%" PRIu64 " %s", ipart, sunit); 203 225 } 226 204 227 if (ret < 0) 205 228 return ENOMEM; … … 208 231 } 209 232 210 static errno_t cap _digit_val(char c, int *val)233 static errno_t capa_digit_val(char c, int *val) 211 234 { 212 235 switch (c) { … … 248 271 } 249 272 250 errno_t cap _parse(const char *str, cap_spec_t *cap)273 errno_t capa_parse(const char *str, capa_spec_t *capa) 251 274 { 252 275 const char *eptr; … … 260 283 261 284 eptr = str; 262 while (cap _digit_val(*eptr, &d) == EOK) {285 while (capa_digit_val(*eptr, &d) == EOK) { 263 286 m = m * 10 + d; 264 287 ++eptr; … … 268 291 ++eptr; 269 292 dp = 0; 270 while (cap _digit_val(*eptr, &d) == EOK) {293 while (capa_digit_val(*eptr, &d) == EOK) { 271 294 m = m * 10 + d; 272 295 ++dp; … … 281 304 282 305 if (*eptr == '\0') { 283 cap ->cunit = cu_byte;306 capa->cunit = cu_byte; 284 307 } else { 285 308 for (i = 0; i < CU_LIMIT; i++) { … … 296 319 return EINVAL; 297 320 found: 298 cap ->cunit = i;299 } 300 301 cap ->m = m;302 cap ->dp = dp;321 capa->cunit = i; 322 } 323 324 capa->m = m; 325 capa->dp = dp; 303 326 return EOK; 304 327 } -
uspace/lib/c/generic/loader.c
rb093a62 r84876aa4 345 345 } 346 346 347 /** Instruct loader to execute the program and do not wait for reply. 348 * 349 * This function does not block even if the loaded task is stopped 350 * for debugging. 351 * 352 * After using this function, no further operations can be performed 353 * on the loader structure and it is deallocated. 354 * 355 * @param ldr Loader connection structure. 356 * 357 * @return Zero on success or an error code. 358 * 359 */ 360 void loader_run_nowait(loader_t *ldr) 361 { 362 async_exch_t *exch = async_exchange_begin(ldr->sess); 363 async_msg_0(exch, LOADER_RUN); 364 async_exchange_end(exch); 365 366 async_hangup(ldr->sess); 367 free(ldr); 368 } 369 347 370 /** Cancel the loader session. 348 371 * -
uspace/lib/c/generic/task.c
rb093a62 r84876aa4 35 35 */ 36 36 37 #include <async.h> 37 38 #include <task.h> 38 39 #include <loader/loader.h> … … 46 47 #include <ns.h> 47 48 #include <stdlib.h> 49 #include <udebug.h> 48 50 #include <libc.h> 49 51 #include "private/ns.h" … … 94 96 * This is really just a convenience wrapper over the more complicated 95 97 * loader API. Arguments are passed as a null-terminated array of strings. 98 * A debug session is created optionally. 96 99 * 97 100 * @param id If not NULL, the ID of the task is stored here on success. … … 100 103 * @param path Pathname of the binary to execute. 101 104 * @param argv Command-line arguments. 102 * 103 * @return Zero on success or an error code. 104 * 105 */ 106 errno_t task_spawnv(task_id_t *id, task_wait_t *wait, const char *path, 107 const char *const args[]) 105 * @param rsess Place to store pointer to debug session or @c NULL 106 * not to start a debug session 107 * 108 * @return Zero on success or an error code. 109 * 110 */ 111 errno_t task_spawnv_debug(task_id_t *id, task_wait_t *wait, const char *path, 112 const char *const args[], async_sess_t **rsess) 108 113 { 109 114 /* Send default files */ … … 125 130 } 126 131 127 return task_spawnvf (id, wait, path, args, fd_stdin, fd_stdout,128 fd_stderr );132 return task_spawnvf_debug(id, wait, path, args, fd_stdin, fd_stdout, 133 fd_stderr, rsess); 129 134 } 130 135 131 136 /** Create a new task by running an executable from the filesystem. 137 * 138 * This is really just a convenience wrapper over the more complicated 139 * loader API. Arguments are passed as a null-terminated array of strings. 140 * 141 * @param id If not NULL, the ID of the task is stored here on success. 142 * @param wait If not NULL, setup waiting for task's return value and store 143 * the information necessary for waiting here on success. 144 * @param path Pathname of the binary to execute. 145 * @param argv Command-line arguments. 146 * 147 * @return Zero on success or an error code. 148 * 149 */ 150 errno_t task_spawnv(task_id_t *id, task_wait_t *wait, const char *path, 151 const char *const args[]) 152 { 153 return task_spawnv_debug(id, wait, path, args, NULL); 154 } 155 156 /** Create a new task by loading an executable from the filesystem. 132 157 * 133 158 * This is really just a convenience wrapper over the more complicated 134 159 * loader API. Arguments are passed as a null-terminated array of strings. 135 160 * Files are passed as null-terminated array of pointers to fdi_node_t. 161 * A debug session is created optionally. 136 162 * 137 163 * @param id If not NULL, the ID of the task is stored here on success. 138 * @param wait If not NULL, setup waiting for task's return value and store 164 * @param wait If not NULL, setup waiting for task's return value and store. 139 165 * @param path Pathname of the binary to execute. 140 * @param argv Command-line arguments. 141 * @param std_in File to use as stdin. 142 * @param std_out File to use as stdout. 143 * @param std_err File to use as stderr. 144 * 145 * @return Zero on success or an error code. 146 * 147 */ 148 errno_t task_spawnvf(task_id_t *id, task_wait_t *wait, const char *path, 149 const char *const args[], int fd_stdin, int fd_stdout, int fd_stderr) 150 { 166 * @param argv Command-line arguments 167 * @param std_in File to use as stdin 168 * @param std_out File to use as stdout 169 * @param std_err File to use as stderr 170 * @param rsess Place to store pointer to debug session or @c NULL 171 * not to start a debug session 172 * 173 * @return Zero on success or an error code 174 * 175 */ 176 errno_t task_spawnvf_debug(task_id_t *id, task_wait_t *wait, 177 const char *path, const char *const args[], int fd_stdin, int fd_stdout, 178 int fd_stderr, async_sess_t **rsess) 179 { 180 async_sess_t *ksess = NULL; 181 151 182 /* Connect to a program loader. */ 152 183 loader_t *ldr = loader_connect(); … … 217 248 } 218 249 219 /* Run it. */ 220 rc = loader_run(ldr); 221 if (rc != EOK) 222 goto error; 250 /* Start a debug session if requested */ 251 if (rsess != NULL) { 252 ksess = async_connect_kbox(task_id); 253 if (ksess == NULL) { 254 /* Most likely debugging support is not compiled in */ 255 rc = ENOTSUP; 256 goto error; 257 } 258 259 rc = udebug_begin(ksess); 260 if (rc != EOK) 261 goto error; 262 263 /* 264 * Run it, not waiting for response. It would never come 265 * as the loader is stopped. 266 */ 267 loader_run_nowait(ldr); 268 } else { 269 /* Run it. */ 270 rc = loader_run(ldr); 271 if (rc != EOK) 272 goto error; 273 } 223 274 224 275 /* Success */ 225 276 if (id != NULL) 226 277 *id = task_id; 227 278 if (rsess != NULL) 279 *rsess = ksess; 228 280 return EOK; 229 281 230 282 error: 283 if (ksess != NULL) 284 async_hangup(ksess); 231 285 if (wait_initialized) 232 286 task_cancel_wait(wait); … … 235 289 loader_abort(ldr); 236 290 return rc; 291 } 292 293 /** Create a new task by running an executable from the filesystem. 294 * 295 * Arguments are passed as a null-terminated array of strings. 296 * Files are passed as null-terminated array of pointers to fdi_node_t. 297 * 298 * @param id If not NULL, the ID of the task is stored here on success. 299 * @param wait If not NULL, setup waiting for task's return value and store. 300 * @param path Pathname of the binary to execute 301 * @param argv Command-line arguments 302 * @param std_in File to use as stdin 303 * @param std_out File to use as stdout 304 * @param std_err File to use as stderr 305 * 306 * @return Zero on success or an error code. 307 * 308 */ 309 errno_t task_spawnvf(task_id_t *id, task_wait_t *wait, const char *path, 310 const char *const args[], int fd_stdin, int fd_stdout, int fd_stderr) 311 { 312 return task_spawnvf_debug(id, wait, path, args, fd_stdin, fd_stdout, 313 fd_stderr, NULL); 237 314 } 238 315 -
uspace/lib/c/include/capa.h
rb093a62 r84876aa4 34 34 */ 35 35 36 #ifndef _LIBC_CAP _H_37 #define _LIBC_CAP _H_36 #ifndef _LIBC_CAPA_H_ 37 #define _LIBC_CAPA_H_ 38 38 39 39 #include <adt/list.h> … … 55 55 cu_zbyte, 56 56 cu_ybyte 57 } cap _unit_t;57 } capa_unit_t; 58 58 59 59 /** Which of values within the precision of the capacity */ … … 65 65 /** The maximum value */ 66 66 cv_max 67 } cap _vsel_t;67 } capa_vsel_t; 68 68 69 69 #define CU_LIMIT (cu_ybyte + 1) … … 87 87 unsigned dp; 88 88 /** Capacity unit */ 89 cap _unit_t cunit;90 } cap _spec_t;89 capa_unit_t cunit; 90 } capa_spec_t; 91 91 92 extern errno_t cap _format(cap_spec_t *, char **);93 extern errno_t cap _parse(const char *, cap_spec_t *);94 extern void cap _simplify(cap_spec_t *);95 extern void cap _from_blocks(uint64_t, size_t, cap_spec_t *);96 extern errno_t cap _to_blocks(cap_spec_t *, cap_vsel_t, size_t, uint64_t *);92 extern errno_t capa_format(capa_spec_t *, char **); 93 extern errno_t capa_parse(const char *, capa_spec_t *); 94 extern void capa_simplify(capa_spec_t *); 95 extern void capa_from_blocks(uint64_t, size_t, capa_spec_t *); 96 extern errno_t capa_to_blocks(capa_spec_t *, capa_vsel_t, size_t, uint64_t *); 97 97 98 98 #endif -
uspace/lib/c/include/loader/loader.h
rb093a62 r84876aa4 53 53 extern errno_t loader_load_program(loader_t *); 54 54 extern errno_t loader_run(loader_t *); 55 extern void loader_run_nowait(loader_t *); 55 56 extern void loader_abort(loader_t *); 56 57 -
uspace/lib/c/include/task.h
rb093a62 r84876aa4 36 36 #define _LIBC_TASK_H_ 37 37 38 #include <async.h> 38 39 #include <stdint.h> 39 40 #include <stdarg.h> … … 56 57 extern errno_t task_spawnv(task_id_t *, task_wait_t *, const char *path, 57 58 const char *const []); 59 extern errno_t task_spawnv_debug(task_id_t *, task_wait_t *, const char *path, 60 const char *const [], async_sess_t **); 58 61 extern errno_t task_spawnvf(task_id_t *, task_wait_t *, const char *path, 59 62 const char *const [], int, int, int); 63 extern errno_t task_spawnvf_debug(task_id_t *, task_wait_t *, const char *path, 64 const char *const [], int, int, int, async_sess_t **); 60 65 extern errno_t task_spawn(task_id_t *, task_wait_t *, const char *path, int, 61 66 va_list ap); -
uspace/lib/c/meson.build
rb093a62 r84876aa4 65 65 'generic/bd_srv.c', 66 66 'generic/perm.c', 67 'generic/cap .c',67 'generic/capa.c', 68 68 'generic/clipboard.c', 69 69 'generic/config.c', … … 204 204 'test/adt/circ_buf.c', 205 205 'test/adt/odict.c', 206 'test/cap .c',206 'test/capa.c', 207 207 'test/casting.c', 208 208 'test/double_to_str.c', -
uspace/lib/c/test/capa.c
rb093a62 r84876aa4 28 28 29 29 #include <pcut/pcut.h> 30 #include <cap .h>30 #include <capa.h> 31 31 32 32 PCUT_INIT; 33 33 34 PCUT_TEST_SUITE(cap );35 36 PCUT_TEST(cap _format)34 PCUT_TEST_SUITE(capa); 35 36 PCUT_TEST(capa_format) 37 37 { 38 38 int block_size = 4; … … 86 86 }; 87 87 88 cap _spec_t cap;88 capa_spec_t capa; 89 89 char *str; 90 90 errno_t rc; … … 93 93 for (i = 0; i < input_size; i++) { 94 94 for (x = 0; x < block_size; x++) { 95 cap _from_blocks(input[i], block[x], &cap);96 cap _simplify(&cap);97 98 rc = cap _format(&cap, &str);95 capa_from_blocks(input[i], block[x], &capa); 96 capa_simplify(&capa); 97 98 rc = capa_format(&capa, &str); 99 99 100 100 PCUT_ASSERT_ERRNO_VAL(EOK, rc); … … 102 102 free(str); 103 103 104 cap _from_blocks(block[x], input[i], &cap);105 cap _simplify(&cap);106 107 rc = cap _format(&cap, &str);104 capa_from_blocks(block[x], input[i], &capa); 105 capa_simplify(&capa); 106 107 rc = capa_format(&capa, &str); 108 108 109 109 PCUT_ASSERT_ERRNO_VAL(EOK, rc); … … 114 114 } 115 115 116 PCUT_TEST(cap _format_rounding)116 PCUT_TEST(capa_format_rounding) 117 117 { 118 118 int input_size = 8; … … 139 139 }; 140 140 141 cap _spec_t cap;141 capa_spec_t capa; 142 142 char *str; 143 143 errno_t rc; … … 145 145 int i; 146 146 for (i = 0; i < input_size; i++) { 147 cap _from_blocks(input[i], 1, &cap);148 cap _simplify(&cap);149 150 rc = cap _format(&cap, &str);147 capa_from_blocks(input[i], 1, &capa); 148 capa_simplify(&capa); 149 150 rc = capa_format(&capa, &str); 151 151 152 152 PCUT_ASSERT_ERRNO_VAL(EOK, rc); … … 154 154 free(str); 155 155 156 cap _from_blocks(1, input[i], &cap);157 cap _simplify(&cap);158 159 rc = cap _format(&cap, &str);156 capa_from_blocks(1, input[i], &capa); 157 capa_simplify(&capa); 158 159 rc = capa_format(&capa, &str); 160 160 161 161 PCUT_ASSERT_ERRNO_VAL(EOK, rc); … … 165 165 } 166 166 167 PCUT_TEST(cap _parse)167 PCUT_TEST(capa_parse) 168 168 { 169 169 int input_size = 4; … … 196 196 }; 197 197 198 cap _spec_t cap;198 capa_spec_t capa; 199 199 errno_t rc; 200 200 int i; 201 201 202 202 for (i = 0; i < input_size; i++) { 203 rc = cap _parse(input[i], &cap);204 205 PCUT_ASSERT_ERRNO_VAL(EOK, rc); 206 PCUT_ASSERT_INT_EQUALS(out_cunit[i], cap .cunit);207 PCUT_ASSERT_INT_EQUALS(out_dp[i], cap .dp);208 PCUT_ASSERT_INT_EQUALS(out_m[i], cap .m);209 } 210 } 211 212 PCUT_TEST(cap _to_blocks)203 rc = capa_parse(input[i], &capa); 204 205 PCUT_ASSERT_ERRNO_VAL(EOK, rc); 206 PCUT_ASSERT_INT_EQUALS(out_cunit[i], capa.cunit); 207 PCUT_ASSERT_INT_EQUALS(out_dp[i], capa.dp); 208 PCUT_ASSERT_INT_EQUALS(out_m[i], capa.m); 209 } 210 } 211 212 PCUT_TEST(capa_to_blocks) 213 213 { 214 214 int input_size = 0; … … 261 261 }; 262 262 263 cap _spec_t cap;263 capa_spec_t capa; 264 264 errno_t rc; 265 265 int i; … … 267 267 268 268 for (i = 0; i < input_size; i++) { 269 cap .m = input_m[i];270 cap .dp = input_dp[i];271 cap .cunit = cu_kbyte;272 273 rc = cap _to_blocks(&cap, cv_nom, block[i], &ret);269 capa.m = input_m[i]; 270 capa.dp = input_dp[i]; 271 capa.cunit = cu_kbyte; 272 273 rc = capa_to_blocks(&capa, cv_nom, block[i], &ret); 274 274 PCUT_ASSERT_ERRNO_VAL(EOK, rc); 275 275 PCUT_ASSERT_INT_EQUALS(out_nom[i], ret); 276 276 277 rc = cap _to_blocks(&cap, cv_min, block[i], &ret);277 rc = capa_to_blocks(&capa, cv_min, block[i], &ret); 278 278 PCUT_ASSERT_ERRNO_VAL(EOK, rc); 279 279 PCUT_ASSERT_INT_EQUALS(out_min[i], ret); 280 280 281 rc = cap _to_blocks(&cap, cv_max, block[i], &ret);281 rc = capa_to_blocks(&capa, cv_max, block[i], &ret); 282 282 PCUT_ASSERT_ERRNO_VAL(EOK, rc); 283 283 PCUT_ASSERT_INT_EQUALS(out_max[i], ret); … … 285 285 } 286 286 287 PCUT_EXPORT(cap );287 PCUT_EXPORT(capa); -
uspace/lib/c/test/getopt.c
rb093a62 r84876aa4 278 278 "get_opt_test", 279 279 "-f", 280 "-p", 281 "param" 280 "-pparam" 282 281 }; 283 282 -
uspace/lib/c/test/main.c
rb093a62 r84876aa4 32 32 PCUT_INIT; 33 33 34 PCUT_IMPORT(cap );34 PCUT_IMPORT(capa); 35 35 PCUT_IMPORT(casting); 36 36 PCUT_IMPORT(circ_buf);
Note:
See TracChangeset
for help on using the changeset viewer.