Changeset c111da2 in mainline for uspace/lib
- Timestamp:
- 2025-10-09T15:44:52Z (3 months ago)
- Branches:
- master
- Children:
- cfd04c4
- Parents:
- 1a96db9
- Location:
- uspace/lib
- Files:
-
- 2 added
- 7 edited
-
c/generic/capa.c (modified) (2 diffs)
-
c/include/capa.h (modified) (2 diffs)
-
c/test/capa.c (modified) (2 diffs)
-
fmgt/include/fmgt.h (modified) (2 diffs)
-
fmgt/include/types/fmgt.h (modified) (1 diff)
-
fmgt/meson.build (modified) (1 diff)
-
fmgt/src/fmgt.c (modified) (5 diffs)
-
fmgt/test/fmgt.c (added)
-
fmgt/test/main.c (added)
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/capa.c
r1a96db9 rc111da2 1 1 /* 2 * Copyright (c) 20 15 Jiri Svoboda2 * Copyright (c) 2025 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 233 233 } 234 234 235 errno_t capa_format_buf(capa_spec_t *capa, char *buf, size_t bufsize) 236 { 237 errno_t rc; 238 const char *sunit; 239 uint64_t ipart; 240 uint64_t fpart; 241 uint64_t div; 242 243 sunit = NULL; 244 245 assert(capa->cunit < CU_LIMIT); 246 247 rc = ipow10_u64(capa->dp, &div); 248 if (rc != EOK) 249 return rc; 250 251 ipart = capa->m / div; 252 fpart = capa->m % div; 253 254 sunit = cu_str[capa->cunit]; 255 if (capa->dp > 0) { 256 snprintf(buf, bufsize, "%" PRIu64 ".%0*" PRIu64 " %s", ipart, 257 (int)capa->dp, fpart, sunit); 258 } else { 259 snprintf(buf, bufsize, "%" PRIu64 " %s", ipart, sunit); 260 } 261 262 return EOK; 263 } 264 265 errno_t capa_blocks_format(uint64_t nblocks, size_t block_size, 266 char **rptr) 267 { 268 capa_spec_t capa; 269 270 capa_from_blocks(nblocks, block_size, &capa); 271 capa_simplify(&capa); 272 return capa_format(&capa, rptr); 273 } 274 275 void capa_blocks_format_buf(uint64_t nblocks, size_t block_size, 276 char *buf, size_t bsize) 277 { 278 capa_spec_t capa; 279 errno_t rc; 280 281 capa_from_blocks(nblocks, block_size, &capa); 282 capa_simplify(&capa); 283 284 /* Should not get range error because of nblocks * block_size limits */ 285 rc = capa_format_buf(&capa, buf, bsize); 286 assert(rc == EOK); 287 (void)rc; 288 } 289 235 290 static errno_t capa_digit_val(char c, int *val) 236 291 { -
uspace/lib/c/include/capa.h
r1a96db9 rc111da2 1 1 /* 2 * Copyright (c) 20 15 Jiri Svoboda2 * Copyright (c) 2025 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 87 87 } capa_spec_t; 88 88 89 /** Size of buffer large enough for capa_blocks_format_buf */ 90 #define CAPA_BLOCKS_BUFSIZE 16 91 89 92 extern errno_t capa_format(capa_spec_t *, char **); 93 extern errno_t capa_format_buf(capa_spec_t *, char *, size_t); 94 extern errno_t capa_blocks_format(uint64_t, size_t, char **); 95 extern void capa_blocks_format_buf(uint64_t, size_t, char *, size_t); 90 96 extern errno_t capa_parse(const char *, capa_spec_t *); 91 97 extern void capa_simplify(capa_spec_t *); -
uspace/lib/c/test/capa.c
r1a96db9 rc111da2 1 1 /* 2 * Copyright (c) 2025 Jiri Svoboda 2 3 * Copyright (c) 2019 Matthieu Riolo 3 4 * All rights reserved. … … 285 286 } 286 287 288 PCUT_TEST(capa_blocks_format) 289 { 290 errno_t rc; 291 char *str; 292 293 rc = capa_blocks_format(42, 1, &str); 294 PCUT_ASSERT_ERRNO_VAL(EOK, rc); 295 PCUT_ASSERT_STR_EQUALS("42 B", str); 296 free(str); 297 } 298 299 PCUT_TEST(capa_blocks_format_buf) 300 { 301 char str[CAPA_BLOCKS_BUFSIZE]; 302 303 capa_blocks_format_buf(42, 1, str, sizeof(str)); 304 PCUT_ASSERT_STR_EQUALS("42 B", str); 305 } 306 287 307 PCUT_EXPORT(capa); -
uspace/lib/fmgt/include/fmgt.h
r1a96db9 rc111da2 39 39 40 40 #include <errno.h> 41 #include <stdbool.h> 41 42 #include <stddef.h> 43 #include <stdint.h> 42 44 #include "types/fmgt.h" 43 45 … … 45 47 extern void fmgt_set_cb(fmgt_t *, fmgt_cb_t *, void *); 46 48 extern void fmgt_destroy(fmgt_t *); 49 extern void fmgt_set_init_update(fmgt_t *, bool); 47 50 extern errno_t fmgt_new_file_suggest(char **); 51 extern errno_t fmgt_new_file(fmgt_t *, const char *, uint64_t); 48 52 49 53 #endif -
uspace/lib/fmgt/include/types/fmgt.h
r1a96db9 rc111da2 38 38 #define TYPES_FMGT_H 39 39 40 #include <capa.h> 41 #include <fibril_synch.h> 42 43 /** File management progress update */ 44 typedef struct { 45 /** Current file processed bytes */ 46 char curf_procb[CAPA_BLOCKS_BUFSIZE]; 47 /** Total bytes to process for current file */ 48 char curf_totalb[CAPA_BLOCKS_BUFSIZE]; 49 /** Percent of current file processed */ 50 char curf_percent[5]; 51 } fmgt_progress_t; 52 40 53 /** File management callbacks */ 41 54 typedef struct { 55 void (*progress)(void *, fmgt_progress_t *); 42 56 } fmgt_cb_t; 43 57 44 58 typedef struct { 59 /** Lock */ 60 fibril_mutex_t lock; 61 /** Progress update timer */ 62 fibril_timer_t *timer; 45 63 /** Callback functions */ 46 64 fmgt_cb_t *cb; 47 65 /** Argument to callback functions */ 48 66 void *cb_arg; 67 /** Bytes processed from current file */ 68 uint64_t curf_procb; 69 /** Total size of current file */ 70 uint64_t curf_totalb; 71 /** Progress was displayed for current file */ 72 bool curf_progr; 73 /** Post an immediate initial progress update */ 74 bool do_init_update; 49 75 } fmgt_t; 50 76 -
uspace/lib/fmgt/meson.build
r1a96db9 rc111da2 28 28 29 29 src = files( 30 'src/fmgt.c' 30 'src/fmgt.c', 31 31 ) 32 33 test_src = files( 34 'test/fmgt.c', 35 'test/main.c', 36 ) -
uspace/lib/fmgt/src/fmgt.c
r1a96db9 rc111da2 46 46 47 47 #define NEWNAME_LEN 64 48 #define BUFFER_SIZE 16384 48 49 49 50 /** Create file management library instance. … … 59 60 if (fmgt == NULL) 60 61 return ENOMEM; 62 63 fibril_mutex_initialize(&fmgt->lock); 64 fmgt->timer = fibril_timer_create(&fmgt->lock); 65 if (fmgt->timer == NULL) { 66 free(fmgt); 67 return ENOMEM; 68 } 61 69 62 70 *rfmgt = fmgt; … … 77 85 } 78 86 87 /** Configure whether to give immediate initial progress update. 88 * 89 * @param fmgt File management object 90 * @param enabled @c true to post and immediate initial progress update 91 */ 92 void fmgt_set_init_update(fmgt_t *fmgt, bool enabled) 93 { 94 fmgt->do_init_update = enabled; 95 } 96 79 97 /** Destroy file management library instance. 80 98 * … … 83 101 void fmgt_destroy(fmgt_t *fmgt) 84 102 { 103 (void)fibril_timer_clear(fmgt->timer); 104 fibril_timer_destroy(fmgt->timer); 85 105 free(fmgt); 86 106 } … … 116 136 } 117 137 138 /** Get progress update report. 139 * 140 * @param fmgt File management object 141 * @param progress Place to store progress update 142 */ 143 static void fmgt_get_progress(fmgt_t *fmgt, fmgt_progress_t *progress) 144 { 145 unsigned percent; 146 147 if (fmgt->curf_totalb > 0) 148 percent = fmgt->curf_procb * 100 / fmgt->curf_totalb; 149 else 150 percent = 100; 151 152 capa_blocks_format_buf(fmgt->curf_procb, 1, progress->curf_procb, 153 sizeof(progress->curf_procb)); 154 capa_blocks_format_buf(fmgt->curf_totalb, 1, progress->curf_totalb, 155 sizeof(progress->curf_totalb)); 156 snprintf(progress->curf_percent, sizeof(progress->curf_percent), "%u%%", 157 percent); 158 } 159 160 /** Give the caller progress update. 161 * 162 * @param fmgt File management object 163 */ 164 static void fmgt_progress_update(fmgt_t *fmgt) 165 { 166 fmgt_progress_t progress; 167 168 if (fmgt->cb != NULL && fmgt->cb->progress != NULL) { 169 fmgt_get_progress(fmgt, &progress); 170 fmgt->curf_progr = true; 171 fmgt->cb->progress(fmgt->cb_arg, &progress); 172 } 173 } 174 175 /** Provide initial progress update (if required). 176 * 177 * The caller configures the file management object regarding whether 178 * initial updates are required. 179 * 180 * @param fmgt File management object 181 */ 182 static void fmgt_initial_progress_update(fmgt_t *fmgt) 183 { 184 if (fmgt->do_init_update) 185 fmgt_progress_update(fmgt); 186 } 187 188 /** Provide final progress update (if required). 189 * 190 * Final update is provided only if a previous progress update was given. 191 * 192 * @param fmgt File management object 193 */ 194 static void fmgt_final_progress_update(fmgt_t *fmgt) 195 { 196 if (fmgt->curf_progr) 197 fmgt_progress_update(fmgt); 198 } 199 200 /** Progress timer function. 201 * 202 * Periodically called to provide progress updates. 203 * 204 * @param arg Argument (fmgt_t *) 205 */ 206 static void fmgt_timer_fun(void *arg) 207 { 208 fmgt_t *fmgt = (fmgt_t *)arg; 209 210 fmgt_progress_update(fmgt); 211 fibril_timer_set(fmgt->timer, 500000, fmgt_timer_fun, (void *)fmgt); 212 } 213 214 /** Start progress update timer. 215 * 216 * @param fmgt File management object 217 */ 218 static void fmgt_timer_start(fmgt_t *fmgt) 219 { 220 fibril_timer_set(fmgt->timer, 500000, fmgt_timer_fun, (void *)fmgt); 221 } 222 223 /** Create new file. 224 * 225 * @param fmgt File management object 226 * @param fname File name 227 * @param fsize Size of new file (number of zero bytes to fill in) 228 * @return EOK on success or an error code 229 */ 230 errno_t fmgt_new_file(fmgt_t *fmgt, const char *fname, uint64_t fsize) 231 { 232 int fd; 233 size_t nw; 234 aoff64_t pos = 0; 235 uint64_t now; 236 char *buffer; 237 errno_t rc; 238 239 buffer = calloc(BUFFER_SIZE, 1); 240 if (buffer == NULL) 241 return ENOMEM; 242 243 rc = vfs_lookup_open(fname, WALK_REGULAR | WALK_MUST_CREATE, 244 MODE_WRITE, &fd); 245 if (rc != EOK) { 246 free(buffer); 247 return rc; 248 } 249 250 fmgt->curf_procb = 0; 251 fmgt->curf_totalb = fsize; 252 fmgt->curf_progr = false; 253 fmgt_timer_start(fmgt); 254 255 fmgt_initial_progress_update(fmgt); 256 257 while (fmgt->curf_procb < fsize) { 258 now = fsize - fmgt->curf_procb; 259 if (now > BUFFER_SIZE) 260 now = BUFFER_SIZE; 261 262 rc = vfs_write(fd, &pos, buffer, now, &nw); 263 if (rc != EOK) { 264 free(buffer); 265 vfs_put(fd); 266 fmgt_final_progress_update(fmgt); 267 return rc; 268 } 269 270 fmgt->curf_procb += nw; 271 } 272 273 free(buffer); 274 vfs_put(fd); 275 fmgt_final_progress_update(fmgt); 276 return EOK; 277 } 278 118 279 /** @} 119 280 */
Note:
See TracChangeset
for help on using the changeset viewer.
