4 * Miscellanious system support
20 struct lockcount_args {
25 RUNESYSCALL(bcopy) (struct bcopy_args *args, void *rval __unused)
27 bcopy(args->s, args->d, args->bytes);
34 RUNESYSCALL(new)(struct new_args *args, void *rval __unused)
36 urunesize_t count = args->count;
38 Type *ptype = args->lvs.lv_Type;
44 switch (ptype->ty_Op) {
47 * The lvs type is the pointer type
49 type = ptype->ty_RawPtrType.et_Type;
55 * Use the type in the pointer (even if the pointer is NULL it should
56 * be properly typed). This is the object target type.
58 * XXX Allow the case where the pointer is completely zerod and take
59 * the reftype for that case ?
61 s = (void *)args->lvs.lv_Addr;
66 type = ptype->ty_RefType.et_Type;
68 dassert(type != NULL);
72 if (ptype->ty_SQFlags & SF_UNTRACKED) {
74 } else if (ptype->ty_SQFlags & SF_UNLOCKED) {
75 RuneRunTime_IRel(info);
77 } else if (ptype->ty_SQFlags & SF_SOFT) {
78 RuneRunTime_IPut(info);
80 } else if (ptype->ty_SQFlags & SF_HARD) {
81 RuneRunTime_IPutH(info);
84 RuneRunTime_IRel(info);
89 RuneRunTime_IRel(info); /* XXX old locking stuff */
90 //#warning "new() system call need lv_Decl instead of lv_Type"
97 dpanic("Rune new() called on non-pointer/non-reference ty=%d",
101 bytes = type->ty_Bytes * count;
103 dassert(bytes / count == type->ty_Bytes);
108 * ref.new() - load the ref (a ReferenceStor with an info)
112 align = type->ty_AlignMask + 1;
113 if (align < sizeof(void *))
114 align = sizeof(void *);
116 info = allocObjectInfoNZ(type, RSOP_ZALLOC, bytes, align);
118 if ((ptype->ty_SQFlags & SF_NOZERO) == 0 ||
119 (type->ty_Flags & TF_HASLVREF))
121 bzero(info->in_Data.od_Base, bytes);
123 info->in_Count = count;
124 info->in_Beg = (void *)info->in_Data.od_Base;
125 info->in_End = (char *)info->in_Beg + bytes;
128 if (ptype->ty_SQFlags & SF_UNTRACKED) {
129 /* Leave one ref intact, explicit free required */
130 } else if (ptype->ty_SQFlags & SF_UNLOCKED) {
132 } else if (ptype->ty_SQFlags & SF_SOFT) {
134 RuneRunTime_ILock(obj);
135 } else if (ptype->ty_SQFlags & SF_HARD) {
137 RuneRunTime_ILockH(obj);
142 /* (already ref'd) XXX old locking stuff */
143 //#warning "new() system call need lv_Decl instead of lv_Type"
148 * ptr.new() - load the pointer with no other paraphanalia
152 align = type->ty_AlignMask + 1;
153 if (align < sizeof(void *))
154 align = sizeof(void *);
155 posix_memalign((void *)&base, align, bytes);
157 if ((ptype->ty_SQFlags & SF_NOZERO) == 0 ||
158 (type->ty_Flags & TF_HASLVREF))
162 *(void **)args->lvs.lv_Addr = base;
166 * Call run-time function to initialize the type if it needs it.
168 if (type->ty_Flags & (TF_HASLVREF | TF_HASASS | TF_HASCONSTRUCT)) {
170 ((itype_func_t)type->ty_DynamicVector[0])(base, type);
172 base += type->ty_Bytes;
178 * Returns the lockcount of a reference target
181 RUNESYSCALL(lockcount)(struct lockcount_args *args, srunesize_t *rval)
183 Type *ptype = args->lvs.lv_Type;
187 switch (ptype->ty_Op) {
190 * We allow the NULL ref case. We do not need the underlying
191 * type in the ref's object for anything.
193 s = (void *)args->lvs.lv_Addr;
196 *rval = info->in_Lock.rl_Count / RLCOUNT_INCR;
208 * Run-time heap and persistent store allocator. Heap and persistent store
209 * declarations are automatically LValueStor's. These are not objects and
210 * do not have ObjectInfo's.
212 * This function will completely initialize a LValueStor given a storage
213 * declaration. We need the decl and not just the type in order to determine
214 * whether the LValue represents HEAP or PERSISTent storage.
216 * Target storage is typically global so we assume unlocked semantics. Caller
217 * will lock the storage upon return if needed.
220 RUNERUNTIME(LVAlloc) (LValueStor *lvs, Declaration *d)
225 type = d->d_StorDecl.ed_Type;
228 if (d->d_ScopeFlags & SCOPE_HEAP) {
229 if ((type->ty_SQFlags & SF_NOZERO) &&
230 (type->ty_Flags & TF_HASLVREF) == 0)
232 lvs->lv_Addr = znalloc(type->ty_Bytes);
234 lvs->lv_Addr = zalloc(type->ty_Bytes);
237 } else if (d->d_ScopeFlags & SCOPE_PERSIST) {
242 if (RuneMode != RUNEMODE_INTERP &&
243 RuneMode != RUNEMODE_BINARY)
245 dpanic("Not initializing %s\n", d->d_Id);
248 path = getprojectpath(d);
249 fd = open(path, O_RDWR | O_CREAT, 0666);
252 fd = open(path, O_RDWR | O_CREAT, 0666);
254 fprintf(stderr, "Cannot open/create \"%s\"\n",
260 if (st.st_size == (off_t)type->ty_Bytes)
262 ftruncate(fd, type->ty_Bytes);
263 lvs->lv_Addr = mmap(NULL, type->ty_Bytes,
264 PROT_READ | PROT_WRITE,
265 MAP_SHARED | MAP_NOCORE,
267 if ((void *)lvs->lv_Addr == MAP_FAILED)
268 dpanic("persist storage mmap(\"%s\") failed\n", path);
270 if (res == 0 && st.st_size != 0)
271 bzero(lvs->lv_Addr, type->ty_Bytes);
275 dpanic("Unsupported scope for lvalue declaration, "
276 "(requires 'heap' or 'persist' only)");
280 * Call run-time function to initialize the type if it needs it.
282 * XXX if already initialized we still want to call the constructors.
284 if (type->ty_Flags & (TF_HASLVREF | TF_HASASS | TF_HASCONSTRUCT)) {
286 ((itype_func_t)type->ty_DynamicVector[0])(lvs->lv_Addr, type);
298 RUNESYSCALL(exit) (struct exit_args *args, void *rval __unused)
309 RUNESYSCALL(abort) (struct abort_args *args __unused, void *rval __unused)
320 RUNESYSCALL(getenv)(struct getenv_args *args, void **resp)
326 str = getenv(args->name);
328 len = strlen(str) + 1;
330 bcopy(str, base, len);
331 *resp = (void *)(intptr_t)str;
342 RUNESYSCALL(setenv)(struct setenv_args *args, void *resp __unused)
344 if (setenv(args->name, args->value, 1) < 0) {
345 dpanic("setenv(\"%s\", \"%s\") failed",
346 args->name, args->value);
350 struct unsetenv_args {
355 RUNESYSCALL(unsetenv)(struct unsetenv_args *args, int *resp)
357 if (unsetenv(args->name) < 0) {