Changeset 05ffb41 in mainline for kernel/generic/src/ipc/ipcrsc.c
- Timestamp:
- 2017-08-17T19:11:14Z (8 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 1c85bae
- Parents:
- 7e3826d9
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/ipc/ipcrsc.c
r7e3826d9 r05ffb41 162 162 } 163 163 164 /** Get phone from the current task by ID. 165 * 166 * @param phoneid Phone ID. 167 * @param phone Place to store pointer to phone. 168 * 169 * @return EOK on success, EINVAL if ID is invalid. 170 * 171 */ 172 int phone_get(sysarg_t phoneid, phone_t **phone) 173 { 174 if (phoneid >= IPC_MAX_PHONES) 175 return EINVAL; 176 177 *phone = &TASK->phones[phoneid]; 178 return EOK; 179 } 180 181 /** Allocate new phone slot in the specified task. 182 * 183 * @param task Task for which to allocate a new phone. 184 * 185 * @return New phone handle or -1 if the phone handle limit is 186 * exceeded. 187 * 164 /** Get phone from the current task by capability. 165 * 166 * @param cap Phone capability. 167 * @param phone Place to store pointer to phone. 168 * 169 * @return Address of the phone kernel object. 170 * @return NULL if the capability is invalid. 171 * 172 */ 173 phone_t *phone_get(task_t *task, int cap) 174 { 175 kobject_t *kobj = kobject_get(task, cap, KOBJECT_TYPE_PHONE); 176 if (!kobj) 177 return NULL; 178 179 return &kobj->phone; 180 } 181 182 phone_t *phone_get_current(int cap) 183 { 184 return phone_get(TASK, cap); 185 } 186 187 static bool phone_can_reclaim(kobject_t *kobj) 188 { 189 assert(kobj->type == KOBJECT_TYPE_PHONE); 190 191 return (kobj->phone.state == IPC_PHONE_HUNGUP) && 192 (atomic_get(&kobj->phone.active_calls) == 0); 193 } 194 195 /** Allocate new phone in the specified task. 196 * 197 * @param task Task for which to allocate a new phone. 198 * 199 * @return New phone capability. 200 * @return KOBJECT_INVALID_CAP if a new capability cannot be allocated. 188 201 */ 189 202 int phone_alloc(task_t *task) 190 203 { 191 irq_spinlock_lock(&task->lock, true); 192 193 size_t i; 194 for (i = 0; i < IPC_MAX_PHONES; i++) { 195 phone_t *phone = &task->phones[i]; 196 197 if ((phone->state == IPC_PHONE_HUNGUP) && 198 (atomic_get(&phone->active_calls) == 0)) 199 phone->state = IPC_PHONE_FREE; 200 201 if (phone->state == IPC_PHONE_FREE) { 202 phone->state = IPC_PHONE_CONNECTING; 203 break; 204 } 204 int cap = kobject_alloc(task); 205 if (cap != KOBJECT_INVALID_CAP) { 206 irq_spinlock_lock(&task->lock, true); 207 kobject_t *kobj = &task->kobject[cap]; 208 ipc_phone_init(&kobj->phone, task); 209 kobj->type = KOBJECT_TYPE_PHONE; 210 kobj->can_reclaim = phone_can_reclaim; 211 kobj->phone.state = IPC_PHONE_CONNECTING; 212 irq_spinlock_unlock(&task->lock, true); 205 213 } 206 214 207 irq_spinlock_unlock(&task->lock, true);208 209 if (i == IPC_MAX_PHONES) 210 return -1; 211 212 return i; 213 } 214 215 /** Mark a phone structure free. 216 * 217 * @param phone Phone structure to be marked free. 218 * 219 */ 220 static void phone_deallocp(phone_t *phone) 221 { 215 return cap; 216 } 217 218 /** Free slot from a disconnected phone. 219 * 220 * All already sent messages will be correctly processed. 221 * 222 * @param phoneid Phone handle of the phone to be freed. 223 * 224 */ 225 void phone_dealloc(int cap) 226 { 227 phone_t *phone = phone_get_current(cap); 228 229 assert(phone); 222 230 assert(phone->state == IPC_PHONE_CONNECTING); 223 224 /* Atomic operation */ 225 phone->state = IPC_PHONE_FREE; 226 } 227 228 /** Free slot from a disconnected phone. 229 * 230 * All already sent messages will be correctly processed. 231 * 232 * @param phoneid Phone handle of the phone to be freed. 233 * 234 */ 235 void phone_dealloc(int phoneid) 236 { 237 phone_deallocp(&TASK->phones[phoneid]); 231 232 kobject_free(TASK, cap); 238 233 } 239 234 240 235 /** Connect phone to a given answerbox. 241 236 * 242 * @param phoneid Phone handle to be connected. 243 * @param box Answerbox to which to connect the phone handle. 244 * @return True if the phone was connected, false otherwise. 245 * 246 * The procedure _enforces_ that the user first marks the phone 247 * busy (e.g. via phone_alloc) and then connects the phone, otherwise 248 * race condition may appear. 249 * 250 */ 251 bool phone_connect(int phoneid, answerbox_t *box) 252 { 253 phone_t *phone = &TASK->phones[phoneid]; 254 237 * @param cap Phone capability to be connected. 238 * @param box Answerbox to which to connect the phone capability. 239 * @return True if the phone was connected, false otherwise. 240 * 241 * The procedure _enforces_ that the user first marks the phone busy (e.g. via 242 * phone_alloc) and then connects the phone, otherwise race condition may 243 * appear. 244 * 245 */ 246 bool phone_connect(int cap, answerbox_t *box) 247 { 248 phone_t *phone = phone_get_current(cap); 249 250 assert(phone); 255 251 assert(phone->state == IPC_PHONE_CONNECTING); 252 256 253 return ipc_phone_connect(phone, box); 257 254 }
Note:
See TracChangeset
for help on using the changeset viewer.